xref: /freebsd/sbin/ipf/ipsend/resend.c (revision 41edb306f05651fcaf6c74f9e3557f59f80292e1)
1*41edb306SCy Schubert /*	$FreeBSD$	*/
2*41edb306SCy Schubert 
3*41edb306SCy Schubert /*
4*41edb306SCy Schubert  * resend.c (C) 1995-1998 Darren Reed
5*41edb306SCy Schubert  *
6*41edb306SCy Schubert  * See the IPFILTER.LICENCE file for details on licencing.
7*41edb306SCy Schubert  *
8*41edb306SCy Schubert  */
9*41edb306SCy Schubert #if !defined(lint)
10*41edb306SCy Schubert static const char sccsid[] = "@(#)resend.c	1.3 1/11/96 (C)1995 Darren Reed";
11*41edb306SCy Schubert static const char rcsid[] = "@(#)$Id$";
12*41edb306SCy Schubert #endif
13*41edb306SCy Schubert #include <sys/param.h>
14*41edb306SCy Schubert #include <sys/types.h>
15*41edb306SCy Schubert #include <sys/time.h>
16*41edb306SCy Schubert #include <sys/socket.h>
17*41edb306SCy Schubert #include <net/if.h>
18*41edb306SCy Schubert #include <netinet/in.h>
19*41edb306SCy Schubert #include <arpa/inet.h>
20*41edb306SCy Schubert #include <netinet/in_systm.h>
21*41edb306SCy Schubert #include <netinet/ip.h>
22*41edb306SCy Schubert # include <netinet/ip_var.h>
23*41edb306SCy Schubert # include <netinet/if_ether.h>
24*41edb306SCy Schubert #include <stdio.h>
25*41edb306SCy Schubert #include <netdb.h>
26*41edb306SCy Schubert #include <string.h>
27*41edb306SCy Schubert #include <stdlib.h>
28*41edb306SCy Schubert #include <unistd.h>
29*41edb306SCy Schubert #include "ipsend.h"
30*41edb306SCy Schubert 
31*41edb306SCy Schubert extern	int	opts;
32*41edb306SCy Schubert 
33*41edb306SCy Schubert void	dumppacket(ip_t *);
34*41edb306SCy Schubert 
35*41edb306SCy Schubert 
36*41edb306SCy Schubert void dumppacket(ip)
37*41edb306SCy Schubert 	ip_t	*ip;
38*41edb306SCy Schubert {
39*41edb306SCy Schubert 	tcphdr_t *t;
40*41edb306SCy Schubert 	int i, j;
41*41edb306SCy Schubert 
42*41edb306SCy Schubert 	t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
43*41edb306SCy Schubert 	if (ip->ip_tos)
44*41edb306SCy Schubert 		printf("tos %#x ", ip->ip_tos);
45*41edb306SCy Schubert 	if (ip->ip_off & 0x3fff)
46*41edb306SCy Schubert 		printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3);
47*41edb306SCy Schubert 	printf("len %d id %d ", ip->ip_len, ip->ip_id);
48*41edb306SCy Schubert 	printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p,
49*41edb306SCy Schubert 		inet_ntoa(ip->ip_src));
50*41edb306SCy Schubert 	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
51*41edb306SCy Schubert 		printf(",%d", t->th_sport);
52*41edb306SCy Schubert 	printf(" dst %s", inet_ntoa(ip->ip_dst));
53*41edb306SCy Schubert 	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
54*41edb306SCy Schubert 		printf(",%d", t->th_dport);
55*41edb306SCy Schubert 	if (ip->ip_p == IPPROTO_TCP) {
56*41edb306SCy Schubert 		printf(" seq %lu:%lu flags ",
57*41edb306SCy Schubert 			(u_long)t->th_seq, (u_long)t->th_ack);
58*41edb306SCy Schubert 		for (j = 0, i = 1; i < 256; i *= 2, j++)
59*41edb306SCy Schubert 			if (t->th_flags & i)
60*41edb306SCy Schubert 				printf("%c", "FSRPAU--"[j]);
61*41edb306SCy Schubert 	}
62*41edb306SCy Schubert 	putchar('\n');
63*41edb306SCy Schubert }
64*41edb306SCy Schubert 
65*41edb306SCy Schubert 
66*41edb306SCy Schubert int	ip_resend(dev, mtu, r, gwip, datain)
67*41edb306SCy Schubert 	char	*dev;
68*41edb306SCy Schubert 	int	mtu;
69*41edb306SCy Schubert 	struct	in_addr	gwip;
70*41edb306SCy Schubert 	struct	ipread	*r;
71*41edb306SCy Schubert 	char	*datain;
72*41edb306SCy Schubert {
73*41edb306SCy Schubert 	ether_header_t	*eh;
74*41edb306SCy Schubert 	char	dhost[6];
75*41edb306SCy Schubert 	ip_t	*ip;
76*41edb306SCy Schubert 	int	fd, wfd = initdevice(dev, 5), len, i;
77*41edb306SCy Schubert 	mb_t	mb;
78*41edb306SCy Schubert 
79*41edb306SCy Schubert 	if (wfd == -1)
80*41edb306SCy Schubert 		return -1;
81*41edb306SCy Schubert 
82*41edb306SCy Schubert 	if (datain)
83*41edb306SCy Schubert 		fd = (*r->r_open)(datain);
84*41edb306SCy Schubert 	else
85*41edb306SCy Schubert 		fd = (*r->r_open)("-");
86*41edb306SCy Schubert 
87*41edb306SCy Schubert 	if (fd < 0)
88*41edb306SCy Schubert 		exit(-1);
89*41edb306SCy Schubert 
90*41edb306SCy Schubert 	ip = (struct ip *)mb.mb_buf;
91*41edb306SCy Schubert 	eh = (ether_header_t *)malloc(sizeof(*eh));
92*41edb306SCy Schubert 	if(!eh)
93*41edb306SCy Schubert 	    {
94*41edb306SCy Schubert 		perror("malloc failed");
95*41edb306SCy Schubert 		return -2;
96*41edb306SCy Schubert 	    }
97*41edb306SCy Schubert 
98*41edb306SCy Schubert 	bzero((char *) &eh->ether_shost, sizeof(eh->ether_shost));
99*41edb306SCy Schubert 	if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
100*41edb306SCy Schubert 	    {
101*41edb306SCy Schubert 		perror("arp");
102*41edb306SCy Schubert 		free(eh);
103*41edb306SCy Schubert 		return -2;
104*41edb306SCy Schubert 	    }
105*41edb306SCy Schubert 
106*41edb306SCy Schubert 	while ((i = (*r->r_readip)(&mb, NULL, NULL)) > 0)
107*41edb306SCy Schubert 	    {
108*41edb306SCy Schubert 		if (!(opts & OPT_RAW)) {
109*41edb306SCy Schubert 			len = ntohs(ip->ip_len);
110*41edb306SCy Schubert 			eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
111*41edb306SCy Schubert 			eh->ether_type = htons((u_short)ETHERTYPE_IP);
112*41edb306SCy Schubert 			if (!gwip.s_addr) {
113*41edb306SCy Schubert 				if (arp((char *)&gwip,
114*41edb306SCy Schubert 					(char *) &eh->ether_dhost) == -1) {
115*41edb306SCy Schubert 					perror("arp");
116*41edb306SCy Schubert 					continue;
117*41edb306SCy Schubert 				}
118*41edb306SCy Schubert 			} else
119*41edb306SCy Schubert 				bcopy(dhost, (char *) &eh->ether_dhost,
120*41edb306SCy Schubert 				      sizeof(dhost));
121*41edb306SCy Schubert 			if (!ip->ip_sum)
122*41edb306SCy Schubert 				ip->ip_sum = chksum((u_short *)ip,
123*41edb306SCy Schubert 						    IP_HL(ip) << 2);
124*41edb306SCy Schubert 			bcopy(ip, (char *)(eh + 1), len);
125*41edb306SCy Schubert 			len += sizeof(*eh);
126*41edb306SCy Schubert 			dumppacket(ip);
127*41edb306SCy Schubert 		} else {
128*41edb306SCy Schubert 			eh = (ether_header_t *)mb.mb_buf;
129*41edb306SCy Schubert 			len = i;
130*41edb306SCy Schubert 		}
131*41edb306SCy Schubert 
132*41edb306SCy Schubert 		if (sendip(wfd, (char *)eh, len) == -1)
133*41edb306SCy Schubert 		    {
134*41edb306SCy Schubert 			perror("send_packet");
135*41edb306SCy Schubert 			break;
136*41edb306SCy Schubert 		    }
137*41edb306SCy Schubert 	    }
138*41edb306SCy Schubert 	(*r->r_close)();
139*41edb306SCy Schubert 	free(eh);
140*41edb306SCy Schubert 	return 0;
141*41edb306SCy Schubert }
142