1145519Sdarrenr/*	$FreeBSD$	*/
2145510Sdarrenr
322514Sdarrenr/*
453024Sguido * resend.c (C) 1995-1998 Darren Reed
522514Sdarrenr *
6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
722514Sdarrenr *
822514Sdarrenr */
9145510Sdarrenr#if !defined(lint)
10145510Sdarrenrstatic const char sccsid[] = "@(#)resend.c	1.3 1/11/96 (C)1995 Darren Reed";
11170268Sdarrenrstatic const char rcsid[] = "@(#)$Id: resend.c,v 2.8.2.3 2007/02/17 12:41:51 darrenr Exp $";
1292686Sdarrenr#endif
13145510Sdarrenr#include <sys/param.h>
1422514Sdarrenr#include <sys/types.h>
1522514Sdarrenr#include <sys/time.h>
1622514Sdarrenr#include <sys/socket.h>
17170268Sdarrenr#ifdef __osf__
18170268Sdarrenr# include "radix_ipf_local.h"
19170268Sdarrenr#endif
2022514Sdarrenr#include <net/if.h>
2122514Sdarrenr#include <netinet/in.h>
2222514Sdarrenr#include <arpa/inet.h>
2322514Sdarrenr#include <netinet/in_systm.h>
2422514Sdarrenr#include <netinet/ip.h>
2522514Sdarrenr#ifndef	linux
2631183Speter# include <netinet/ip_var.h>
2731183Speter# include <netinet/if_ether.h>
2831183Speter# if __FreeBSD_version >= 300000
2931183Speter#  include <net/if_var.h>
3031183Speter# endif
3122514Sdarrenr#endif
32145510Sdarrenr#include <stdio.h>
33145510Sdarrenr#include <netdb.h>
34145510Sdarrenr#include <string.h>
35145510Sdarrenr#include <stdlib.h>
36145510Sdarrenr#include <unistd.h>
3724583Sdarrenr#include "ipsend.h"
3822514Sdarrenr
3931183Speterextern	int	opts;
4022514Sdarrenr
4153024Sguidostatic	u_char	pbuf[65536];	/* 1 big packet */
4231183Spetervoid	printpacket __P((ip_t *));
4322514Sdarrenr
4422514Sdarrenr
4531183Spetervoid printpacket(ip)
4622514Sdarrenrip_t	*ip;
4722514Sdarrenr{
4822514Sdarrenr	tcphdr_t *t;
4922514Sdarrenr	int i, j;
5022514Sdarrenr
51145510Sdarrenr	t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
5222514Sdarrenr	if (ip->ip_tos)
5322514Sdarrenr		printf("tos %#x ", ip->ip_tos);
5422514Sdarrenr	if (ip->ip_off & 0x3fff)
5522514Sdarrenr		printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3);
5622514Sdarrenr	printf("len %d id %d ", ip->ip_len, ip->ip_id);
5722514Sdarrenr	printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p,
5822514Sdarrenr		inet_ntoa(ip->ip_src));
5922514Sdarrenr	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
6022514Sdarrenr		printf(",%d", t->th_sport);
6122514Sdarrenr	printf(" dst %s", inet_ntoa(ip->ip_dst));
6222514Sdarrenr	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
6322514Sdarrenr		printf(",%d", t->th_dport);
6422514Sdarrenr	if (ip->ip_p == IPPROTO_TCP) {
6522514Sdarrenr		printf(" seq %lu:%lu flags ",
6622514Sdarrenr			(u_long)t->th_seq, (u_long)t->th_ack);
6722514Sdarrenr		for (j = 0, i = 1; i < 256; i *= 2, j++)
6822514Sdarrenr			if (t->th_flags & i)
6922514Sdarrenr				printf("%c", "FSRPAU--"[j]);
7022514Sdarrenr	}
7122514Sdarrenr	putchar('\n');
7222514Sdarrenr}
7322514Sdarrenr
7422514Sdarrenr
7522514Sdarrenrint	ip_resend(dev, mtu, r, gwip, datain)
7622514Sdarrenrchar	*dev;
7722514Sdarrenrint	mtu;
7822514Sdarrenrstruct	in_addr	gwip;
7922514Sdarrenrstruct	ipread	*r;
8022514Sdarrenrchar	*datain;
8122514Sdarrenr{
8222514Sdarrenr	ether_header_t	*eh;
8322514Sdarrenr	char	dhost[6];
8422514Sdarrenr	ip_t	*ip;
85145510Sdarrenr	int	fd, wfd = initdevice(dev, 5), len, i;
8622514Sdarrenr
87161357Sguido	if (wfd == -1)
88161357Sguido		return -1;
89161357Sguido
9022514Sdarrenr	if (datain)
9122514Sdarrenr		fd = (*r->r_open)(datain);
9222514Sdarrenr	else
9322514Sdarrenr		fd = (*r->r_open)("-");
94145510Sdarrenr
9522514Sdarrenr	if (fd < 0)
9622514Sdarrenr		exit(-1);
9722514Sdarrenr
9853024Sguido	ip = (struct ip *)pbuf;
9922514Sdarrenr	eh = (ether_header_t *)malloc(sizeof(*eh));
10072003Sdarrenr	if(!eh)
10172003Sdarrenr	    {
10272003Sdarrenr		perror("malloc failed");
10372003Sdarrenr		return -2;
10472003Sdarrenr	    }
10522514Sdarrenr
10631183Speter	bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost));
10722514Sdarrenr	if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
10822514Sdarrenr	    {
10922514Sdarrenr		perror("arp");
110161357Sguido		free(eh);
11122514Sdarrenr		return -2;
11222514Sdarrenr	    }
11322514Sdarrenr
11453024Sguido	while ((i = (*r->r_readip)((char *)pbuf, sizeof(pbuf), NULL, NULL)) > 0)
11522514Sdarrenr	    {
11631183Speter		if (!(opts & OPT_RAW)) {
11731183Speter			len = ntohs(ip->ip_len);
11831183Speter			eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
11931183Speter			eh->ether_type = htons((u_short)ETHERTYPE_IP);
12031183Speter			if (!gwip.s_addr) {
12131183Speter				if (arp((char *)&gwip,
12231183Speter					(char *)A_A eh->ether_dhost) == -1) {
12331183Speter					perror("arp");
12431183Speter					continue;
12531183Speter				}
12631183Speter			} else
12731183Speter				bcopy(dhost, (char *)A_A eh->ether_dhost,
12831183Speter				      sizeof(dhost));
12931183Speter			if (!ip->ip_sum)
13031183Speter				ip->ip_sum = chksum((u_short *)ip,
131145510Sdarrenr						    IP_HL(ip) << 2);
13231183Speter			bcopy(ip, (char *)(eh + 1), len);
13331183Speter			len += sizeof(*eh);
13431183Speter			printpacket(ip);
13531183Speter		} else {
13653024Sguido			eh = (ether_header_t *)pbuf;
13731183Speter			len = i;
13831183Speter		}
13922514Sdarrenr
14031183Speter		if (sendip(wfd, (char *)eh, len) == -1)
14122514Sdarrenr		    {
14222514Sdarrenr			perror("send_packet");
14322514Sdarrenr			break;
14422514Sdarrenr		    }
14522514Sdarrenr	    }
14622514Sdarrenr	(*r->r_close)();
147161357Sguido	free(eh);
14822514Sdarrenr	return 0;
14922514Sdarrenr}
150