I’ve posted this before, buyt now that I have better source code formatting, I’ll repost. This converts a mac address to a link only IPv6 address.
mac2ipv6addr.c
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdarg.h> int main(int argc, char** argv){ int addrlen = strlen("0000:0000:0000:0000:0000:0000:0000:"); char* out = malloc(addrlen); char * outorig = out; memset(out, 0, addrlen); char* addr = "00:0c:29:20:4e:e3"; if (argc > 1){ addr = argv[1]; }else{ fprintf(stderr,"usage %s macaddr\n",argv[0]); exit(-1); } int len = strlen(addr); if (len > 18){ printf ("String too long\n"); exit(-1); } /*We know we have the right length. Main processing follows */ int i ; int col_count = 0; unsigned char current = 0; for (i = 0; i < len; ++i){ char c = addr[i]; if (0 == c){ break; }else if (':' == c){ switch( col_count ){ case 0:{ sprintf(out,"fe80::"); out += strlen(out); /*Toggle the '2' bit*/ unsigned short c2 = ( current | 0x02 ); if (c2 == current){ c2 = current & 0xcf; } sprintf(out,"%02x",c2); out += strlen(out); } break; case 2:{ /*The magic number goes halfway through the mac address*/ sprintf(out,"%02xff:fe",current); out += strlen(out); } break; default: sprintf(out,"%02x",current); out += strlen(out); if (col_count % 2){ sprintf(out,":"); out += strlen(out); } } ++col_count; current = 0; }else if ((c >= 'a') && (c <= 'f')){ current *=16; current += ( 10 + c - 'a'); }else if ((c >= 'A') && (c <= 'F')){ current *=16; current += ( 10 + c - 'a'); }else if ((c >= '0') && (c <= '9')){ current *=16; current += ( c - '0'); } } sprintf(out,"%x",current); out += strlen(out); printf(outorig); return 0; } |
Ignore that last line. Not sure why the formatting code is closing my open tags insde a pre tag…