xref: /freebsd/sbin/ipf/ipsend/resend.c (revision 51e16cb8fc536913f490ac6bc9c17e92ebd0411b)
141edb306SCy Schubert 
241edb306SCy Schubert /*
341edb306SCy Schubert  * resend.c (C) 1995-1998 Darren Reed
441edb306SCy Schubert  *
541edb306SCy Schubert  * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert  *
741edb306SCy Schubert  */
841edb306SCy Schubert #include <sys/param.h>
941edb306SCy Schubert #include <sys/types.h>
1041edb306SCy Schubert #include <sys/time.h>
1141edb306SCy Schubert #include <sys/socket.h>
1241edb306SCy Schubert #include <net/if.h>
1341edb306SCy Schubert #include <netinet/in.h>
1441edb306SCy Schubert #include <arpa/inet.h>
1541edb306SCy Schubert #include <netinet/in_systm.h>
1641edb306SCy Schubert #include <netinet/ip.h>
1741edb306SCy Schubert # include <netinet/ip_var.h>
1841edb306SCy Schubert # include <netinet/if_ether.h>
1941edb306SCy Schubert #include <stdio.h>
2041edb306SCy Schubert #include <netdb.h>
2141edb306SCy Schubert #include <string.h>
2241edb306SCy Schubert #include <stdlib.h>
2341edb306SCy Schubert #include <unistd.h>
2441edb306SCy Schubert #include "ipsend.h"
2541edb306SCy Schubert 
2641edb306SCy Schubert extern	int	opts;
2741edb306SCy Schubert 
2841edb306SCy Schubert void	dumppacket(ip_t *);
2941edb306SCy Schubert 
3041edb306SCy Schubert 
31efeb8bffSCy Schubert void
dumppacket(ip_t * ip)32efeb8bffSCy Schubert dumppacket(ip_t *ip)
3341edb306SCy Schubert {
3441edb306SCy Schubert 	tcphdr_t *t;
3541edb306SCy Schubert 	int i, j;
3641edb306SCy Schubert 
3741edb306SCy Schubert 	t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
3841edb306SCy Schubert 	if (ip->ip_tos)
3941edb306SCy Schubert 		printf("tos %#x ", ip->ip_tos);
4041edb306SCy Schubert 	if (ip->ip_off & 0x3fff)
4141edb306SCy Schubert 		printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3);
4241edb306SCy Schubert 	printf("len %d id %d ", ip->ip_len, ip->ip_id);
4341edb306SCy Schubert 	printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p,
4441edb306SCy Schubert 		inet_ntoa(ip->ip_src));
4541edb306SCy Schubert 	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
4641edb306SCy Schubert 		printf(",%d", t->th_sport);
4741edb306SCy Schubert 	printf(" dst %s", inet_ntoa(ip->ip_dst));
4841edb306SCy Schubert 	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
4941edb306SCy Schubert 		printf(",%d", t->th_dport);
5041edb306SCy Schubert 	if (ip->ip_p == IPPROTO_TCP) {
5141edb306SCy Schubert 		printf(" seq %lu:%lu flags ",
5241edb306SCy Schubert 			(u_long)t->th_seq, (u_long)t->th_ack);
5341edb306SCy Schubert 		for (j = 0, i = 1; i < 256; i *= 2, j++)
5441edb306SCy Schubert 			if (t->th_flags & i)
5541edb306SCy Schubert 				printf("%c", "FSRPAU--"[j]);
5641edb306SCy Schubert 	}
5741edb306SCy Schubert 	putchar('\n');
5841edb306SCy Schubert }
5941edb306SCy Schubert 
6041edb306SCy Schubert 
61efeb8bffSCy Schubert int
ip_resend(char * dev,int mtu,struct ipread * r,struct in_addr gwip,char * datain)62efeb8bffSCy Schubert ip_resend(char *dev, int mtu, struct  ipread  *r, struct  in_addr gwip,
63efeb8bffSCy Schubert 	char *datain)
6441edb306SCy Schubert {
6541edb306SCy Schubert 	ether_header_t	*eh;
6641edb306SCy Schubert 	char	dhost[6];
6741edb306SCy Schubert 	ip_t	*ip;
6841edb306SCy Schubert 	int	fd, wfd = initdevice(dev, 5), len, i;
6941edb306SCy Schubert 	mb_t	mb;
7041edb306SCy Schubert 
7141edb306SCy Schubert 	if (wfd == -1)
72*2582ae57SCy Schubert 		return (-1);
7341edb306SCy Schubert 
7441edb306SCy Schubert 	if (datain)
7541edb306SCy Schubert 		fd = (*r->r_open)(datain);
7641edb306SCy Schubert 	else
7741edb306SCy Schubert 		fd = (*r->r_open)("-");
7841edb306SCy Schubert 
7941edb306SCy Schubert 	if (fd < 0)
8041edb306SCy Schubert 		exit(-1);
8141edb306SCy Schubert 
8241edb306SCy Schubert 	ip = (struct ip *)mb.mb_buf;
8341edb306SCy Schubert 	eh = (ether_header_t *)malloc(sizeof(*eh));
8441edb306SCy Schubert 	if(!eh)
8541edb306SCy Schubert 	    {
8641edb306SCy Schubert 		perror("malloc failed");
87*2582ae57SCy Schubert 		return (-2);
8841edb306SCy Schubert 	    }
8941edb306SCy Schubert 
9041edb306SCy Schubert 	bzero((char *) &eh->ether_shost, sizeof(eh->ether_shost));
9141edb306SCy Schubert 	if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
9241edb306SCy Schubert 	    {
9341edb306SCy Schubert 		perror("arp");
9441edb306SCy Schubert 		free(eh);
95*2582ae57SCy Schubert 		return (-2);
9641edb306SCy Schubert 	    }
9741edb306SCy Schubert 
9841edb306SCy Schubert 	while ((i = (*r->r_readip)(&mb, NULL, NULL)) > 0)
9941edb306SCy Schubert 	    {
10041edb306SCy Schubert 		if (!(opts & OPT_RAW)) {
10141edb306SCy Schubert 			len = ntohs(ip->ip_len);
10241edb306SCy Schubert 			eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
10341edb306SCy Schubert 			eh->ether_type = htons((u_short)ETHERTYPE_IP);
10441edb306SCy Schubert 			if (!gwip.s_addr) {
10541edb306SCy Schubert 				if (arp((char *)&gwip,
10641edb306SCy Schubert 					(char *) &eh->ether_dhost) == -1) {
10741edb306SCy Schubert 					perror("arp");
10841edb306SCy Schubert 					continue;
10941edb306SCy Schubert 				}
11041edb306SCy Schubert 			} else
11141edb306SCy Schubert 				bcopy(dhost, (char *) &eh->ether_dhost,
11241edb306SCy Schubert 				      sizeof(dhost));
11341edb306SCy Schubert 			if (!ip->ip_sum)
11441edb306SCy Schubert 				ip->ip_sum = chksum((u_short *)ip,
11541edb306SCy Schubert 						    IP_HL(ip) << 2);
11641edb306SCy Schubert 			bcopy(ip, (char *)(eh + 1), len);
11741edb306SCy Schubert 			len += sizeof(*eh);
11841edb306SCy Schubert 			dumppacket(ip);
11941edb306SCy Schubert 		} else {
12041edb306SCy Schubert 			eh = (ether_header_t *)mb.mb_buf;
12141edb306SCy Schubert 			len = i;
12241edb306SCy Schubert 		}
12341edb306SCy Schubert 
12441edb306SCy Schubert 		if (sendip(wfd, (char *)eh, len) == -1)
12541edb306SCy Schubert 		    {
12641edb306SCy Schubert 			perror("send_packet");
12741edb306SCy Schubert 			break;
12841edb306SCy Schubert 		    }
12941edb306SCy Schubert 	    }
13041edb306SCy Schubert 	(*r->r_close)();
13141edb306SCy Schubert 	free(eh);
132*2582ae57SCy Schubert 	return (0);
13341edb306SCy Schubert }
134