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