/* mac2eui64.c Conversion from the IEEE 802 MAC format to the IEEE EUI-64 format. Displays values suitable for use as a 64 bit interface ID in A6 RRs. Also displayed are labels suitable for use with PTR RRs in the two defined reverse zones ip6.arpa (A6) and ip6.int (AAAA). Copyright (C) 2003 Trond Endrestøl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. $Ximalas$ */ #include #include #include #include int main(int argc, char **argv) { void Usage(const char * const argv0, int ReturnValue); void Version(const char * const argv0); void TransformMAC(const char * const argv0, const char * const argvi); int c; size_t i; opterr = 0; while ((c = getopt(argc, argv, "hv")) != -1) { switch (c) { case 'h': Usage(argv[0], EXIT_SUCCESS); break; case 'v': Version(argv[0]); break; case '?': fprintf(stderr, "%s: invalid option -%c\n", argv[0], optopt); break; default: fprintf(stderr, "%s: something is dead wrong with getopt() or with this program\n", argv[0]); return EXIT_FAILURE; break; } } i = optind; if (i == argc) Usage(argv[0], EXIT_FAILURE); TransformMAC(argv[0], argv[i++]); while (i < argc) { puts(""); TransformMAC(argv[0], argv[i++]); } return EXIT_SUCCESS; } /* main() */ void Usage(const char * const argv0, int ReturnValue) { fprintf((ReturnValue == EXIT_SUCCESS) ? stdout : stderr, "Usage: %s [-h | -v | [macaddress2] ... [macaddressN]]\n\n" "Options:\n" "-h show this help\n" "-v display version and copyright\n\n" "MAC addresses must consist of 12 hex digits with leading zeroes.\n" "Any punctuation is ignored. Examples of valid MAC addresses:\n\n" " 00:50:DA:2C:8F:55\n" " 00-50-DA-2C-8F-55\n" " 0050.DA2C.8F55\n" " 0050DA2C8F55\n", argv0); exit(ReturnValue); } /* Usage() */ void Version(const char * const argv0) { printf("%s version 1.0\n\n" "Conversion from the IEEE 802 MAC format to the IEEE EUI-64 format.\n" "Displays values suitable for use as a 64 bit interface ID in A6 RRs.\n" "Also displayed are labels suitable for use with PTR RRs in the\n" "two defined reverse zones ip6.arpa (A6) and ip6.int (AAAA).\n\n" "Copyright (C) 2003 Trond Endrestøl \n\n" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License, or\n" "(at your option) any later version.\n\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.\n", argv0); exit(EXIT_SUCCESS); } /* Version */ void TransformMAC(const char * const argv0, const char * const argvi) { int ConstructMAC(const char *argvi, unsigned char *MAC); void ConstructEUI64(const unsigned char * const MAC, unsigned char * const EUI64); void InvertUniversalLocalBit(unsigned char * const EUI64); void PrintMAC(const unsigned char * const MAC); void PrintEUI64(const unsigned char * const EUI64); void PrintEUI64_InterfaceID(const unsigned char * const EUI64); void PrintEUI64_IP6_INT(const unsigned char * const EUI64); void PrintEUI64_IP6_ARPA(const unsigned char * const EUI64); unsigned char MAC[6], EUI64[8]; if (ConstructMAC(argvi, MAC)) { fprintf(stderr, "%s: invalid MAC address: %s\n", argv0, argvi); return; } ConstructEUI64(MAC, EUI64); PrintMAC(MAC); PrintEUI64(EUI64); /* Transform the EUI-64 address into the Modified EUI-64 address for use as the value for the interface ID */ InvertUniversalLocalBit(EUI64); PrintEUI64_InterfaceID(EUI64); PrintEUI64_IP6_INT(EUI64); PrintEUI64_IP6_ARPA(EUI64); } /* TransformMAC() */ int ConstructMAC(const char *argvi, unsigned char * MAC) { unsigned char ConstructHexByte(unsigned char MSNybble, unsigned char LSNybble); int ReturnValue = EXIT_SUCCESS, NumDigits = 0; size_t i = 0; unsigned char MSNybble, LSNybble; while (*argvi) { if (isxdigit(*argvi)) { NumDigits++; MSNybble = *argvi++; if (!isxdigit(*argvi)) { break; } NumDigits++; LSNybble = *argvi; MAC[i++] = ConstructHexByte(MSNybble, LSNybble); } argvi++; } if (NumDigits != 12) ReturnValue = EXIT_FAILURE; return ReturnValue; } /* ConstructMAC() */ unsigned char ConstructHexByte(unsigned char MSNybble, unsigned char LSNybble) { unsigned char Byte; MSNybble = toupper(MSNybble); LSNybble = toupper(LSNybble); if (MSNybble >= 'A') { MSNybble = 0x0A + MSNybble - 'A'; } else { MSNybble -= '0'; } if (LSNybble >= 'A') { LSNybble = 0x0A + LSNybble - 'A'; } else { LSNybble -= '0'; } Byte = (MSNybble << 4) | LSNybble; return Byte; } /* ConstructHexByte() */ void ConstructEUI64(const unsigned char * const MAC, unsigned char * const EUI64) { EUI64[0] = MAC[0]; EUI64[1] = MAC[1]; EUI64[2] = MAC[2]; EUI64[3] = 0xFF; EUI64[4] = 0xFE; EUI64[5] = MAC[3]; EUI64[6] = MAC[4]; EUI64[7] = MAC[5]; } /* ConstructEUI64() */ void InvertUniversalLocalBit(unsigned char * const EUI64) { if (EUI64[0] & 0x02) EUI64[0] &= ~0x02; else EUI64[0] |= 0x02; } /* InvertUniversalLocalBit() */ void PrintMAC(const unsigned char * const MAC) { printf("MAC:\t\t%02X:%02X:%02X:%02X:%02X:%02X\n", MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]); } /* PrintMAC() */ void PrintEUI64(const unsigned char * const EUI64) { printf("EUI-64:\t\t%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", EUI64[0], EUI64[1], EUI64[2], EUI64[3], EUI64[4], EUI64[5], EUI64[6], EUI64[7]); } /* PrintEUI64() */ void PrintEUI64_InterfaceID(const unsigned char * const EUI64) { printf("Interface ID:\t::%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", EUI64[0], EUI64[1], EUI64[2], EUI64[3], EUI64[4], EUI64[5], EUI64[6], EUI64[7]); } /* PrintEUI64_InterfaceID() */ void PrintEUI64_IP6_INT(const unsigned char * const EUI64) { printf("ip6.int/64:\t%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x\n", EUI64[7] & 0x0F, EUI64[7] >> 4, EUI64[6] & 0x0F, EUI64[6] >> 4, EUI64[5] & 0x0F, EUI64[5] >> 4, EUI64[4] & 0x0F, EUI64[4] >> 4, EUI64[3] & 0x0F, EUI64[3] >> 4, EUI64[2] & 0x0F, EUI64[2] >> 4, EUI64[1] & 0x0F, EUI64[1] >> 4, EUI64[0] & 0x0F, EUI64[0] >> 4); } /* PrintEUI64_IP6_INT() */ void PrintEUI64_IP6_ARPA(const unsigned char * const EUI64) { printf("ip6.arpa:\t\\[x%02X%02X%02X%02X%02X%02X%02X%02X/64]\n", EUI64[0], EUI64[1], EUI64[2], EUI64[3], EUI64[4], EUI64[5], EUI64[6], EUI64[7]); } /* PrintEUI64_IP6_ARPA() */ /* mac2eui64.c */