Hi.

        I have a trouble that an application packet-injecting by pcap(bpf)'s
        pcap_sendpacket function doesn't communicate to FreeBSD host, but
        can communicate to other machine.  So I researched, and I noticed
        that sys/net/if_ethersubr.c has a structured issue(?)(I didn't know).
        Do you have any idea?


        I made a test program (attached file, fake-arp-reply.c).  Do 'gcc
        fake-arp-reply -lpcap'.  I tested 2 case (8-current self,
        8-current -> 7-stable):

test platform (I tested on 8-current, 7.2-stable)
on 8-current:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -
$ ifconfig rl0
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 00:0b:97:33:1c:30
        inet 192.168.36.6 netmask 0xffffff00 broadcast 192.168.36.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
$ arp -an
? (192.168.36.6) at 00:0b:97:33:1c:30 on rl0 permanent [ethernet]
? (192.168.36.1) at 00:1b:78:37:f1:cf on rl0 [ethernet]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -

on 7-stable:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -
$ ifconfig bge0
bge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=98<VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 00:1b:78:37:f1:cf
        inet 192.168.36.1 netmask 0xffffff00 broadcast 192.168.36.255
        inet6 fe80::21b:78ff:fe37:f1cf%bge0 prefixlen 64 scopeid 0x1 
        media: Ethernet autoselect (1000baseTX <full-duplex>)
        status: active
$ arp -an
? (192.168.36.1) at 00:1b:78:37:f1:cf on bge0 permanent [ethernet]
? (192.168.36.6) at 00:0b:97:33:1c:30 on bge0 [ethernet]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -

TEST 1: 8-current self (same 7-stable self, too)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -
# ./a.out -d rl0 -i 192.168.36.64 -m 10-20-30-40-50-60
rl0, 192.168.36.64 10:20:30:40:50:60
(on other console, ping 192.168.36.64)
arp request catched, arp replyed and done.
# arp -an
? (192.168.36.6) at 00:0b:97:33:1c:30 on rl0 permanent [ethernet]
? (192.168.36.1) at 00:1b:78:37:f1:cf on rl0 [ethernet]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -

