141edb306SCy Schubert
241edb306SCy Schubert /*
341edb306SCy Schubert * resend.c (C) 1995-1998 Darren Reed
441edb306SCy Schubert *
541edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert *
741edb306SCy Schubert */
841edb306SCy Schubert #include <sys/param.h>
941edb306SCy Schubert #include <sys/types.h>
1041edb306SCy Schubert #include <sys/time.h>
1141edb306SCy Schubert #include <sys/socket.h>
1241edb306SCy Schubert #include <net/if.h>
1341edb306SCy Schubert #include <netinet/in.h>
1441edb306SCy Schubert #include <arpa/inet.h>
1541edb306SCy Schubert #include <netinet/in_systm.h>
1641edb306SCy Schubert #include <netinet/ip.h>
1741edb306SCy Schubert # include <netinet/ip_var.h>
1841edb306SCy Schubert # include <netinet/if_ether.h>
1941edb306SCy Schubert #include <stdio.h>
2041edb306SCy Schubert #include <netdb.h>
2141edb306SCy Schubert #include <string.h>
2241edb306SCy Schubert #include <stdlib.h>
2341edb306SCy Schubert #include <unistd.h>
2441edb306SCy Schubert #include "ipsend.h"
2541edb306SCy Schubert
2641edb306SCy Schubert extern int opts;
2741edb306SCy Schubert
2841edb306SCy Schubert void dumppacket(ip_t *);
2941edb306SCy Schubert
3041edb306SCy Schubert
31efeb8bffSCy Schubert void
dumppacket(ip_t * ip)32efeb8bffSCy Schubert dumppacket(ip_t *ip)
3341edb306SCy Schubert {
3441edb306SCy Schubert tcphdr_t *t;
3541edb306SCy Schubert int i, j;
3641edb306SCy Schubert
3741edb306SCy Schubert t = (tcphdr_t *)((char *)ip + (IP_HL(ip) << 2));
3841edb306SCy Schubert if (ip->ip_tos)
3941edb306SCy Schubert printf("tos %#x ", ip->ip_tos);
4041edb306SCy Schubert if (ip->ip_off & 0x3fff)
4141edb306SCy Schubert printf("frag @%#x ", (ip->ip_off & 0x1fff) << 3);
4241edb306SCy Schubert printf("len %d id %d ", ip->ip_len, ip->ip_id);
4341edb306SCy Schubert printf("ttl %d p %d src %s", ip->ip_ttl, ip->ip_p,
4441edb306SCy Schubert inet_ntoa(ip->ip_src));
4541edb306SCy Schubert if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
4641edb306SCy Schubert printf(",%d", t->th_sport);
4741edb306SCy Schubert printf(" dst %s", inet_ntoa(ip->ip_dst));
4841edb306SCy Schubert if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
4941edb306SCy Schubert printf(",%d", t->th_dport);
5041edb306SCy Schubert if (ip->ip_p == IPPROTO_TCP) {
5141edb306SCy Schubert printf(" seq %lu:%lu flags ",
5241edb306SCy Schubert (u_long)t->th_seq, (u_long)t->th_ack);
5341edb306SCy Schubert for (j = 0, i = 1; i < 256; i *= 2, j++)
5441edb306SCy Schubert if (t->th_flags & i)
5541edb306SCy Schubert printf("%c", "FSRPAU--"[j]);
5641edb306SCy Schubert }
5741edb306SCy Schubert putchar('\n');
5841edb306SCy Schubert }
5941edb306SCy Schubert
6041edb306SCy Schubert
61efeb8bffSCy Schubert int
ip_resend(char * dev,int mtu,struct ipread * r,struct in_addr gwip,char * datain)62efeb8bffSCy Schubert ip_resend(char *dev, int mtu, struct ipread *r, struct in_addr gwip,
63efeb8bffSCy Schubert char *datain)
6441edb306SCy Schubert {
6541edb306SCy Schubert ether_header_t *eh;
6641edb306SCy Schubert char dhost[6];
6741edb306SCy Schubert ip_t *ip;
6841edb306SCy Schubert int fd, wfd = initdevice(dev, 5), len, i;
6941edb306SCy Schubert mb_t mb;
7041edb306SCy Schubert
7141edb306SCy Schubert if (wfd == -1)
72*2582ae57SCy Schubert return (-1);
7341edb306SCy Schubert
7441edb306SCy Schubert if (datain)
7541edb306SCy Schubert fd = (*r->r_open)(datain);
7641edb306SCy Schubert else
7741edb306SCy Schubert fd = (*r->r_open)("-");
7841edb306SCy Schubert
7941edb306SCy Schubert if (fd < 0)
8041edb306SCy Schubert exit(-1);
8141edb306SCy Schubert
8241edb306SCy Schubert ip = (struct ip *)mb.mb_buf;
8341edb306SCy Schubert eh = (ether_header_t *)malloc(sizeof(*eh));
8441edb306SCy Schubert if(!eh)
8541edb306SCy Schubert {
8641edb306SCy Schubert perror("malloc failed");
87*2582ae57SCy Schubert return (-2);
8841edb306SCy Schubert }
8941edb306SCy Schubert
9041edb306SCy Schubert bzero((char *) &eh->ether_shost, sizeof(eh->ether_shost));
9141edb306SCy Schubert if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
9241edb306SCy Schubert {
9341edb306SCy Schubert perror("arp");
9441edb306SCy Schubert free(eh);
95*2582ae57SCy Schubert return (-2);
9641edb306SCy Schubert }
9741edb306SCy Schubert
9841edb306SCy Schubert while ((i = (*r->r_readip)(&mb, NULL, NULL)) > 0)
9941edb306SCy Schubert {
10041edb306SCy Schubert if (!(opts & OPT_RAW)) {
10141edb306SCy Schubert len = ntohs(ip->ip_len);
10241edb306SCy Schubert eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
10341edb306SCy Schubert eh->ether_type = htons((u_short)ETHERTYPE_IP);
10441edb306SCy Schubert if (!gwip.s_addr) {
10541edb306SCy Schubert if (arp((char *)&gwip,
10641edb306SCy Schubert (char *) &eh->ether_dhost) == -1) {
10741edb306SCy Schubert perror("arp");
10841edb306SCy Schubert continue;
10941edb306SCy Schubert }
11041edb306SCy Schubert } else
11141edb306SCy Schubert bcopy(dhost, (char *) &eh->ether_dhost,
11241edb306SCy Schubert sizeof(dhost));
11341edb306SCy Schubert if (!ip->ip_sum)
11441edb306SCy Schubert ip->ip_sum = chksum((u_short *)ip,
11541edb306SCy Schubert IP_HL(ip) << 2);
11641edb306SCy Schubert bcopy(ip, (char *)(eh + 1), len);
11741edb306SCy Schubert len += sizeof(*eh);
11841edb306SCy Schubert dumppacket(ip);
11941edb306SCy Schubert } else {
12041edb306SCy Schubert eh = (ether_header_t *)mb.mb_buf;
12141edb306SCy Schubert len = i;
12241edb306SCy Schubert }
12341edb306SCy Schubert
12441edb306SCy Schubert if (sendip(wfd, (char *)eh, len) == -1)
12541edb306SCy Schubert {
12641edb306SCy Schubert perror("send_packet");
12741edb306SCy Schubert break;
12841edb306SCy Schubert }
12941edb306SCy Schubert }
13041edb306SCy Schubert (*r->r_close)();
13141edb306SCy Schubert free(eh);
132*2582ae57SCy Schubert return (0);
13341edb306SCy Schubert }
134