1145519Sdarrenr/*	$FreeBSD: stable/10/contrib/ipfilter/ipsend/resend.c 342023 2018-12-13 03:12:15Z cy $	*/
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";
11255332Scystatic const char rcsid[] = "@(#)$Id$";
1292686Sdarrenr#endif
13145510Sdarrenr#include <sys/param.h>
1422514Sdarrenr#include <sys/types.h>
1522514Sdarrenr#include <sys/time.h>
1622514Sdarrenr#include <sys/socket.h>
1722514Sdarrenr#include <net/if.h>
1822514Sdarrenr#include <netinet/in.h>
1922514Sdarrenr#include <arpa/inet.h>
2022514Sdarrenr#include <netinet/in_systm.h>
2122514Sdarrenr#include <netinet/ip.h>
2222514Sdarrenr#ifndef	linux
2331183Speter# include <netinet/ip_var.h>
2431183Speter# include <netinet/if_ether.h>
2531183Speter# if __FreeBSD_version >= 300000
2631183Speter#  include <net/if_var.h>
2731183Speter# endif
2822514Sdarrenr#endif
29145510Sdarrenr#include <stdio.h>
30145510Sdarrenr#include <netdb.h>
31145510Sdarrenr#include <string.h>
32145510Sdarrenr#include <stdlib.h>
33145510Sdarrenr#include <unistd.h>
3424583Sdarrenr#include "ipsend.h"
3522514Sdarrenr
3631183Speterextern	int	opts;
3722514Sdarrenr
38255332Scyvoid	dumppacket __P((ip_t *));
3922514Sdarrenr
4022514Sdarrenr
41255332Scyvoid dumppacket(ip)
42255332Scy	ip_t	*ip;
4322514Sdarrenr{
4422514Sdarrenr	tcphdr_t *t;
4522514Sdarrenr	int i, j;
4622514Sdarrenr
47145510Sdarrenr	t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
4822514Sdarrenr	if (ip->ip_tos)
4922514Sdarrenr		printf("tos %#x ", ip->ip_tos);
5022514Sdarrenr	if (ip->ip_off & 0x3fff)
5122514Sdarrenr		printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3);
5222514Sdarrenr	printf("len %d id %d ", ip->ip_len, ip->ip_id);
5322514Sdarrenr	printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p,
5422514Sdarrenr		inet_ntoa(ip->ip_src));
5522514Sdarrenr	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
5622514Sdarrenr		printf(",%d", t->th_sport);
5722514Sdarrenr	printf(" dst %s", inet_ntoa(ip->ip_dst));
5822514Sdarrenr	if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
5922514Sdarrenr		printf(",%d", t->th_dport);
6022514Sdarrenr	if (ip->ip_p == IPPROTO_TCP) {
6122514Sdarrenr		printf(" seq %lu:%lu flags ",
6222514Sdarrenr			(u_long)t->th_seq, (u_long)t->th_ack);
6322514Sdarrenr		for (j = 0, i = 1; i < 256; i *= 2, j++)
6422514Sdarrenr			if (t->th_flags & i)
6522514Sdarrenr				printf("%c", "FSRPAU--"[j]);
6622514Sdarrenr	}
6722514Sdarrenr	putchar('\n');
6822514Sdarrenr}
6922514Sdarrenr
7022514Sdarrenr
7122514Sdarrenrint	ip_resend(dev, mtu, r, gwip, datain)
72255332Scy	char	*dev;
73255332Scy	int	mtu;
74255332Scy	struct	in_addr	gwip;
75255332Scy	struct	ipread	*r;
76255332Scy	char	*datain;
7722514Sdarrenr{
7822514Sdarrenr	ether_header_t	*eh;
7922514Sdarrenr	char	dhost[6];
8022514Sdarrenr	ip_t	*ip;
81145510Sdarrenr	int	fd, wfd = initdevice(dev, 5), len, i;
82255332Scy	mb_t	mb;
8322514Sdarrenr
84161357Sguido	if (wfd == -1)
85161357Sguido		return -1;
86161357Sguido
8722514Sdarrenr	if (datain)
8822514Sdarrenr		fd = (*r->r_open)(datain);
8922514Sdarrenr	else
9022514Sdarrenr		fd = (*r->r_open)("-");
91145510Sdarrenr
9222514Sdarrenr	if (fd < 0)
9322514Sdarrenr		exit(-1);
9422514Sdarrenr
95255332Scy	ip = (struct ip *)mb.mb_buf;
9622514Sdarrenr	eh = (ether_header_t *)malloc(sizeof(*eh));
9772003Sdarrenr	if(!eh)
9872003Sdarrenr	    {
9972003Sdarrenr		perror("malloc failed");
10072003Sdarrenr		return -2;
10172003Sdarrenr	    }
10222514Sdarrenr
103342023Scy	bzero((char *) &eh->ether_shost, sizeof(eh->ether_shost));
10422514Sdarrenr	if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
10522514Sdarrenr	    {
10622514Sdarrenr		perror("arp");
107161357Sguido		free(eh);
10822514Sdarrenr		return -2;
10922514Sdarrenr	    }
11022514Sdarrenr
111255332Scy	while ((i = (*r->r_readip)(&mb, NULL, NULL)) > 0)
11222514Sdarrenr	    {
11331183Speter		if (!(opts & OPT_RAW)) {
11431183Speter			len = ntohs(ip->ip_len);
11531183Speter			eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
11631183Speter			eh->ether_type = htons((u_short)ETHERTYPE_IP);
11731183Speter			if (!gwip.s_addr) {
11831183Speter				if (arp((char *)&gwip,
119342023Scy					(char *) &eh->ether_dhost) == -1) {
12031183Speter					perror("arp");
12131183Speter					continue;
12231183Speter				}
12331183Speter			} else
124342023Scy				bcopy(dhost, (char *) &eh->ether_dhost,
12531183Speter				      sizeof(dhost));
12631183Speter			if (!ip->ip_sum)
12731183Speter				ip->ip_sum = chksum((u_short *)ip,
128145510Sdarrenr						    IP_HL(ip) << 2);
12931183Speter			bcopy(ip, (char *)(eh + 1), len);
13031183Speter			len += sizeof(*eh);
131255332Scy			dumppacket(ip);
13231183Speter		} else {
133255332Scy			eh = (ether_header_t *)mb.mb_buf;
13431183Speter			len = i;
13531183Speter		}
13622514Sdarrenr
13731183Speter		if (sendip(wfd, (char *)eh, len) == -1)
13822514Sdarrenr		    {
13922514Sdarrenr			perror("send_packet");
14022514Sdarrenr			break;
14122514Sdarrenr		    }
14222514Sdarrenr	    }
14322514Sdarrenr	(*r->r_close)();
144161357Sguido	free(eh);
14522514Sdarrenr	return 0;
14622514Sdarrenr}
147