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