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