1 /* $FreeBSD: src/contrib/ipfilter/ipsend/ipsend.c,v 1.4.2.6 2004/07/04 09:24:40 darrenr Exp $ */
2 /* $DragonFly: src/contrib/ipfilter/ipsend/ipsend.c,v 1.4 2004/07/28 00:49:54 hmp Exp $ */
4 * ipsend.c (C) 1995-1998 Darren Reed
6 * This was written to test what size TCP fragments would get through
7 * various TCP/IP packet filters, as used in IP firewalls. In certain
8 * conditions, enough of the TCP header is missing for unpredictable
9 * results unless the filter is aware that this can happen.
11 * See the IPFILTER.LICENCE file for details on licencing.
13 #if defined(__sgi) && (IRIX > 602)
14 # include <sys/ptimers.h>
21 #include <sys/param.h>
22 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <netinet/in_systm.h>
28 #include <netinet/ip.h>
29 #include <netinet/ip_var.h>
30 #include <netinet/tcp.h>
31 #include <netinet/udp.h>
32 #include <netinet/udp_var.h>
33 #include <netinet/ip_icmp.h>
35 #include <netinet/ip_var.h>
40 static const char sccsid
[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
41 static const char rcsid
[] = "@(#)$Id: ipsend.c,v 2.2.2.6 2002/12/06 11:40:35 darrenr Exp $";
47 extern void iplang
__P((FILE *));
52 char default_device
[] = "eth0";
55 char default_device
[] = "le0";
58 char default_device
[] = "ln0";
61 char default_device
[] = "ef0";
64 char default_device
[] = "ec0";
66 char default_device
[] = "lan0";
74 static void usage
__P((char *));
75 static void do_icmp
__P((ip_t
*, char *));
76 void udpcksum(ip_t
*, struct udphdr
*, int);
77 int main
__P((int, char **));
80 static void usage(prog
)
83 fprintf(stderr
, "Usage: %s [options] dest [flags]\n\
86 \t\t-i device\tSend out on this device\n\
87 \t\t-f fragflags\tcan set IP_MF or IP_DF\n\
88 \t\t-g gateway\tIP gateway to use if non-local dest.\n\
89 \t\t-I code,type[,gw[,dst[,src]]]\tSet ICMP protocol\n\
90 \t\t-m mtu\t\tfake MTU to use when sending out\n\
91 \t\t-P protocol\tSet protocol by name\n\
92 \t\t-s src\t\tsource address for IP packet\n\
93 \t\t-T\t\tSet TCP protocol\n\
94 \t\t-t port\t\tdestination port\n\
95 \t\t-U\t\tSet UDP protocol\n\
96 \t\t-v\tverbose mode\n\
97 \t\t-w <window>\tSet the TCP window size\n\
99 fprintf(stderr
, "Usage: %s [-dv] -L <filename>\n\
101 \t\t-d\tdebug mode\n\
102 \t\t-L filename\tUse IP language for sending packets\n\
103 \t\t-v\tverbose mode\n\
109 static void do_icmp(ip
, args
)
116 ip
->ip_p
= IPPROTO_ICMP
;
117 ip
->ip_len
+= sizeof(*ic
);
118 ic
= (struct icmp
*)(ip
+ 1);
119 bzero((char *)ic
, sizeof(*ic
));
120 if (!(s
= strchr(args
, ',')))
122 fprintf(stderr
, "ICMP args missing: ,\n");
126 ic
->icmp_type
= atoi(args
);
127 ic
->icmp_code
= atoi(s
);
128 if (ic
->icmp_type
== ICMP_REDIRECT
&& strchr(s
, ','))
133 t
= strtok(NULL
, ",");
134 if (resolve(t
, (char *)&ic
->icmp_gwaddr
) == -1)
136 fprintf(stderr
,"Cant resolve %s\n", t
);
139 if ((t
= strtok(NULL
, ",")))
141 if (resolve(t
, (char *)&ic
->icmp_ip
.ip_dst
) == -1)
143 fprintf(stderr
,"Cant resolve %s\n", t
);
146 if ((t
= strtok(NULL
, ",")))
149 (char *)&ic
->icmp_ip
.ip_src
) == -1)
151 fprintf(stderr
,"Cant resolve %s\n", t
);
160 int send_packets(dev
, mtu
, ip
, gwip
)
169 if (ip
->ip_p
== IPPROTO_TCP
|| ip
->ip_p
== IPPROTO_UDP
)
170 sport
= ((struct tcpiphdr
*)ip
)->ti_sport
;
171 wfd
= initdevice(dev
, sport
, 5);
173 return send_packet(wfd
, mtu
, ip
, gwip
);
177 udpcksum(ip_t
*ip
, struct udphdr
*udp
, int len
)
190 u_short cksum
, *opts
;
192 ph
.h
.len
= htons(len
);
194 ph
.h
.proto
= IPPROTO_UDP
;
195 ph
.h
.src
= ip
->ip_src
.s_addr
;
196 ph
.h
.dst
= ip
->ip_dst
.s_addr
;
199 temp32
+= opts
[0] + opts
[1] + opts
[2] + opts
[3] + opts
[4] + opts
[5];
200 temp32
= (temp32
>> 16) + (temp32
& 65535);
201 temp32
+= (temp32
>> 16);
202 udp
->uh_sum
= temp32
& 65535;
203 udp
->uh_sum
= chksum((u_short
*)udp
, len
);
204 if (udp
->uh_sum
== 0)
205 udp
->uh_sum
= 0xffff;
212 FILE *langfile
= NULL
;
219 char *name
= argv
[0], host
[MAXHOSTNAMELEN
+ 1];
220 char *gateway
= NULL
, *dev
= NULL
;
221 char *src
= NULL
, *dst
, *s
;
222 int mtu
= 1500, olen
= 0, c
, nonl
= 0;
225 * 65535 is maximum packet size...you never know...
227 ip
= (ip_t
*)calloc(1, 65536);
228 ti
= (struct tcpiphdr
*)ip
;
229 ui
= (struct udpiphdr
*)ip
;
230 tcp
= (tcphdr_t
*)&ti
->ti_sport
;
231 udp
= (udphdr_t
*)&ui
->ui_sport
;
232 ui
->ui_ulen
= htons(sizeof(*udp
));
233 ip
->ip_len
= sizeof(*ip
);
234 ip
->ip_hl
= sizeof(*ip
) >> 2;
236 while ((c
= getopt(argc
, argv
, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1)
243 fprintf(stderr
, "Protocol already set: %d\n",
252 "Incorrect usage of -L option.\n");
255 if (!strcmp(optarg
, "-"))
257 else if (!(langfile
= fopen(optarg
, "r"))) {
258 fprintf(stderr
, "can't open file %s\n",
271 fprintf(stderr
, "Protocol already set: %d\n",
275 if ((p
= getprotobyname(optarg
)))
276 ip
->ip_p
= p
->p_proto
;
278 fprintf(stderr
, "Unknown protocol: %s\n",
286 fprintf(stderr
, "Protocol already set: %d\n",
290 ip
->ip_p
= IPPROTO_TCP
;
291 ip
->ip_len
+= sizeof(tcphdr_t
);
297 fprintf(stderr
, "Protocol already set: %d\n",
301 ip
->ip_p
= IPPROTO_UDP
;
302 ip
->ip_len
+= sizeof(udphdr_t
);
309 ip
->ip_off
= strtol(optarg
, NULL
, 0);
324 fprintf(stderr
, "mtu must be > 28\n");
330 olen
= buildopts(optarg
, options
, (ip
->ip_hl
- 5) << 2);
338 if (ip
->ip_p
== IPPROTO_TCP
|| ip
->ip_p
== IPPROTO_UDP
)
339 tcp
->th_dport
= htons(atoi(optarg
));
346 if (ip
->ip_p
== IPPROTO_TCP
)
347 tcp
->th_win
= atoi(optarg
);
349 fprintf(stderr
, "set protocol to TCP first\n");
352 fprintf(stderr
, "Unknown option \"%c\"\n", c
);
356 if (argc
- optind
< 1)
358 dst
= argv
[optind
++];
362 gethostname(host
, sizeof(host
));
366 if (resolve(src
, (char *)&ip
->ip_src
) == -1)
368 fprintf(stderr
,"Cant resolve %s\n", src
);
372 if (resolve(dst
, (char *)&ip
->ip_dst
) == -1)
374 fprintf(stderr
,"Cant resolve %s\n", dst
);
380 else if (resolve(gateway
, (char *)&gwip
) == -1)
382 fprintf(stderr
,"Cant resolve %s\n", gateway
);
386 if (ip
->ip_p
!= IPPROTO_TCP
&& ip
->ip_p
!= IPPROTO_UDP
) {
387 fprintf(stderr
,"Unsupported protocol %d\n", ip
->ip_p
);
396 printf("Options: %d\n", olen
);
397 hlen
= sizeof(*ip
) + olen
;
398 ip
->ip_hl
= hlen
>> 2;
400 p
= (char *)malloc(65536);
403 fprintf(stderr
,"malloc failed\n");
406 bcopy(ip
, p
, sizeof(*ip
));
407 bcopy(options
, p
+ sizeof(*ip
), olen
);
408 bcopy(ip
+ 1, p
+ hlen
, ip
->ip_len
- hlen
);
410 if (ip
->ip_p
== IPPROTO_TCP
) {
411 tcp
= (tcphdr_t
*)((char *)ip
+ hlen
);
413 udp
= (udphdr_t
*)((char *)ip
+ hlen
);
417 if (ip
->ip_p
== IPPROTO_TCP
)
418 for (s
= argv
[optind
]; s
&& (c
= *s
); s
++)
421 case 'S' : case 's' :
422 tcp
->th_flags
|= TH_SYN
;
424 case 'A' : case 'a' :
425 tcp
->th_flags
|= TH_ACK
;
427 case 'F' : case 'f' :
428 tcp
->th_flags
|= TH_FIN
;
430 case 'R' : case 'r' :
431 tcp
->th_flags
|= TH_RST
;
433 case 'P' : case 'p' :
434 tcp
->th_flags
|= TH_PUSH
;
436 case 'U' : case 'u' :
437 tcp
->th_flags
|= TH_URG
;
442 dev
= default_device
;
443 printf("Device: %s\n", dev
);
444 printf("Source: %s\n", inet_ntoa(ip
->ip_src
));
445 printf("Dest: %s\n", inet_ntoa(ip
->ip_dst
));
446 printf("Gateway: %s\n", inet_ntoa(gwip
));
447 if (ip
->ip_p
== IPPROTO_TCP
&& tcp
->th_flags
)
448 printf("Flags: %#x\n", tcp
->th_flags
);
449 printf("mtu: %d\n", mtu
);
451 if (ip
->ip_p
== IPPROTO_UDP
) {
453 udpcksum(ip
, udp
, (ip
->ip_len
) - (ip
->ip_hl
<< 2));
456 if (ip
->ip_p
== IPPROTO_TCP
&& tcp
->th_dport
)
457 return do_socket(dev
, mtu
, (struct tcpiphdr
*)ip
, gwip
);
459 return send_packets(dev
, mtu
, ip
, gwip
);