4 * ipsend.c (C) 1995-1998 Darren Reed
6 * See the IPFILTER.LICENCE file for details on licencing.
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";
12 #include <sys/param.h>
13 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
18 #include <netinet/in_systm.h>
24 #include <netinet/ip.h>
26 # include <netinet/ip_var.h>
31 # include <netinet/udp_var.h>
37 extern void iplang
__P((FILE *));
42 char default_device
[] = "eth0";
45 char default_device
[] = "ln0";
48 char default_device
[] = "ef0";
51 char default_device
[] = "ec0";
54 char default_device
[] = "lan0";
56 char default_device
[] = "le0";
59 # endif /* __bsdi__ */
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
)
73 fprintf(stderr
, "Usage: %s [options] dest [flags]\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\
89 fprintf(stderr
, "Usage: %s [-dv] -L <filename>\n\
92 \t\t-L filename\tUse IP language for sending packets\n\
93 \t\t-v\tverbose mode\n\
99 static void do_icmp(ip
, args
)
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");
116 ic
->icmp_type
= atoi(args
);
117 ic
->icmp_code
= atoi(s
);
118 if (ic
->icmp_type
== ICMP_REDIRECT
&& strchr(s
, ','))
123 t
= strtok(NULL
, ",");
124 if (resolve(t
, (char *)&ic
->icmp_gwaddr
) == -1)
126 fprintf(stderr
,"Cant resolve %s\n", t
);
129 if ((t
= strtok(NULL
, ",")))
131 if (resolve(t
, (char *)&ic
->icmp_ip
.ip_dst
) == -1)
133 fprintf(stderr
,"Cant resolve %s\n", t
);
136 if ((t
= strtok(NULL
, ",")))
139 (char *)&ic
->icmp_ip
.ip_src
) == -1)
141 fprintf(stderr
,"Cant resolve %s\n", t
);
150 int send_packets(dev
, mtu
, ip
, gwip
)
158 wfd
= initdevice(dev
, 5);
161 return send_packet(wfd
, mtu
, ip
, gwip
);
165 udpcksum(ip_t
*ip
, struct udphdr
*udp
, int len
)
180 ph
.h
.len
= htons(len
);
182 ph
.h
.proto
= IPPROTO_UDP
;
183 ph
.h
.src
= ip
->ip_src
.s_addr
;
184 ph
.h
.dst
= ip
->ip_dst
.s_addr
;
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;
200 FILE *langfile
= NULL
;
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) {
226 fprintf(stderr
, "Protocol already set: %d\n",
235 "Incorrect usage of -L option.\n");
238 if (!strcmp(optarg
, "-"))
240 else if (!(langfile
= fopen(optarg
, "r"))) {
241 fprintf(stderr
, "can't open file %s\n",
254 fprintf(stderr
, "Protocol already set: %d\n",
258 if ((p
= getprotobyname(optarg
)))
259 ip
->ip_p
= p
->p_proto
;
261 fprintf(stderr
, "Unknown protocol: %s\n",
269 fprintf(stderr
, "Protocol already set: %d\n",
273 ip
->ip_p
= IPPROTO_TCP
;
274 ip
->ip_len
+= sizeof(tcphdr_t
);
280 fprintf(stderr
, "Protocol already set: %d\n",
284 ip
->ip_p
= IPPROTO_UDP
;
285 ip
->ip_len
+= sizeof(udphdr_t
);
292 ip
->ip_off
= strtol(optarg
, NULL
, 0);
307 fprintf(stderr
, "mtu must be > 28\n");
313 olen
= buildopts(optarg
, options
, (IP_HL(ip
) - 5) << 2);
321 if (ip
->ip_p
== IPPROTO_TCP
|| ip
->ip_p
== IPPROTO_UDP
)
322 tcp
->th_dport
= htons(atoi(optarg
));
329 if (ip
->ip_p
== IPPROTO_TCP
)
330 tcp
->th_win
= atoi(optarg
);
332 fprintf(stderr
, "set protocol to TCP first\n");
335 fprintf(stderr
, "Unknown option \"%c\"\n", c
);
340 if (argc
- optind
< 1)
342 dst
= argv
[optind
++];
346 gethostname(host
, sizeof(host
));
350 if (resolve(src
, (char *)&ip
->ip_src
) == -1)
352 fprintf(stderr
,"Cant resolve %s\n", src
);
356 if (resolve(dst
, (char *)&ip
->ip_dst
) == -1)
358 fprintf(stderr
,"Cant resolve %s\n", dst
);
364 else if (resolve(gateway
, (char *)&gwip
) == -1)
366 fprintf(stderr
,"Cant resolve %s\n", gateway
);
375 printf("Options: %d\n", olen
);
376 hlen
= sizeof(*ip
) + olen
;
377 IP_HL_A(ip
, hlen
>> 2);
379 p
= (char *)malloc(65536);
382 fprintf(stderr
, "malloc failed\n");
386 bcopy(ip
, p
, sizeof(*ip
));
387 bcopy(options
, p
+ sizeof(*ip
), olen
);
388 bcopy(ip
+ 1, p
+ hlen
, ip
->ip_len
- hlen
);
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
++)
402 case 'S' : case 's' :
403 tcp
->th_flags
|= TH_SYN
;
405 case 'A' : case 'a' :
406 tcp
->th_flags
|= TH_ACK
;
408 case 'F' : case 'f' :
409 tcp
->th_flags
|= TH_FIN
;
411 case 'R' : case 'r' :
412 tcp
->th_flags
|= TH_RST
;
414 case 'P' : case 'p' :
415 tcp
->th_flags
|= TH_PUSH
;
417 case 'U' : case 'u' :
418 tcp
->th_flags
|= TH_URG
;
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
) {
434 udpcksum(ip
, udp
, ip
->ip_len
- (IP_HL(ip
) << 2));
437 if (ip
->ip_p
== IPPROTO_TCP
&& tcp
->th_dport
)
438 return do_socket(dev
, mtu
, ip
, gwip
);
440 return send_packets(dev
, mtu
, ip
, gwip
);