| 52 | #define LETTER (4*3) |
| 53 | |
| 54 | void |
| 55 | link_addr(const char *addr, struct sockaddr_dl *sdl) |
| 56 | { |
| 57 | char *cp = sdl->sdl_data; |
| 58 | char *cplim = sdl->sdl_len + (char *)sdl; |
| 59 | int byte = 0, state = NAMING, new; |
| 60 | |
| 61 | bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1); |
| 62 | sdl->sdl_family = AF_LINK; |
| 63 | do { |
| 64 | state &= ~LETTER; |
| 65 | if ((*addr >= '0') && (*addr <= '9')) { |
| 66 | new = *addr - '0'; |
| 67 | } else if ((*addr >= 'a') && (*addr <= 'f')) { |
| 68 | new = *addr - 'a' + 10; |
| 69 | } else if ((*addr >= 'A') && (*addr <= 'F')) { |
| 70 | new = *addr - 'A' + 10; |
| 71 | } else if (*addr == 0) { |
| 72 | state |= END; |
| 73 | } else if (state == NAMING && |
| 74 | (((*addr >= 'A') && (*addr <= 'Z')) || |
| 75 | ((*addr >= 'a') && (*addr <= 'z')))) |
| 76 | state |= LETTER; |
| 77 | else |
| 78 | state |= DELIM; |
| 79 | addr++; |
| 80 | switch (state /* | INPUT */) { |
| 81 | case NAMING | DIGIT: |
| 82 | case NAMING | LETTER: |
| 83 | *cp++ = addr[-1]; |
| 84 | continue; |
| 85 | case NAMING | DELIM: |
| 86 | state = RESET; |
| 87 | sdl->sdl_nlen = cp - sdl->sdl_data; |
| 88 | continue; |
| 89 | case GOTTWO | DIGIT: |
| 90 | *cp++ = byte; |
| 91 | /* FALLTHROUGH */ |
| 92 | case RESET | DIGIT: |
| 93 | state = GOTONE; |
| 94 | byte = new; |
| 95 | continue; |
| 96 | case GOTONE | DIGIT: |
| 97 | state = GOTTWO; |
| 98 | byte = new + (byte << 4); |
| 99 | continue; |
| 100 | default: /* | DELIM */ |
| 101 | state = RESET; |
| 102 | *cp++ = byte; |
| 103 | byte = 0; |
| 104 | continue; |
| 105 | case GOTONE | END: |
| 106 | case GOTTWO | END: |
| 107 | *cp++ = byte; |
| 108 | /* FALLTHROUGH */ |
| 109 | case RESET | END: |
| 110 | break; |
| 111 | } |
no test coverage detected