| 139 | } |
| 140 | |
| 141 | static void |
| 142 | link_getaddr(const char *addr, int which) |
| 143 | { |
| 144 | char *temp; |
| 145 | struct sockaddr_dl sdl; |
| 146 | struct sockaddr *sa = &link_ridreq.ifr_addr; |
| 147 | |
| 148 | if (which != ADDR) |
| 149 | errx(1, "can't set link-level netmask or broadcast"); |
| 150 | if (!strcmp(addr, "random")) { |
| 151 | sdl.sdl_len = sizeof(sdl); |
| 152 | sdl.sdl_alen = ETHER_ADDR_LEN; |
| 153 | sdl.sdl_nlen = 0; |
| 154 | sdl.sdl_family = AF_LINK; |
| 155 | #ifndef FSTACK |
| 156 | arc4random_buf(&sdl.sdl_data, ETHER_ADDR_LEN); |
| 157 | #else |
| 158 | RAND_bytes((void *)&sdl.sdl_data, ETHER_ADDR_LEN); |
| 159 | #endif |
| 160 | /* Non-multicast and claim it is locally administered. */ |
| 161 | sdl.sdl_data[0] &= 0xfc; |
| 162 | sdl.sdl_data[0] |= 0x02; |
| 163 | } else { |
| 164 | if ((temp = malloc(strlen(addr) + 2)) == NULL) |
| 165 | errx(1, "malloc failed"); |
| 166 | temp[0] = ':'; |
| 167 | strcpy(temp + 1, addr); |
| 168 | sdl.sdl_len = sizeof(sdl); |
| 169 | link_addr(temp, &sdl); |
| 170 | free(temp); |
| 171 | } |
| 172 | if (sdl.sdl_alen > sizeof(sa->sa_data)) |
| 173 | errx(1, "malformed link-level address"); |
| 174 | sa->sa_family = AF_LINK; |
| 175 | sa->sa_len = sdl.sdl_alen; |
| 176 | bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen); |
| 177 | } |
| 178 | |
| 179 | static struct afswtch af_link = { |
| 180 | .af_name = "link", |
nothing calls this directly
no test coverage detected