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