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