]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ipfilter/ipsend/ipsend.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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$";
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         if (wfd == -1)
159                 return -1;
160         return send_packet(wfd, mtu, ip, gwip);
161 }
162
163 void
164 udpcksum(ip_t *ip, struct udphdr *udp, int len)
165 {
166         union pseudoh {
167                 struct hdr {
168                         u_short len;
169                         u_char ttl;
170                         u_char proto;
171                         u_32_t src;
172                         u_32_t dst;
173                 } h;
174                 u_short w[6];
175         } ph;
176         u_32_t temp32;
177         u_short *opts;
178
179         ph.h.len = htons(len);
180         ph.h.ttl = 0;
181         ph.h.proto = IPPROTO_UDP;
182         ph.h.src = ip->ip_src.s_addr;
183         ph.h.dst = ip->ip_dst.s_addr;
184         temp32 = 0;
185         opts = &ph.w[0];
186         temp32 += opts[0] + opts[1] + opts[2] + opts[3] + opts[4] + opts[5];
187         temp32 = (temp32 >> 16) + (temp32 & 65535);
188         temp32 += (temp32 >> 16);
189         udp->uh_sum = temp32 & 65535;
190         udp->uh_sum = chksum((u_short *)udp, len);
191         if (udp->uh_sum == 0)
192                 udp->uh_sum = 0xffff;
193 }
194
195 int main(argc, argv)
196         int     argc;
197         char    **argv;
198 {
199         FILE    *langfile = NULL;
200         struct  in_addr gwip;
201         tcphdr_t        *tcp;
202         udphdr_t        *udp;
203         ip_t    *ip;
204         char    *name =  argv[0], host[MAXHOSTNAMELEN + 1];
205         char    *gateway = NULL, *dev = NULL;
206         char    *src = NULL, *dst, *s;
207         int     mtu = 1500, olen = 0, c, nonl = 0;
208
209         /*
210          * 65535 is maximum packet size...you never know...
211          */
212         ip = (ip_t *)calloc(1, 65536);
213         tcp = (tcphdr_t *)(ip + 1);
214         udp = (udphdr_t *)tcp;
215         ip->ip_len = sizeof(*ip);
216         IP_HL_A(ip, sizeof(*ip) >> 2);
217
218         while ((c = getopt(argc, argv, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1) {
219                 switch (c)
220                 {
221                 case 'I' :
222                         nonl++;
223                         if (ip->ip_p)
224                             {
225                                 fprintf(stderr, "Protocol already set: %d\n",
226                                         ip->ip_p);
227                                 break;
228                             }
229                         do_icmp(ip, optarg);
230                         break;
231                 case 'L' :
232                         if (nonl) {
233                                 fprintf(stderr,
234                                         "Incorrect usage of -L option.\n");
235                                 usage(name);
236                         }
237                         if (!strcmp(optarg, "-"))
238                                 langfile = stdin;
239                         else if (!(langfile = fopen(optarg, "r"))) {
240                                 fprintf(stderr, "can't open file %s\n",
241                                         optarg);
242                                 exit(1);
243                         }
244                         iplang(langfile);
245                         return 0;
246                 case 'P' :
247                     {
248                         struct  protoent        *p;
249
250                         nonl++;
251                         if (ip->ip_p)
252                             {
253                                 fprintf(stderr, "Protocol already set: %d\n",
254                                         ip->ip_p);
255                                 break;
256                             }
257                         if ((p = getprotobyname(optarg)))
258                                 ip->ip_p = p->p_proto;
259                         else
260                                 fprintf(stderr, "Unknown protocol: %s\n",
261                                         optarg);
262                         break;
263                     }
264                 case 'T' :
265                         nonl++;
266                         if (ip->ip_p)
267                             {
268                                 fprintf(stderr, "Protocol already set: %d\n",
269                                         ip->ip_p);
270                                 break;
271                             }
272                         ip->ip_p = IPPROTO_TCP;
273                         ip->ip_len += sizeof(tcphdr_t);
274                         break;
275                 case 'U' :
276                         nonl++;
277                         if (ip->ip_p)
278                             {
279                                 fprintf(stderr, "Protocol already set: %d\n",
280                                         ip->ip_p);
281                                 break;
282                             }
283                         ip->ip_p = IPPROTO_UDP;
284                         ip->ip_len += sizeof(udphdr_t);
285                         break;
286                 case 'd' :
287                         opts |= OPT_DEBUG;
288                         break;
289                 case 'f' :
290                         nonl++;
291                         ip->ip_off = strtol(optarg, NULL, 0);
292                         break;
293                 case 'g' :
294                         nonl++;
295                         gateway = optarg;
296                         break;
297                 case 'i' :
298                         nonl++;
299                         dev = optarg;
300                         break;
301                 case 'm' :
302                         nonl++;
303                         mtu = atoi(optarg);
304                         if (mtu < 28)
305                             {
306                                 fprintf(stderr, "mtu must be > 28\n");
307                                 exit(1);
308                             }
309                         break;
310                 case 'o' :
311                         nonl++;
312                         olen = buildopts(optarg, options, (IP_HL(ip) - 5) << 2);
313                         break;
314                 case 's' :
315                         nonl++;
316                         src = optarg;
317                         break;
318                 case 't' :
319                         nonl++;
320                         if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
321                                 tcp->th_dport = htons(atoi(optarg));
322                         break;
323                 case 'v' :
324                         opts |= OPT_VERBOSE;
325                         break;
326                 case 'w' :
327                         nonl++;
328                         if (ip->ip_p == IPPROTO_TCP)
329                                 tcp->th_win = atoi(optarg);
330                         else
331                                 fprintf(stderr, "set protocol to TCP first\n");
332                         break;
333                 default :
334                         fprintf(stderr, "Unknown option \"%c\"\n", c);
335                         usage(name);
336                 }
337         }
338
339         if (argc - optind < 1)
340                 usage(name);
341         dst = argv[optind++];
342
343         if (!src)
344             {
345                 gethostname(host, sizeof(host));
346                 src = host;
347             }
348
349         if (resolve(src, (char *)&ip->ip_src) == -1)
350             {
351                 fprintf(stderr,"Cant resolve %s\n", src);
352                 exit(2);
353             }
354
355         if (resolve(dst, (char *)&ip->ip_dst) == -1)
356             {
357                 fprintf(stderr,"Cant resolve %s\n", dst);
358                 exit(2);
359             }
360
361         if (!gateway)
362                 gwip = ip->ip_dst;
363         else if (resolve(gateway, (char *)&gwip) == -1)
364             {
365                 fprintf(stderr,"Cant resolve %s\n", gateway);
366                 exit(2);
367             }
368
369         if (olen)
370             {
371                 int hlen;
372                 char *p;
373
374                 printf("Options: %d\n", olen);
375                 hlen = sizeof(*ip) + olen;
376                 IP_HL_A(ip, hlen >> 2);
377                 ip->ip_len += olen;
378                 p = (char *)malloc(65536);
379                 if (p == NULL)
380                     {
381                         fprintf(stderr, "malloc failed\n");
382                         exit(2);
383                     }
384
385                 bcopy(ip, p, sizeof(*ip));
386                 bcopy(options, p + sizeof(*ip), olen);
387                 bcopy(ip + 1, p + hlen, ip->ip_len - hlen);
388                 ip = (ip_t *)p;
389
390                 if (ip->ip_p == IPPROTO_TCP) {
391                         tcp = (tcphdr_t *)(p + hlen);
392                 } else if (ip->ip_p == IPPROTO_UDP) {
393                         udp = (udphdr_t *)(p + hlen);
394                 }
395             }
396
397         if (ip->ip_p == IPPROTO_TCP)
398                 for (s = argv[optind]; s && (c = *s); s++)
399                         switch(c)
400                         {
401                         case 'S' : case 's' :
402                                 tcp->th_flags |= TH_SYN;
403                                 break;
404                         case 'A' : case 'a' :
405                                 tcp->th_flags |= TH_ACK;
406                                 break;
407                         case 'F' : case 'f' :
408                                 tcp->th_flags |= TH_FIN;
409                                 break;
410                         case 'R' : case 'r' :
411                                 tcp->th_flags |= TH_RST;
412                                 break;
413                         case 'P' : case 'p' :
414                                 tcp->th_flags |= TH_PUSH;
415                                 break;
416                         case 'U' : case 'u' :
417                                 tcp->th_flags |= TH_URG;
418                                 break;
419                         }
420
421         if (!dev)
422                 dev = default_device;
423         printf("Device:  %s\n", dev);
424         printf("Source:  %s\n", inet_ntoa(ip->ip_src));
425         printf("Dest:    %s\n", inet_ntoa(ip->ip_dst));
426         printf("Gateway: %s\n", inet_ntoa(gwip));
427         if (ip->ip_p == IPPROTO_TCP && tcp->th_flags)
428                 printf("Flags:   %#x\n", tcp->th_flags);
429         printf("mtu:     %d\n", mtu);
430
431         if (ip->ip_p == IPPROTO_UDP) {
432                 udp->uh_sum = 0;
433                 udpcksum(ip, udp, ip->ip_len - (IP_HL(ip) << 2));
434         }
435 #ifdef  DOSOCKET
436         if (ip->ip_p == IPPROTO_TCP && tcp->th_dport)
437                 return do_socket(dev, mtu, ip, gwip);
438 #endif
439         return send_packets(dev, mtu, ip, gwip);
440 }