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