3 * ipsend.c (C) 1995-1998 Darren Reed
5 * See the IPFILTER.LICENCE file for details on licencing.
8 static const char sccsid
[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
9 static const char rcsid
[] = "@(#)$Id: ipsend.c,v 2.8.2.3 2006/03/17 13:45:34 darrenr Exp $";
11 #include <sys/param.h>
12 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <netinet/in_systm.h>
23 #include <netinet/ip.h>
25 # include <netinet/ip_var.h>
30 # include <netinet/udp_var.h>
36 extern void iplang
__P((FILE *));
41 char default_device
[] = "eth0";
44 char default_device
[] = "ln0";
47 char default_device
[] = "ef0";
50 char default_device
[] = "ec0";
53 char default_device
[] = "lan0";
55 char default_device
[] = "le0";
58 # endif /* __bsdi__ */
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 **));
69 static void usage(prog
)
72 fprintf(stderr
, "Usage: %s [options] dest [flags]\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\
88 fprintf(stderr
, "Usage: %s [-dv] -L <filename>\n\
91 \t\t-L filename\tUse IP language for sending packets\n\
92 \t\t-v\tverbose mode\n\
98 static void do_icmp(ip
, args
)
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
, ',')))
111 fprintf(stderr
, "ICMP args missing: ,\n");
115 ic
->icmp_type
= atoi(args
);
116 ic
->icmp_code
= atoi(s
);
117 if (ic
->icmp_type
== ICMP_REDIRECT
&& strchr(s
, ','))
122 t
= strtok(NULL
, ",");
123 if (resolve(t
, (char *)&ic
->icmp_gwaddr
) == -1)
125 fprintf(stderr
,"Cant resolve %s\n", t
);
128 if ((t
= strtok(NULL
, ",")))
130 if (resolve(t
, (char *)&ic
->icmp_ip
.ip_dst
) == -1)
132 fprintf(stderr
,"Cant resolve %s\n", t
);
135 if ((t
= strtok(NULL
, ",")))
138 (char *)&ic
->icmp_ip
.ip_src
) == -1)
140 fprintf(stderr
,"Cant resolve %s\n", t
);
149 int send_packets(dev
, mtu
, ip
, gwip
)
157 wfd
= initdevice(dev
, 5);
160 return send_packet(wfd
, mtu
, ip
, gwip
);
164 udpcksum(ip_t
*ip
, struct udphdr
*udp
, int len
)
179 ph
.h
.len
= htons(len
);
181 ph
.h
.proto
= IPPROTO_UDP
;
182 ph
.h
.src
= ip
->ip_src
.s_addr
;
183 ph
.h
.dst
= ip
->ip_dst
.s_addr
;
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;
199 FILE *langfile
= NULL
;
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;
210 * 65535 is maximum packet size...you never know...
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);
218 while ((c
= getopt(argc
, argv
, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1) {
225 fprintf(stderr
, "Protocol already set: %d\n",
234 "Incorrect usage of -L option.\n");
237 if (!strcmp(optarg
, "-"))
239 else if (!(langfile
= fopen(optarg
, "r"))) {
240 fprintf(stderr
, "can't open file %s\n",
253 fprintf(stderr
, "Protocol already set: %d\n",
257 if ((p
= getprotobyname(optarg
)))
258 ip
->ip_p
= p
->p_proto
;
260 fprintf(stderr
, "Unknown protocol: %s\n",
268 fprintf(stderr
, "Protocol already set: %d\n",
272 ip
->ip_p
= IPPROTO_TCP
;
273 ip
->ip_len
+= sizeof(tcphdr_t
);
279 fprintf(stderr
, "Protocol already set: %d\n",
283 ip
->ip_p
= IPPROTO_UDP
;
284 ip
->ip_len
+= sizeof(udphdr_t
);
291 ip
->ip_off
= strtol(optarg
, NULL
, 0);
306 fprintf(stderr
, "mtu must be > 28\n");
312 olen
= buildopts(optarg
, options
, (IP_HL(ip
) - 5) << 2);
320 if (ip
->ip_p
== IPPROTO_TCP
|| ip
->ip_p
== IPPROTO_UDP
)
321 tcp
->th_dport
= htons(atoi(optarg
));
328 if (ip
->ip_p
== IPPROTO_TCP
)
329 tcp
->th_win
= atoi(optarg
);
331 fprintf(stderr
, "set protocol to TCP first\n");
334 fprintf(stderr
, "Unknown option \"%c\"\n", c
);
339 if (argc
- optind
< 1)
341 dst
= argv
[optind
++];
345 gethostname(host
, sizeof(host
));
349 if (resolve(src
, (char *)&ip
->ip_src
) == -1)
351 fprintf(stderr
,"Cant resolve %s\n", src
);
355 if (resolve(dst
, (char *)&ip
->ip_dst
) == -1)
357 fprintf(stderr
,"Cant resolve %s\n", dst
);
363 else if (resolve(gateway
, (char *)&gwip
) == -1)
365 fprintf(stderr
,"Cant resolve %s\n", gateway
);
374 printf("Options: %d\n", olen
);
375 hlen
= sizeof(*ip
) + olen
;
376 IP_HL_A(ip
, hlen
>> 2);
378 p
= (char *)malloc(65536);
381 fprintf(stderr
, "malloc failed\n");
385 bcopy(ip
, p
, sizeof(*ip
));
386 bcopy(options
, p
+ sizeof(*ip
), olen
);
387 bcopy(ip
+ 1, p
+ hlen
, ip
->ip_len
- hlen
);
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
);
397 if (ip
->ip_p
== IPPROTO_TCP
)
398 for (s
= argv
[optind
]; s
&& (c
= *s
); s
++)
401 case 'S' : case 's' :
402 tcp
->th_flags
|= TH_SYN
;
404 case 'A' : case 'a' :
405 tcp
->th_flags
|= TH_ACK
;
407 case 'F' : case 'f' :
408 tcp
->th_flags
|= TH_FIN
;
410 case 'R' : case 'r' :
411 tcp
->th_flags
|= TH_RST
;
413 case 'P' : case 'p' :
414 tcp
->th_flags
|= TH_PUSH
;
416 case 'U' : case 'u' :
417 tcp
->th_flags
|= TH_URG
;
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
);
431 if (ip
->ip_p
== IPPROTO_UDP
) {
433 udpcksum(ip
, udp
, ip
->ip_len
- (IP_HL(ip
) << 2));
436 if (ip
->ip_p
== IPPROTO_TCP
&& tcp
->th_dport
)
437 return do_socket(dev
, mtu
, ip
, gwip
);
439 return send_packets(dev
, mtu
, ip
, gwip
);