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