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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 delta 9096 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 I!G@{-19X#v-~a#s