/[mac2eui64]/trunk/mac2eui64.c
ViewVC logotype

Diff of /trunk/mac2eui64.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 3 by trond, 2015-09-29T08:26:40Z Revision 6 by trond, 2015-10-12T07:53:50Z
# Line 1  Line 1 
1  /*  /*
2   mac2eui64.c   mac2eui64.c
3    
4   Conversion from the IEEE 802 MAC format to the IEEE EUI-64 format.   Conversion from the IEEE 802 MAC format to the (modified) IEEE EUI-64 format.
5   Displays values suitable for use as a 64 bit interface ID in A6 RRs.   Displays values suitable for use as a 64 bit interface ID in AAAA and A6 RRs.
6   Also displayed are labels suitable for use with PTR RRs in the   Also displays labels suitable for use with PTR RRs in the reverse zone
7   two defined reverse zones ip6.arpa (A6) and ip6.int (AAAA).   ip6.arpa.
8    
9   Copyright (C) 2003 Trond Endrestøl <trond@ramstind.gtf.ol.no>   Updated in 2015 to conform to ISO C 2011.
10    
11     Copyright (C) 2003 Trond Endrestøl <Trond.Endrestol@ximalas.info>
12    
13   This program is free software; you can redistribute it and/or modify   This program is free software; you can redistribute it and/or modify
14   it under the terms of the GNU General Public License as published by   it under the terms of the GNU General Public License as published by
15   the Free Software Foundation; either version 2 of the License, or   the Free Software Foundation; either version 2 of the License, or
16   (at your option) any later version.   (at your option) any later version.
17    
18   This program is distributed in the hope that it will be useful,   This program is distributed in the hope that it will be useful,
19   but WITHOUT ANY WARRANTY; without even the implied warranty of   but WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21   GNU General Public License for more details.   GNU General Public License for more details.
22    
23   You should have received a copy of the GNU General Public License   You should have received a copy of the GNU General Public License
24   along with this program; if not, write to the Free Software   along with this program; if not, write to the Free Software
25   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
26    
27   $Ximalas$   $Ximalas$
28  */  */
29  #include <ctype.h>  #include <ctype.h>
30  #include <stdio.h>  #include <stdio.h>
31  #include <stdlib.h>  #include <stdlib.h>
32  #include <unistd.h>  #include <unistd.h>
33    
34    void Usage(const char * const argv0, int ReturnValue) __attribute__((noreturn));
35    void Version(const char * const argv0) __attribute__((noreturn));
36    void TransformMAC(const char * const argv0, const char * const argvi);
37    
38  int main(int argc, char **argv)  int main(int argc, char **argv)
39  {  {
   void Usage(const char * const argv0, int ReturnValue);  
   void Version(const char * const argv0);  
   void TransformMAC(const char * const argv0, const char * const argvi);  
   
40    int c;    int c;
41    size_t i;    ssize_t i;
42    
43    opterr = 0;    opterr = 0;
44    while ((c = getopt(argc, argv, "hv")) != -1) {    while ((c = getopt(argc, argv, "hv")) != -1) {
45      switch (c) {      switch (c) {
46        case 'h':        case 'h':
47          Usage(argv[0], EXIT_SUCCESS);          Usage(argv[0], EXIT_SUCCESS);
48          break;          //break;
49    
50        case 'v':        case 'v':
51          Version(argv[0]);          Version(argv[0]);
52          break;          //break;
53    
54        case '?':        case '?':
55          fprintf(stderr, "%s: invalid option -%c\n", argv[0], optopt);          fprintf(stderr, "%s: invalid option -%c\n", argv[0], optopt);
56          break;          break;
57    
58        default:        default:
59          fprintf(stderr, "%s: something is dead wrong with getopt() or with this program\n", argv[0]);          fprintf(stderr, "%s: something is dead wrong with getopt() or with this program\n", argv[0]);
60          return EXIT_FAILURE;          return EXIT_FAILURE;
61          break;          //break;
62        }        }
63      }      }
64    
65    i = optind;    i = optind;
66    
67    if (i == argc)    if (i == argc)
68      Usage(argv[0], EXIT_FAILURE);      Usage(argv[0], EXIT_FAILURE);
69    
70    TransformMAC(argv[0], argv[i++]);    TransformMAC(argv[0], argv[i++]);
71    
72    while (i < argc) {    while (i < argc) {
73      puts("");      puts("");
74      TransformMAC(argv[0], argv[i++]);      TransformMAC(argv[0], argv[i++]);
75      }      }
76    
# Line 87  void Version(const char * const argv0) Line 89  void Version(const char * const argv0)
89            "MAC addresses must consist of 12 hex digits with leading zeroes.\n"            "MAC addresses must consist of 12 hex digits with leading zeroes.\n"
90            "Any punctuation is ignored. Examples of valid MAC addresses:\n\n"            "Any punctuation is ignored. Examples of valid MAC addresses:\n\n"
91    
92            "  00:50:DA:2C:8F:55\n"            "  00:50:DA:2C:8F:55\n"
93            "  00-50-DA-2C-8F-55\n"            "  00-50-DA-2C-8F-55\n"
94            "  0050.DA2C.8F55\n"            "  0050.DA2C.8F55\n"
95            "  0050DA2C8F55\n",            "  0050DA2C8F55\n",
96            argv0);            argv0);
97    exit(ReturnValue);    exit(ReturnValue);
98  } /* Usage() */  } /* Usage() */
99    
100  void Version(const char * const argv0)  void Version(const char * const argv0)
101  {  {
102    printf("%s version 1.0\n\n"    printf("%s version 1.0\n\n"
103    
104           "Conversion from the IEEE 802 MAC format to the IEEE EUI-64 format.\n"           "Conversion from the IEEE 802 MAC format to the (modified) IEEE EUI-64 format.\n"
105           "Displays values suitable for use as a 64 bit interface ID in A6 RRs.\n"           "Displays values suitable for use as a 64 bit interface ID in AAAA and A6 RRs.\n"
106           "Also displayed are labels suitable for use with PTR RRs in the\n"           "Also displays labels suitable for use with PTR RRs in the reverse zone\n"
107           "two defined reverse zones ip6.arpa (A6) and ip6.int (AAAA).\n\n"           "ip6.arpa.\n\n"
108    
109           "Copyright (C) 2003 Trond Endrestøl <trond@ramstind.gtf.ol.no>\n\n"           "Updated in 2015 to conform to ISO C 2011.\n\n"
110    
111             "Copyright (C) 2003 Trond Endrestøl <Trond.Endrestol@ximalas.info>\n\n"
112    
113           "This program is free software; you can redistribute it and/or modify\n"           "This program is free software; you can redistribute it and/or modify\n"
114           "it under the terms of the GNU General Public License as published by\n"           "it under the terms of the GNU General Public License as published by\n"
115           "the Free Software Foundation; either version 2 of the License, or\n"           "the Free Software Foundation; either version 2 of the License, or\n"
116           "(at your option) any later version.\n\n"           "(at your option) any later version.\n\n"
117    
118           "This program is distributed in the hope that it will be useful,\n"           "This program is distributed in the hope that it will be useful,\n"
119           "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"           "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
120           "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"           "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
121           "GNU General Public License for more details.\n\n"           "GNU General Public License for more details.\n\n"
122    
123           "You should have received a copy of the GNU General Public License\n"           "You should have received a copy of the GNU General Public License\n"
124           "along with this program; if not, write to the Free Software\n"           "along with this program; if not, write to the Free Software\n"
125           "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.\n",           "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.\n",
126           argv0);           argv0);
127    
128    exit(EXIT_SUCCESS);    exit(EXIT_SUCCESS);
129  } /* Version */  } /* Version */
130    
131    int ConstructMAC(const char *argvi, unsigned char *MAC);
132    void ConstructEUI64(const unsigned char * const MAC, unsigned char * const EUI64);
133    void ConstructModEUI64(const unsigned char * const EUI64, unsigned char * const ModEUI64);
134    
135    void PrintMAC(const unsigned char * const MAC);
136    void PrintEUI64(const unsigned char * const EUI64);
137    void PrintModEUI64(const unsigned char * const EUI64);
138    void PrintEUI64_InterfaceID(const unsigned char * const EUI64);
139    void PrintEUI64_IP6_ARPA(const unsigned char * const EUI64);
140    //void PrintEUI64_IP6_INT(const unsigned char * const EUI64);
141    
142  void TransformMAC(const char * const argv0, const char * const argvi)  void TransformMAC(const char * const argv0, const char * const argvi)
143  {  {
144    int ConstructMAC(const char *argvi, unsigned char *MAC);    unsigned char MAC[6], EUI64[8], ModEUI64[8];
   void ConstructEUI64(const unsigned char * const MAC, unsigned char * const EUI64);  
   void InvertUniversalLocalBit(unsigned char * const EUI64);  
145    
   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];  
   
146    if (ConstructMAC(argvi, MAC)) {    if (ConstructMAC(argvi, MAC)) {
147      fprintf(stderr, "%s: invalid MAC address: %s\n", argv0, argvi);      fprintf(stderr, "%s: invalid MAC address: %s\n", argv0, argvi);
148      return;      return;
149      }      }
150    
151    ConstructEUI64(MAC, EUI64);    ConstructEUI64(MAC, EUI64);
152      ConstructModEUI64(EUI64, ModEUI64);
153    
154    PrintMAC(MAC);    PrintMAC(MAC);
155    PrintEUI64(EUI64);    PrintEUI64(EUI64);
156      PrintModEUI64(ModEUI64);
157    /* Transform the EUI-64 address into    PrintEUI64_InterfaceID(ModEUI64);
158       the Modified EUI-64 address for use as    PrintEUI64_IP6_ARPA(ModEUI64);
159       the value for the interface ID */    //PrintEUI64_IP6_INT(ModEUI64);
   InvertUniversalLocalBit(EUI64);  
   
   PrintEUI64_InterfaceID(EUI64);  
   PrintEUI64_IP6_INT(EUI64);  
   PrintEUI64_IP6_ARPA(EUI64);  
160  } /* TransformMAC() */  } /* TransformMAC() */
161    
162    unsigned char ConstructHexByte(unsigned char MSNybble, unsigned char LSNybble);
163    
164  int ConstructMAC(const char *argvi, unsigned char * MAC)  int ConstructMAC(const char *argvi, unsigned char * MAC)
165  {  {
   unsigned char ConstructHexByte(unsigned char MSNybble, unsigned char LSNybble);  
   
166    int ReturnValue = EXIT_SUCCESS, NumDigits = 0;    int ReturnValue = EXIT_SUCCESS, NumDigits = 0;
167    size_t i = 0;    size_t i = 0;
168    unsigned char MSNybble, LSNybble;    unsigned char MSNybble, LSNybble;
169    
170    while (*argvi) {    while (*argvi) {
171      if (isxdigit(*argvi)) {      if (isxdigit(*argvi)) {
172        NumDigits++;        NumDigits++;
173        MSNybble = *argvi++;        MSNybble = (unsigned char)*argvi++;
174    
175        if (!isxdigit(*argvi)) {        if (!isxdigit(*argvi)) {
176          break;          break;
177          }          }
178    
179        NumDigits++;        NumDigits++;
180        LSNybble = *argvi;        LSNybble = (unsigned char)*argvi;
181    
182        MAC[i++] = ConstructHexByte(MSNybble, LSNybble);        MAC[i++] = ConstructHexByte(MSNybble, LSNybble);
183        }        }
184    
185      argvi++;      argvi++;
186      }      }
187    
188    if (NumDigits != 12)    if (NumDigits != 12)
189      ReturnValue = EXIT_FAILURE;      ReturnValue = EXIT_FAILURE;
190    
191    return ReturnValue;    return ReturnValue;
192  } /* ConstructMAC() */  } /* ConstructMAC() */
193    
194  unsigned char ConstructHexByte(unsigned char MSNybble, unsigned char LSNybble)  unsigned char ConstructHexByte(unsigned char MSNybble, unsigned char LSNybble)
195  {  {
196    unsigned char Byte;    unsigned char Byte;
197    
198    MSNybble = toupper(MSNybble);    MSNybble = (unsigned char)toupper(MSNybble);
199    LSNybble = toupper(LSNybble);    LSNybble = (unsigned char)toupper(LSNybble);
200    
201    if (MSNybble >= 'A') {    if (MSNybble >= 'A') {
202      MSNybble = 0x0A + MSNybble - 'A';      MSNybble = 0x0A + MSNybble - 'A';
203      }      }
204    else {    else {
205      MSNybble -= '0';      MSNybble -= '0';
206      }      }
207    
208    if (LSNybble >= 'A') {    if (LSNybble >= 'A') {
209      LSNybble = 0x0A + LSNybble - 'A';      LSNybble = 0x0A + LSNybble - 'A';
210      }      }
211    else {    else {
212      LSNybble -= '0';      LSNybble -= '0';
213      }      }
214    
215    Byte = (MSNybble << 4) | LSNybble;    Byte = (unsigned char)((MSNybble << 4) | LSNybble);
216    
217    return Byte;    return Byte;
218  } /* ConstructHexByte() */  } /* ConstructHexByte() */
219    
220  void ConstructEUI64(const unsigned char * const MAC, unsigned char * const EUI64)  void ConstructEUI64(const unsigned char * const MAC, unsigned char * const EUI64)
221  {  {
222    EUI64[0] = MAC[0];    EUI64[0] = MAC[0];
223    EUI64[1] = MAC[1];    EUI64[1] = MAC[1];
224    EUI64[2] = MAC[2];    EUI64[2] = MAC[2];
225    EUI64[3] = 0xFF;    EUI64[3] = 0xFF;
226    EUI64[4] = 0xFE;    EUI64[4] = 0xFF;
227    EUI64[5] = MAC[3];    EUI64[5] = MAC[3];
228    EUI64[6] = MAC[4];    EUI64[6] = MAC[4];
229    EUI64[7] = MAC[5];    EUI64[7] = MAC[5];
230  } /* ConstructEUI64() */  } /* ConstructEUI64() */
231    
232    void InvertUniversalLocalBit(unsigned char * const EUI64);
233    
234    void ConstructModEUI64(const unsigned char * const EUI64, unsigned char * const ModEUI64)
235    {
236      ModEUI64[0] = EUI64[0];
237      ModEUI64[1] = EUI64[1];
238      ModEUI64[2] = EUI64[2];
239      ModEUI64[3] = EUI64[3];
240      ModEUI64[4] = 0xFE;
241      ModEUI64[5] = EUI64[5];
242      ModEUI64[6] = EUI64[6];
243      ModEUI64[7] = EUI64[7];
244    
245      InvertUniversalLocalBit(ModEUI64);
246    } /* ConstructModEUI64() */
247    
248  void InvertUniversalLocalBit(unsigned char * const EUI64)  void InvertUniversalLocalBit(unsigned char * const EUI64)
249  {  {
250    if (EUI64[0] & 0x02)    if (EUI64[0] & 0x02)
251      EUI64[0] &= ~0x02;      EUI64[0] &= ~0x02;
252    else    else
253      EUI64[0] |= 0x02;      EUI64[0] |= 0x02;
254  } /* InvertUniversalLocalBit() */  } /* InvertUniversalLocalBit() */
255    
256  void PrintMAC(const unsigned char * const MAC)  void PrintMAC(const unsigned char * const MAC)
257  {  {
258    printf("MAC:\t\t%02X:%02X:%02X:%02X:%02X:%02X\n",    printf("MAC:\t\t%02X:%02X:%02X:%02X:%02X:%02X\n",
259           MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]);           MAC[0], MAC[1], MAC[2], MAC[3], MAC[4], MAC[5]);
260  } /* PrintMAC() */  } /* PrintMAC() */
261    
262  void PrintEUI64(const unsigned char * const EUI64)  void PrintEUI64(const unsigned char * const EUI64)
263  {  {
264    printf("EUI-64:\t\t%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",    printf("EUI-64:\t\t%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
265           EUI64[0], EUI64[1], EUI64[2], EUI64[3],           EUI64[0], EUI64[1], EUI64[2], EUI64[3],
266           EUI64[4], EUI64[5], EUI64[6], EUI64[7]);           EUI64[4], EUI64[5], EUI64[6], EUI64[7]);
267  } /* PrintEUI64() */  } /* PrintEUI64() */
268    
269    void PrintModEUI64(const unsigned char * const EUI64)
270    {
271      printf("Mod. EUI-64:\t%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
272             EUI64[0], EUI64[1], EUI64[2], EUI64[3],
273             EUI64[4], EUI64[5], EUI64[6], EUI64[7]);
274    } /* PrintModEUI64() */
275    
276  void PrintEUI64_InterfaceID(const unsigned char * const EUI64)  void PrintEUI64_InterfaceID(const unsigned char * const EUI64)
277  {  {
278    printf("Interface ID:\t::%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",    printf("Interface ID:\t::%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
279           EUI64[0], EUI64[1], EUI64[2], EUI64[3],           EUI64[0], EUI64[1], EUI64[2], EUI64[3],
280           EUI64[4], EUI64[5], EUI64[6], EUI64[7]);           EUI64[4], EUI64[5], EUI64[6], EUI64[7]);
281  } /* PrintEUI64_InterfaceID() */  } /* PrintEUI64_InterfaceID() */
282    
283  void PrintEUI64_IP6_INT(const unsigned char * const EUI64)  void PrintEUI64_IP6_ARPA(const unsigned char * const EUI64)
284  {  {
285    printf("ip6.int/64:\t%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x\n",  //  printf("ip6.arpa:\t\\[x%02X%02X%02X%02X%02X%02X%02X%02X/64]\n",
286    //         EUI64[0], EUI64[1], EUI64[2], EUI64[3],
287    //         EUI64[4], EUI64[5], EUI64[6], EUI64[7]);
288    
289      printf("ip6.arpa/64:\t%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x\n",
290           EUI64[7] & 0x0F, EUI64[7] >> 4,           EUI64[7] & 0x0F, EUI64[7] >> 4,
291           EUI64[6] & 0x0F, EUI64[6] >> 4,           EUI64[6] & 0x0F, EUI64[6] >> 4,
292           EUI64[5] & 0x0F, EUI64[5] >> 4,           EUI64[5] & 0x0F, EUI64[5] >> 4,
293           EUI64[4] & 0x0F, EUI64[4] >> 4,           EUI64[4] & 0x0F, EUI64[4] >> 4,
294           EUI64[3] & 0x0F, EUI64[3] >> 4,           EUI64[3] & 0x0F, EUI64[3] >> 4,
295           EUI64[2] & 0x0F, EUI64[2] >> 4,           EUI64[2] & 0x0F, EUI64[2] >> 4,
296           EUI64[1] & 0x0F, EUI64[1] >> 4,           EUI64[1] & 0x0F, EUI64[1] >> 4,
297           EUI64[0] & 0x0F, EUI64[0] >> 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]);  
298  } /* PrintEUI64_IP6_ARPA() */  } /* PrintEUI64_IP6_ARPA() */
299    
300    //void PrintEUI64_IP6_INT(const unsigned char * const EUI64)
301    //{
302    //  printf("ip6.int/64:\t%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x\n",
303    //         EUI64[7] & 0x0F, EUI64[7] >> 4,
304    //         EUI64[6] & 0x0F, EUI64[6] >> 4,
305    //         EUI64[5] & 0x0F, EUI64[5] >> 4,
306    //         EUI64[4] & 0x0F, EUI64[4] >> 4,
307    //         EUI64[3] & 0x0F, EUI64[3] >> 4,
308    //         EUI64[2] & 0x0F, EUI64[2] >> 4,
309    //         EUI64[1] & 0x0F, EUI64[1] >> 4,
310    //         EUI64[0] & 0x0F, EUI64[0] >> 4);
311    //} /* PrintEUI64_IP6_INT() */
312    
313  /* mac2eui64.c */  /* mac2eui64.c */


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

svn@ximalas.info
ViewVC Help
Powered by ViewVC 1.3.0-dev