Convert a struct sockaddr from ASCII to binary. If its a protocol family that we specially handle, do that, otherwise defer to the generic parse type ng_ksocket_generic_sockaddr_type. */
| 198 | family that we specially handle, do that, otherwise defer to the |
| 199 | generic parse type ng_ksocket_generic_sockaddr_type. */ |
| 200 | static int |
| 201 | ng_ksocket_sockaddr_parse(const struct ng_parse_type *type, |
| 202 | const char *s, int *off, const u_char *const start, |
| 203 | u_char *const buf, int *buflen) |
| 204 | { |
| 205 | struct sockaddr *const sa = (struct sockaddr *)buf; |
| 206 | enum ng_parse_token tok; |
| 207 | char fambuf[32]; |
| 208 | int family, len; |
| 209 | char *t; |
| 210 | |
| 211 | /* If next token is a left curly brace, use generic parse type */ |
| 212 | if ((tok = ng_parse_get_token(s, off, &len)) == T_LBRACE) { |
| 213 | return (*ng_ksocket_generic_sockaddr_type.supertype->parse) |
| 214 | (&ng_ksocket_generic_sockaddr_type, |
| 215 | s, off, start, buf, buflen); |
| 216 | } |
| 217 | |
| 218 | /* Get socket address family followed by a slash */ |
| 219 | while (isspace(s[*off])) |
| 220 | (*off)++; |
| 221 | if ((t = strchr(s + *off, '/')) == NULL) |
| 222 | return (EINVAL); |
| 223 | if ((len = t - (s + *off)) > sizeof(fambuf) - 1) |
| 224 | return (EINVAL); |
| 225 | strncpy(fambuf, s + *off, len); |
| 226 | fambuf[len] = '\0'; |
| 227 | *off += len + 1; |
| 228 | if ((family = ng_ksocket_parse(ng_ksocket_families, fambuf, 0)) == -1) |
| 229 | return (EINVAL); |
| 230 | |
| 231 | /* Set family */ |
| 232 | if (*buflen < SADATA_OFFSET) |
| 233 | return (ERANGE); |
| 234 | sa->sa_family = family; |
| 235 | |
| 236 | /* Set family-specific data and length */ |
| 237 | switch (sa->sa_family) { |
| 238 | case PF_LOCAL: /* Get pathname */ |
| 239 | { |
| 240 | const int pathoff = OFFSETOF(struct sockaddr_un, sun_path); |
| 241 | struct sockaddr_un *const sun = (struct sockaddr_un *)sa; |
| 242 | int toklen, pathlen; |
| 243 | char *path; |
| 244 | |
| 245 | if ((path = ng_get_string_token(s, off, &toklen, NULL)) == NULL) |
| 246 | return (EINVAL); |
| 247 | pathlen = strlen(path); |
| 248 | if (pathlen > SOCK_MAXADDRLEN) { |
| 249 | free(path, M_NETGRAPH_KSOCKET); |
| 250 | return (E2BIG); |
| 251 | } |
| 252 | if (*buflen < pathoff + pathlen) { |
| 253 | free(path, M_NETGRAPH_KSOCKET); |
| 254 | return (ERANGE); |
| 255 | } |
| 256 | *off += toklen; |
| 257 | bcopy(path, sun->sun_path, pathlen); |
nothing calls this directly
no test coverage detected