Date: Fri, 27 Feb 2004 11:39:12 -0500 From: Matthew Goward <mgoward@mail.msen.com> To: freebsd-ipfw@freebsd.org Subject: Gathering data via Divert Sockets Message-ID: <20040227113912.S8241@conch.msen.com>
next in thread | raw e-mail | index | archive | help
I am currently playing with a toy app using divert and ipfw on 5.2.1. One of the bits of info I am trying to get ahold of is the rule number in ipfw that sent the diverted packet over to me. The DIVERT(4) man page states: Diverted packets may be read unaltered via read(2), recv(2), or recvfrom(2). In the latter case, the address returned will have its port set to some tag supplied by the packet diverter, (usually the ipfw rule number) But I cant seem to get it to do so, nor am i really sure I want it to do so. I still need the source and dest ip and ports, along with the IPFW rule number. Here is a bit of what I have (all the error checking and setup stuff pulled out for brievity) get a socket fd=socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) bind to it: bindPort.sin_family=AF_INET; bindPort.sin_port=htons(atol(port)); bindPort.sin_addr.s_addr=0; if ((ret=bind(fd,(struct sockaddr *) &bindPort, sizeof(struct sockaddr_in))) != 0) { blah blah error checking} stolen from the divert socket mini faq to try and use the data start grabbing data: sinlen=sizeof(struct sockaddr_in); while(1) { n=recvfrom(fd, packet, BUFSIZE, 0, (struct sockaddr *) &sin, &sinlen); iphdr=(struct ip*)packet; if (iphdr->ip_p == IPPROTO_TCP) { tcphdr = (struct tcphdr *) (packet + sizeof(struct ip)); } else if (iphdr->ip_p == IPPROTO_UDP) { udphdr = (struct udphdr *) (packet + sizeof(struct ip)); } printf("\n"); printf("%s: Source address: %s\n",progname, inet_ntoa(iphdr->ip_src)); if (iphdr->ip_p == IPPROTO_TCP) printf("%s: Source port: %d\n",progname, ntohs(tcphdr->th_sport)); printf("%s: Destination address: %s\n", progname, inet_ntoa(iphdr->ip_dst)); if (iphdr->ip_p == IPPROTO_TCP) printf("%s: Destination port: %d\n\n",progname, ntohs(tcphdr->th_dport)); printf("%s: Receiving IF address: %s\n", progname, inet_ntoa(sin.sin_addr)); printf("%s: Protocol number: %i\n", progname, iphdr->ip_p); printf("%s: Header length: %i\n", progname, iphdr->ip_hl); printf("%s: Header ttl: %i\n", progname, iphdr->ip_ttl); printf("%s: Header sum: %i\n\n", progname, iphdr->ip_sum); if (iphdr->ip_p == IPPROTO_TCP) { printf("%s: Sequence Number %d\n",progname, ntohs(tcphdr->th_seq)); printf("%s: Acknowledgement Number %d\n\n",progname, ntohs(tcphdr->th_ack)); } } And it all works as you would expect. This really was from source port 1360 and to port 25. The packet in hex: 69 16 00 52 247 230 64 00 64 06 61 91 192 168 66 11 192 168 66 22 05 80 00 25 49 238 186 32 30 184 225 162 128 16 226 64 195 168 00 00 01 01 08 10 27 81 180 235 00 38 09 44 Source address: 192.168.66.11 Source port: 1360 Destination address: 192.168.66.22 Destination port: 25 Receiving IF address: 192.168.66.22 Protocol number: 6 Header length: 5 Header ttl: 64 Header sum: 23357 Sequence Number 12782 Acknowledgement Number 7864 DIVERT 52 bytes 52 bytes reinjected. Now, I need the data this way as i am also stuffing it off to a file in pcap format. But from reading the divert man page I would expect to see the rule number somewhere. Sorry to have rambled on so much. I just want to know how I can continue to get all the data I have now, but also find out what rule number ipfw is hitting on before diverting to me. Thank you so much for you help, Matthew Goward m g o w a r d @ e v i l o v e r l o r d . o r g mgoward@IneedAname 906> uname -a FreeBSD IneedAname 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #2: Thu Feb 26 12:57:33 GMT 2004 +root@IneedAname:/usr/obj/usr/src/sys/MATT i38 mgoward@IneedAname 909> diff MATT GENERIC 49c49 < options SCSI_DELAY=2000 #Delay (in ms) before probing SCSI --- > options SCSI_DELAY=15000 #Delay (in ms) before probing SCSI 60,69d59 < options IPFIREWALL #firewall < options IPFIREWALL_VERBOSE #enable logging to syslogd(8) < options IPDIVERT #divert sockets < options IPFIREWALL_VERBOSE_LIMIT=100 < #options IPFIREWALL_DEFAULT_TO_ACCEPT < options RANDOM_IP_ID < options DUMMYNET < options TCP_DROP_SYNFIN < options IPSTEALTH < #options "ICMP_BANDLIM" 00001 48 2549 divert 5555 tcp from 192.168.66.11 to 192.168.66.22 dst-port 25 00001 0 0 divert 5555 udp from 192.168.55.22 to 192.168.66.22 dst-port 25 00002 0 0 divert 5555 tcp from 192.168.66.22 25 to 192.168.55.22 00002 0 0 divert 5555 udp from 192.168.66.22 25 to 192.168.55.22 00100 54 2914 allow ip from any to any via lo0 00200 0 0 deny ip from any to 127.0.0.0/8 00300 0 0 deny ip from 127.0.0.0/8 to any 65000 34423 9607284 allow ip from any to any 65535 0 0 deny ip from any to any ipfw2 initialized, divert enabled, rule-based forwarding enabled, default to deny, logging limited to 100 packets/entry by +default if anything else would be helpfull let me know.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040227113912.S8241>