TEST 2: 8-current -> 7-stable(same 8-current -> 7-stable, too)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -
# ./a.out -d rl0 -i 192.168.36.64 -m 10-20-30-40-50-60
rl0, 192.168.36.64 10:20:30:40:50:60
 (on other machine's console, ping 192.168.36.64...)
arp request catched, arp replyed and done.

On other machine:
$ ping 192.168.36.64
PING 192.168.36.64 (192.168.36.64): 56 data bytes
^C
--- 192.168.36.64 ping statistics ---
2 packets transmitted, 0 packets received, 100.0% packet loss
$ arp -an
? (192.168.36.1) at 00:1b:78:37:f1:cf on bge0 permanent [ethernet]
? (192.168.36.6) at 00:0b:97:33:1c:30 on bge0 [ethernet]
? (192.168.36.64) at 10:20:30:40:50:60 on bge0 [ethernet]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
- - - - - - - -
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>

struct sendpkt {
        u_char  dmac[6];
        u_char  smac[6];
        u_char  etype[2];
        u_char  htype[2];
        u_char  ptype[2];
        u_char  hlen[1];
        u_char  plen[1];
        u_char  op[2];
        u_char  src_mac[6];
        u_char  src_ipv4[4];
        u_char  dst_mac[6];
        u_char  dst_ipv4[4];
        u_char  trailer[18];
} __packed;

struct sendpkt sendpkt = {
        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, /* overwrite live packet */
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* overwrite argument */
        { 0x08, 0x06, },                         /* constant */
        { 0x00, 0x01, },                         /* constant */
        { 0x08, 0x00, },                         /* constant */
        { 0x06, },                               /* constant */
        { 0x04, },                               /* constant */
        { 0x00, 0x02, },                         /* constant */
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, /* overwrite live packet */
        { 0x00, 0x00, 0x00, 0x00, },             /* overwrite live packet */
        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, /* overwrite argument */
        { 0xff, 0xff, 0xff, 0xff, },             /* overwrite argument */
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    /* constant */
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
};

int
main(int argc, char *argv[])
{
        int     ch;
        u_char  dev[30] = "lo0",
                mac[6]  = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, },
                ipv4[4] = { 0, 0, 0, 0, };
        pcap_t  *p;
        static char errbuf[PCAP_ERRBUF_SIZE];

        while(  (ch = getopt(argc, argv, "d:i:m:")) != -1  )  {
                switch (ch)  {
                case 'd':
                        strlcpy(dev, optarg, sizeof(dev));
                        break;
                case 'i':
                        sscanf(optarg, "%hhd%*[.]%hhd%*[.]%hhd%*[.]%hhd",
                                &ipv4[0], &ipv4[1], &ipv4[2], &ipv4[3]);
                        break;
                case 'm':
                        sscanf(optarg, 
"%hhx%*[:.-]%hhx%*[:.-]%hhx%*[:.-]%hhx%*[:.-]%hhx%*[:.-]%hhx",
                                &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], 
&mac[5]);
                        break;
                default:
                        fprintf(stderr, "-d Device Name -i IPv4 Address -m MAC 
Addresss\n");
                        exit(0);
                        /* NOT REACHABLE */
                }
        }

        printf("%s, %d.%d.%d.%d %02x:%02x:%02x:%02x:%02x:%02x\n",
                dev,
                ipv4[0], ipv4[1], ipv4[2], ipv4[3],
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

        memcpy(&sendpkt.smac,     mac,  sizeof(sendpkt.smac));
        memcpy(&sendpkt.src_mac,  mac,  sizeof(sendpkt.src_mac));
        memcpy(&sendpkt.src_ipv4, ipv4, sizeof(sendpkt.src_ipv4));

        if(  (p = pcap_open_live(dev, 1500/*bytes*/, 1/*TRUE*/, 10/*msec*/, 
errbuf))  )  {
                int in_loop = 1;
                while(  in_loop  )  {
                        struct pcap_pkthdr pkt_info;
                        u_char *recvpkt;
                        if(  (recvpkt = (u_char *)pcap_next(p, &pkt_info))  )  {
                                if(  recvpkt[12] == 0x08    && recvpkt[13] == 
0x06
                                &&   recvpkt[20] == 0x00    && recvpkt[21] == 
0x01
                                &&   recvpkt[38] == ipv4[0] && recvpkt[39] == 
ipv4[1]
                                &&   recvpkt[40] == ipv4[2] && recvpkt[41] == 
ipv4[3]  )  {
                                        memcpy(sendpkt.dmac,     &recvpkt[6],  
sizeof(sendpkt.dmac));
                                        memcpy(sendpkt.dst_mac,  &recvpkt[22], 
sizeof(sendpkt.dst_mac));
                                        memcpy(sendpkt.dst_ipv4, &recvpkt[28], 
sizeof(sendpkt.dst_ipv4));
                                        pcap_sendpacket(p, (u_char *)&sendpkt, 
sizeof(sendpkt));
                                        printf("arp request catched, arp 
replyed and done.\n");
                                        in_loop = 0;
                                }  else  {
                                        printf("len=%d           \r", 
pkt_info.caplen);
                                        if(  recvpkt[12] == 0x08    && 
recvpkt[13] == 0x06
                                        &&   recvpkt[20] == 0x00    && 
recvpkt[21] == 0x01  )  {
                                                printf("arp? recv=%d.%d.%d.%d / 
argv=%d.%d.%d.%d\n",
                                                        recvpkt[38], 
recvpkt[39], recvpkt[40], recvpkt[41],
                                                        ipv4[0], ipv4[1], 
ipv4[2], ipv4[3]);
                                        }
                                        fflush(stdout);
                                }
                        }
                        usleep(100);
                }

                pcap_close(p);
        }  else  {
                fprintf(stderr, "pcap_open_live: error '%s'\n", errbuf);
        }

        return 0;
}
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to