resend.c revision 31183
162587Sitojun/* 262587Sitojun * resend.c (C) 1995-1997 Darren Reed 362587Sitojun * 4139823Simp * This was written to test what size TCP fragments would get through 562587Sitojun * various TCP/IP packet filters, as used in IP firewalls. In certain 662587Sitojun * conditions, enough of the TCP header is missing for unpredictable 762587Sitojun * results unless the filter is aware that this can happen. 862587Sitojun * 962587Sitojun * Redistribution and use in source and binary forms are permitted 1062587Sitojun * provided that this notice is preserved and due credit is given 1162587Sitojun * to the original author and the contributors. 1262587Sitojun */ 1362587Sitojun#if !defined(lint) 1462587Sitojunstatic const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed"; 1562587Sitojunstatic const char rcsid[] = "@(#)$Id: resend.c,v 2.0.2.12 1997/10/23 11:42:46 darrenr Exp $"; 1662587Sitojun#endif 1762587Sitojun#include <stdio.h> 1862587Sitojun#include <netdb.h> 1962587Sitojun#include <string.h> 2062587Sitojun#include <stdlib.h> 2162587Sitojun#include <unistd.h> 2262587Sitojun#include <sys/types.h> 2362587Sitojun#include <sys/time.h> 2462587Sitojun#include <sys/socket.h> 2562587Sitojun#include <net/if.h> 2662587Sitojun#include <netinet/in.h> 2762587Sitojun#include <arpa/inet.h> 2862587Sitojun#include <netinet/in_systm.h> 2962587Sitojun#include <netinet/ip.h> 3062587Sitojun#include <netinet/tcp.h> 3162587Sitojun#include <netinet/udp.h> 3262587Sitojun#include <netinet/ip_icmp.h> 3362587Sitojun#ifndef linux 3462587Sitojun# include <netinet/ip_var.h> 3562587Sitojun# include <netinet/if_ether.h> 3662587Sitojun# if __FreeBSD_version >= 300000 3762587Sitojun# include <net/if_var.h> 3862587Sitojun# endif 3962587Sitojun#endif 4062587Sitojun#include "ipsend.h" 4162587Sitojun 4262587Sitojunextern int opts; 4362587Sitojun 4462587Sitojunstatic u_char buf[65536]; /* 1 big packet */ 4562587Sitojunvoid printpacket __P((ip_t *)); 4692723Salfred 4762587Sitojun 4862587Sitojunvoid printpacket(ip) 4962587Sitojunip_t *ip; 5062587Sitojun{ 5192723Salfred tcphdr_t *t; 5292723Salfred int i, j; 5392723Salfred 5492723Salfred t = (tcphdr_t *)((char *)ip + (ip->ip_hl << 2)); 5562587Sitojun if (ip->ip_tos) 5692723Salfred printf("tos %#x ", ip->ip_tos); 5792723Salfred if (ip->ip_off & 0x3fff) 5892723Salfred printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3); 5992723Salfred printf("len %d id %d ", ip->ip_len, ip->ip_id); 6092723Salfred printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p, 6192723Salfred inet_ntoa(ip->ip_src)); 6262587Sitojun if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) 6362587Sitojun printf(",%d", t->th_sport); 6462587Sitojun 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 *)buf; 99 eh = (ether_header_t *)malloc(sizeof(*eh)); 100 101 bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost)); 102 if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1)) 103 { 104 perror("arp"); 105 return -2; 106 } 107 108 while ((i = (*r->r_readip)(buf, sizeof(buf), NULL, NULL)) > 0) 109 { 110 if (!(opts & OPT_RAW)) { 111 len = ntohs(ip->ip_len); 112 eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len); 113 eh->ether_type = htons((u_short)ETHERTYPE_IP); 114 if (!gwip.s_addr) { 115 if (arp((char *)&gwip, 116 (char *)A_A eh->ether_dhost) == -1) { 117 perror("arp"); 118 continue; 119 } 120 } else 121 bcopy(dhost, (char *)A_A eh->ether_dhost, 122 sizeof(dhost)); 123 if (!ip->ip_sum) 124 ip->ip_sum = chksum((u_short *)ip, 125 ip->ip_hl << 2); 126 bcopy(ip, (char *)(eh + 1), len); 127 len += sizeof(*eh); 128 printpacket(ip); 129 } else { 130 eh = (ether_header_t *)buf; 131 len = i; 132 } 133 134 if (sendip(wfd, (char *)eh, len) == -1) 135 { 136 perror("send_packet"); 137 break; 138 } 139 } 140 (*r->r_close)(); 141 return 0; 142} 143