resend.c revision 72003
1/* 2 * resend.c (C) 1995-1998 Darren Reed 3 * 4 * This was written to test what size TCP fragments would get through 5 * various TCP/IP packet filters, as used in IP firewalls. In certain 6 * conditions, enough of the TCP header is missing for unpredictable 7 * results unless the filter is aware that this can happen. 8 * 9 * Redistribution and use in source and binary forms are permitted 10 * provided that this notice is preserved and due credit is given 11 * to the original author and the contributors. 12 */ 13#if !defined(lint) 14static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed"; 15static const char rcsid[] = "@(#)$Id: resend.c,v 2.1.4.1 2001/01/10 06:21:20 darrenr Exp $"; 16#endif 17#include <stdio.h> 18#include <netdb.h> 19#include <string.h> 20#include <stdlib.h> 21#include <unistd.h> 22#include <sys/types.h> 23#include <sys/time.h> 24#include <sys/socket.h> 25#include <net/if.h> 26#include <netinet/in.h> 27#include <arpa/inet.h> 28#include <netinet/in_systm.h> 29#include <netinet/ip.h> 30#include <netinet/tcp.h> 31#include <netinet/udp.h> 32#include <netinet/ip_icmp.h> 33#ifndef linux 34# include <netinet/ip_var.h> 35# include <netinet/if_ether.h> 36# if __FreeBSD_version >= 300000 37# include <net/if_var.h> 38# endif 39#endif 40#include "ipsend.h" 41 42extern int opts; 43 44static u_char pbuf[65536]; /* 1 big packet */ 45void printpacket __P((ip_t *)); 46 47 48void printpacket(ip) 49ip_t *ip; 50{ 51 tcphdr_t *t; 52 int i, j; 53 54 t = (tcphdr_t *)((char *)ip + (ip->ip_hl << 2)); 55 if (ip->ip_tos) 56 printf("tos %#x ", ip->ip_tos); 57 if (ip->ip_off & 0x3fff) 58 printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3); 59 printf("len %d id %d ", ip->ip_len, ip->ip_id); 60 printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p, 61 inet_ntoa(ip->ip_src)); 62 if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) 63 printf(",%d", t->th_sport); 64 printf(" dst %s", inet_ntoa(ip->ip_dst)); 65 if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) 66 printf(",%d", t->th_dport); 67 if (ip->ip_p == IPPROTO_TCP) { 68 printf(" seq %lu:%lu flags ", 69 (u_long)t->th_seq, (u_long)t->th_ack); 70 for (j = 0, i = 1; i < 256; i *= 2, j++) 71 if (t->th_flags & i) 72 printf("%c", "FSRPAU--"[j]); 73 } 74 putchar('\n'); 75} 76 77 78int ip_resend(dev, mtu, r, gwip, datain) 79char *dev; 80int mtu; 81struct in_addr gwip; 82struct ipread *r; 83char *datain; 84{ 85 ether_header_t *eh; 86 char dhost[6]; 87 ip_t *ip; 88 int fd, wfd = initdevice(dev, 0, 5), len, i; 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 return -2; 111 } 112 113 while ((i = (*r->r_readip)((char *)pbuf, sizeof(pbuf), NULL, NULL)) > 0) 114 { 115 if (!(opts & OPT_RAW)) { 116 len = ntohs(ip->ip_len); 117 eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len); 118 eh->ether_type = htons((u_short)ETHERTYPE_IP); 119 if (!gwip.s_addr) { 120 if (arp((char *)&gwip, 121 (char *)A_A eh->ether_dhost) == -1) { 122 perror("arp"); 123 continue; 124 } 125 } else 126 bcopy(dhost, (char *)A_A eh->ether_dhost, 127 sizeof(dhost)); 128 if (!ip->ip_sum) 129 ip->ip_sum = chksum((u_short *)ip, 130 ip->ip_hl << 2); 131 bcopy(ip, (char *)(eh + 1), len); 132 len += sizeof(*eh); 133 printpacket(ip); 134 } else { 135 eh = (ether_header_t *)pbuf; 136 len = i; 137 } 138 139 if (sendip(wfd, (char *)eh, len) == -1) 140 { 141 perror("send_packet"); 142 break; 143 } 144 } 145 (*r->r_close)(); 146 return 0; 147} 148