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