Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / contrib / ipfilter / ipsend / ipsend.c
1 /* $FreeBSD: src/contrib/ipfilter/ipsend/ipsend.c,v 1.4.2.5 2003/03/01 03:55:53 darrenr Exp $ */
2 /* $DragonFly: src/contrib/ipfilter/ipsend/ipsend.c,v 1.2 2003/06/17 04:24:02 dillon Exp $ */
3 /*
4  * ipsend.c (C) 1995-1998 Darren Reed
5  *
6  * This was written to test what size TCP fragments would get through
7  * various TCP/IP packet filters, as used in IP firewalls.  In certain
8  * conditions, enough of the TCP header is missing for unpredictable
9  * results unless the filter is aware that this can happen.
10  *
11  * See the IPFILTER.LICENCE file for details on licencing.
12  */
13 #if defined(__sgi) && (IRIX > 602)
14 # include <sys/ptimers.h>
15 #endif
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <netdb.h>
20 #include <string.h>
21 #include <sys/param.h>
22 #include <sys/types.h>
23 #include <sys/time.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <netinet/in_systm.h>
28 #include <netinet/ip.h>
29 #include <netinet/tcp.h>
30 #include <netinet/udp.h>
31 #include <netinet/ip_icmp.h>
32 #ifndef linux
33 #include <netinet/ip_var.h>
34 #endif
35 #include "ipsend.h"
36
37 #if !defined(lint)
38 static const char sccsid[] = "@(#)ipsend.c      1.5 12/10/95 (C)1995 Darren Reed";
39 static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.2.2.6 2002/12/06 11:40:35 darrenr Exp $";
40 #endif
41
42
43 extern  char    *optarg;
44 extern  int     optind;
45 extern  void    iplang __P((FILE *));
46
47 char    options[68];
48 int     opts;
49 #ifdef  linux
50 char    default_device[] = "eth0";
51 #else
52 # ifdef sun
53 char    default_device[] = "le0";
54 # else
55 #  ifdef        ultrix
56 char    default_device[] = "ln0";
57 #  else
58 #   ifdef       __bsdi__
59 char    default_device[] = "ef0";
60 #   else
61 #    ifdef      __sgi
62 char    default_device[] = "ec0";
63 #    else
64 char    default_device[] = "lan0";
65 #    endif
66 #   endif
67 #  endif
68 # endif
69 #endif
70
71
72 static  void    usage __P((char *));
73 static  void    do_icmp __P((ip_t *, char *));
74 int     main __P((int, char **));
75
76
77 static  void    usage(prog)
78 char    *prog;
79 {
80         fprintf(stderr, "Usage: %s [options] dest [flags]\n\
81 \toptions:\n\
82 \t\t-d\tdebug mode\n\
83 \t\t-i device\tSend out on this device\n\
84 \t\t-f fragflags\tcan set IP_MF or IP_DF\n\
85 \t\t-g gateway\tIP gateway to use if non-local dest.\n\
86 \t\t-I code,type[,gw[,dst[,src]]]\tSet ICMP protocol\n\
87 \t\t-m mtu\t\tfake MTU to use when sending out\n\
88 \t\t-P protocol\tSet protocol by name\n\
89 \t\t-s src\t\tsource address for IP packet\n\
90 \t\t-T\t\tSet TCP protocol\n\
91 \t\t-t port\t\tdestination port\n\
92 \t\t-U\t\tSet UDP protocol\n\
93 \t\t-v\tverbose mode\n\
94 \t\t-w <window>\tSet the TCP window size\n\
95 ", prog);
96         fprintf(stderr, "Usage: %s [-dv] -L <filename>\n\
97 \toptions:\n\
98 \t\t-d\tdebug mode\n\
99 \t\t-L filename\tUse IP language for sending packets\n\
100 \t\t-v\tverbose mode\n\
101 ", prog);
102         exit(1);
103 }
104
105
106 static void do_icmp(ip, args)
107 ip_t *ip;
108 char *args;
109 {
110         struct  icmp    *ic;
111         char    *s;
112
113         ip->ip_p = IPPROTO_ICMP;
114         ip->ip_len += sizeof(*ic);
115         ic = (struct icmp *)(ip + 1);
116         bzero((char *)ic, sizeof(*ic));
117         if (!(s = strchr(args, ',')))
118             {
119                 fprintf(stderr, "ICMP args missing: ,\n");
120                 return;
121             }
122         *s++ = '\0';
123         ic->icmp_type = atoi(args);
124         ic->icmp_code = atoi(s);
125         if (ic->icmp_type == ICMP_REDIRECT && strchr(s, ','))
126             {
127                 char    *t;
128
129                 t = strtok(s, ",");
130                 t = strtok(NULL, ",");
131                 if (resolve(t, (char *)&ic->icmp_gwaddr) == -1)
132                     {
133                         fprintf(stderr,"Cant resolve %s\n", t);
134                         exit(2);
135                     }
136                 if ((t = strtok(NULL, ",")))
137                     {
138                         if (resolve(t, (char *)&ic->icmp_ip.ip_dst) == -1)
139                             {
140                                 fprintf(stderr,"Cant resolve %s\n", t);
141                                 exit(2);
142                             }
143                         if ((t = strtok(NULL, ",")))
144                             {
145                                 if (resolve(t,
146                                             (char *)&ic->icmp_ip.ip_src) == -1)
147                                     {
148                                         fprintf(stderr,"Cant resolve %s\n", t);
149                                         exit(2);
150                                     }
151                             }
152                     }
153             }
154 }
155
156
157 int send_packets(dev, mtu, ip, gwip)
158 char *dev;
159 int mtu;
160 ip_t *ip;
161 struct in_addr gwip;
162 {
163         u_short sport = 0;
164         int     wfd;
165
166         if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
167                 sport = ((struct tcpiphdr *)ip)->ti_sport;
168         wfd = initdevice(dev, sport, 5);
169
170         return send_packet(wfd, mtu, ip, gwip);
171 }
172
173
174 int main(argc, argv)
175 int     argc;
176 char    **argv;
177 {
178         FILE    *langfile = NULL;
179         struct  tcpiphdr *ti;
180         struct  in_addr gwip;
181         tcphdr_t        *tcp;
182         ip_t    *ip;
183         char    *name =  argv[0], host[MAXHOSTNAMELEN + 1];
184         char    *gateway = NULL, *dev = NULL;
185         char    *src = NULL, *dst, *s;
186         int     mtu = 1500, olen = 0, c, nonl = 0;
187
188         /*
189          * 65535 is maximum packet size...you never know...
190          */
191         ip = (ip_t *)calloc(1, 65536);
192         ti = (struct tcpiphdr *)ip;
193         tcp = (tcphdr_t *)&ti->ti_sport;
194         ip->ip_len = sizeof(*ip);
195         ip->ip_hl = sizeof(*ip) >> 2;
196
197         while ((c = getopt(argc, argv, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1)
198                 switch (c)
199                 {
200                 case 'I' :
201                         nonl++;
202                         if (ip->ip_p)
203                             {
204                                 fprintf(stderr, "Protocol already set: %d\n",
205                                         ip->ip_p);
206                                 break;
207                             }
208                         do_icmp(ip, optarg);
209                         break;
210                 case 'L' :
211                         if (nonl) {
212                                 fprintf(stderr,
213                                         "Incorrect usage of -L option.\n");
214                                 usage(name);
215                         }
216                         if (!strcmp(optarg, "-"))
217                                 langfile = stdin;
218                         else if (!(langfile = fopen(optarg, "r"))) {
219                                 fprintf(stderr, "can't open file %s\n",
220                                         optarg);
221                                 exit(1);
222                         }
223                         iplang(langfile);
224                         return 0;
225                 case 'P' :
226                     {
227                         struct  protoent        *p;
228
229                         nonl++;
230                         if (ip->ip_p)
231                             {
232                                 fprintf(stderr, "Protocol already set: %d\n",
233                                         ip->ip_p);
234                                 break;
235                             }
236                         if ((p = getprotobyname(optarg)))
237                                 ip->ip_p = p->p_proto;
238                         else
239                                 fprintf(stderr, "Unknown protocol: %s\n",
240                                         optarg);
241                         break;
242                     }
243                 case 'T' :
244                         nonl++;
245                         if (ip->ip_p)
246                             {
247                                 fprintf(stderr, "Protocol already set: %d\n",
248                                         ip->ip_p);
249                                 break;
250                             }
251                         ip->ip_p = IPPROTO_TCP;
252                         ip->ip_len += sizeof(tcphdr_t);
253                         break;
254                 case 'U' :
255                         nonl++;
256                         if (ip->ip_p)
257                             {
258                                 fprintf(stderr, "Protocol already set: %d\n",
259                                         ip->ip_p);
260                                 break;
261                             }
262                         ip->ip_p = IPPROTO_UDP;
263                         ip->ip_len += sizeof(udphdr_t);
264                         break;
265                 case 'd' :
266                         opts |= OPT_DEBUG;
267                         break;
268                 case 'f' :
269                         nonl++;
270                         ip->ip_off = strtol(optarg, NULL, 0);
271                         break;
272                 case 'g' :
273                         nonl++;
274                         gateway = optarg;
275                         break;
276                 case 'i' :
277                         nonl++;
278                         dev = optarg;
279                         break;
280                 case 'm' :
281                         nonl++;
282                         mtu = atoi(optarg);
283                         if (mtu < 28)
284                             {
285                                 fprintf(stderr, "mtu must be > 28\n");
286                                 exit(1);
287                             }
288                         break;
289                 case 'o' :
290                         nonl++;
291                         olen = buildopts(optarg, options, (ip->ip_hl - 5) << 2);
292                         break;
293                 case 's' :
294                         nonl++;
295                         src = optarg;
296                         break;
297                 case 't' :
298                         nonl++;
299                         if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
300                                 tcp->th_dport = htons(atoi(optarg));
301                         break;
302                 case 'v' :
303                         opts |= OPT_VERBOSE;
304                         break;
305                 case 'w' :
306                         nonl++;
307                         if (ip->ip_p == IPPROTO_TCP)
308                                 tcp->th_win = atoi(optarg);
309                         else
310                                 fprintf(stderr, "set protocol to TCP first\n");
311                         break;
312                 default :
313                         fprintf(stderr, "Unknown option \"%c\"\n", c);
314                         usage(name);
315                 }
316
317         if (argc - optind < 1)
318                 usage(name);
319         dst = argv[optind++];
320
321         if (!src)
322             {
323                 gethostname(host, sizeof(host));
324                 src = host;
325             }
326
327         if (resolve(src, (char *)&ip->ip_src) == -1)
328             {
329                 fprintf(stderr,"Cant resolve %s\n", src);
330                 exit(2);
331             }
332
333         if (resolve(dst, (char *)&ip->ip_dst) == -1)
334             {
335                 fprintf(stderr,"Cant resolve %s\n", dst);
336                 exit(2);
337             }
338
339         if (!gateway)
340                 gwip = ip->ip_dst;
341         else if (resolve(gateway, (char *)&gwip) == -1)
342             {
343                 fprintf(stderr,"Cant resolve %s\n", gateway);
344                 exit(2);
345             }
346
347         if (olen)
348             {
349                 caddr_t ipo = (caddr_t)ip;
350
351                 printf("Options: %d\n", olen);
352                 ti = (struct tcpiphdr *)malloc(olen + ip->ip_len);
353                 if(!ti)
354                     {
355                         fprintf(stderr,"malloc failed\n");
356                         exit(2);
357                     } 
358
359                 bcopy((char *)ip, (char *)ti, sizeof(*ip));
360                 ip = (ip_t *)ti;
361                 ip->ip_hl = (olen >> 2);
362                 bcopy(options, (char *)(ip + 1), olen);
363                 bcopy((char *)tcp, (char *)(ip + 1) + olen, sizeof(*tcp));
364                 ip->ip_len += olen;
365                 bcopy((char *)ip, (char *)ipo, ip->ip_len);
366                 ip = (ip_t *)ipo;
367                 tcp = (tcphdr_t *)((char *)(ip + 1) + olen);
368             }
369
370         if (ip->ip_p == IPPROTO_TCP)
371                 for (s = argv[optind]; s && (c = *s); s++)
372                         switch(c)
373                         {
374                         case 'S' : case 's' :
375                                 tcp->th_flags |= TH_SYN;
376                                 break;
377                         case 'A' : case 'a' :
378                                 tcp->th_flags |= TH_ACK;
379                                 break;
380                         case 'F' : case 'f' :
381                                 tcp->th_flags |= TH_FIN;
382                                 break;
383                         case 'R' : case 'r' :
384                                 tcp->th_flags |= TH_RST;
385                                 break;
386                         case 'P' : case 'p' :
387                                 tcp->th_flags |= TH_PUSH;
388                                 break;
389                         case 'U' : case 'u' :
390                                 tcp->th_flags |= TH_URG;
391                                 break;
392                         }
393
394         if (!dev)
395                 dev = default_device;
396         printf("Device:  %s\n", dev);
397         printf("Source:  %s\n", inet_ntoa(ip->ip_src));
398         printf("Dest:    %s\n", inet_ntoa(ip->ip_dst));
399         printf("Gateway: %s\n", inet_ntoa(gwip));
400         if (ip->ip_p == IPPROTO_TCP && tcp->th_flags)
401                 printf("Flags:   %#x\n", tcp->th_flags);
402         printf("mtu:     %d\n", mtu);
403
404 #ifdef  DOSOCKET
405         if (tcp->th_dport)
406                 return do_socket(dev, mtu, ti, gwip);
407 #endif
408         return send_packets(dev, mtu, (ip_t *)ti, gwip);
409 }