From owner-freebsd-net@FreeBSD.ORG Sun Jul 5 05:53:28 2009 Return-Path: Delivered-To: freebsd-net@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8F19B106566C; Sun, 5 Jul 2009 05:53:28 +0000 (UTC) (envelope-from nork@FreeBSD.org) Received: from sakura.ninth-nine.com (unknown [IPv6:2001:2f0:104:80a0:21b:78ff:fe37:f1cf]) by mx1.freebsd.org (Postfix) with ESMTP id 053888FC1A; Sun, 5 Jul 2009 05:53:27 +0000 (UTC) (envelope-from nork@FreeBSD.org) Received: from nadesico.ninth-nine.com (ns1.ninth-nine.com [219.127.74.121] (may be forged)) (authenticated bits=0) by sakura.ninth-nine.com (8.14.3/8.14.3/NinthNine) with ESMTP id n655rLMh041355; Sun, 5 Jul 2009 14:53:26 +0900 (JST) (envelope-from nork@FreeBSD.org) Date: Sun, 5 Jul 2009 14:53:20 +0900 From: Norikatsu Shigemura To: freebsd-net@FreeBSD.org Message-Id: <20090705145320.fdd081ef.nork@FreeBSD.org> X-Mailer: Sylpheed 2.6.0 (GTK+ 2.16.2; i386-portbld-freebsd8.0) Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart=_Sun__5_Jul_2009_14_53_20_+0900_y8D5l2IG6XLuZe3b" Cc: Norikatsu Shigemura Subject: pcap(bpf) packet injection not-acceptable on FreeBSD host. X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Jul 2009 05:53:28 -0000 This is a multi-part message in MIME format. --Multipart=_Sun__5_Jul_2009_14_53_20_+0900_y8D5l2IG6XLuZe3b Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit 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 metric 0 mtu 1500 options=8 ether 00:0b:97:33:1c:30 inet 192.168.36.6 netmask 0xffffff00 broadcast 192.168.36.255 media: Ethernet autoselect (100baseTX ) 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 metric 0 mtu 1500 options=98 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 ) 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] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --Multipart=_Sun__5_Jul_2009_14_53_20_+0900_y8D5l2IG6XLuZe3b Content-Type: text/plain; name="fake-arp-reply.c" Content-Disposition: attachment; filename="fake-arp-reply.c" Content-Transfer-Encoding: 7bit #include #include #include #include #include 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; } --Multipart=_Sun__5_Jul_2009_14_53_20_+0900_y8D5l2IG6XLuZe3b--