From efa214533ceb89a74daba68cc4dd996d9f35d556 Mon Sep 17 00:00:00 2001 From: Salvatore Pitrulli Date: Tue, 22 Mar 2011 12:48:02 +0100 Subject: [PATCH] In tun mode, device's fake MAC address is derived from its EUI-64. --- tools/stm32w/wpcapslip6/wpcapslip6.c | 54 ++++++++++++++++++------- tools/stm32w/wpcapslip6/wpcapslip6.exe | Bin 43757 -> 44269 bytes 2 files changed, 40 insertions(+), 14 deletions(-) mode change 100644 => 100755 tools/stm32w/wpcapslip6/wpcapslip6.c mode change 100644 => 100755 tools/stm32w/wpcapslip6/wpcapslip6.exe diff --git a/tools/stm32w/wpcapslip6/wpcapslip6.c b/tools/stm32w/wpcapslip6/wpcapslip6.c old mode 100644 new mode 100755 index 4cb27a610..730ec3a26 --- a/tools/stm32w/wpcapslip6/wpcapslip6.c +++ b/tools/stm32w/wpcapslip6/wpcapslip6.c @@ -116,13 +116,11 @@ static bool clean_route = false; static bool clean_neighb = false; static struct uip_eth_addr adapter_eth_addr; static char * if_name; -static char * if_mac; OSVERSIONINFO osVersionInfo; /* Fictitious Ethernet address of the attached device (used in tun mode). */ -#define DEV_MAC_ADDR "02-00-00-00-00-02" -static const struct uip_eth_addr dev_eth_addr = {{0x02,0x00,0x00,0x00,0x00,0x02}}; +static struct uip_eth_addr dev_eth_addr = {{0x00,0x00,0x00,0x00,0x00,0x00}}; static bool request_mac = true; @@ -327,22 +325,51 @@ read_more: if(inpktbuf[0] == '!') { if (inpktbuf[1] == 'M' && inbufptr == 18) { /* Read gateway MAC address and autoconfigure tap0 interface */ - char macs[24]; - int i, pos; + char macs64[24], macs48[18]; + int addr_bytes[8]; + int i, pos; for(i = 0, pos = 0; i < 16; i++) { - macs[pos++] = inpktbuf[2 + i]; + macs64[pos++] = inpktbuf[2 + i]; if ((i & 1) == 1 && i < 14) { - macs[pos++] = ':'; + macs64[pos++] = '-'; } } - macs[pos] = '\0'; - printf("*** Gateway's MAC address: %s\n", macs); + macs64[pos] = '\0'; + printf("*** Gateway's MAC address: %s\n", macs64); mac_received = true; + + sscanf(macs64, "%2X-%2X-%2X-%2X-%2X-%2X-%2X-%2X", + &addr_bytes[0], + &addr_bytes[1], + &addr_bytes[2], + &addr_bytes[3], + &addr_bytes[4], + &addr_bytes[5], + &addr_bytes[6], + &addr_bytes[7]); + + /* Form a fictitious MAC address for the attached device from its EUI-64 (2 middle bytes elided) */ + addr_bytes[0] |= 0x02; + for(i=0;i<3;i++){ + dev_eth_addr.addr[i] = addr_bytes[i]; + } + for(i=3;i<6;i++){ + dev_eth_addr.addr[i] = addr_bytes[i+2]; + } + sprintf(macs48,"%02X-%02X-%02X-%02X-%02X-%02X", + dev_eth_addr.addr[0], + dev_eth_addr.addr[1], + dev_eth_addr.addr[2], + dev_eth_addr.addr[3], + dev_eth_addr.addr[4], + dev_eth_addr.addr[5]); + + printf("Fictitious MAC-48: %s\n", macs48); if(autoconf){ - if(IPAddrFromPrefix(autoconf_addr, ipprefix, macs)!=0){ + if(IPAddrFromPrefix(autoconf_addr, ipprefix, macs64)!=0){ fprintf(stderr, "Invalid IPv6 address.\n"); exit(1); } @@ -353,13 +380,13 @@ read_more: if(br_prefix != NULL){ /* RPL Border Router mode. Add route towards LoWPAN. */ - if(IPAddrFromPrefix(rem_ipaddr, br_prefix, macs)!=0){ + if(IPAddrFromPrefix(rem_ipaddr, br_prefix, macs64)!=0){ fprintf(stderr, "Invalid IPv6 address.\n"); exit(1); } addLoWPANRoute(if_name, br_prefix, rem_ipaddr); - addNeighbor(if_name, rem_ipaddr, if_mac);//DEV_MAC_ADDR); + addNeighbor(if_name, rem_ipaddr, macs48); } } @@ -860,7 +887,7 @@ int IPAddrFromPrefix(char * ipaddr, const char * ipprefix, const char * mac) // sscanf requires int instead of 8-bit for hexadecimal variables. - sscanf(mac, "%2X:%2X:%2X:%2X:%2X:%2X:%2X:%2X", + sscanf(mac, "%2X-%2X-%2X-%2X-%2X-%2X-%2X-%2X", &addr_bytes[0], &addr_bytes[1], &addr_bytes[2], @@ -1060,7 +1087,6 @@ main(int argc, char **argv) (int *)&adapter_eth_addr.addr[2],(int *)&adapter_eth_addr.addr[3], (int *)&adapter_eth_addr.addr[4],(int *)&adapter_eth_addr.addr[5]); if_name = wpcap_start(&adapter_eth_addr, verbose); - if_mac = argv[1]; if(local_ipaddr!=NULL){ addAddress(if_name, local_ipaddr); diff --git a/tools/stm32w/wpcapslip6/wpcapslip6.exe b/tools/stm32w/wpcapslip6/wpcapslip6.exe old mode 100644 new mode 100755 index 3317d74a56c95a1211aad4c7ae0d03b2765d687f..84dbcc76807d09267a36b750cb05409547691b87 GIT binary patch delta 9547 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