* Parse an IPv4 address. * * Last argument (ctx->args) is retrieved to determine storage size and * location. */
| 11115 | * location. |
| 11116 | */ |
| 11117 | static int |
| 11118 | parse_ipv4_addr(struct context *ctx, const struct token *token, |
| 11119 | const char *str, unsigned int len, |
| 11120 | void *buf, unsigned int size) |
| 11121 | { |
| 11122 | const struct arg *arg = pop_args(ctx); |
| 11123 | char str2[len + 1]; |
| 11124 | struct in_addr tmp; |
| 11125 | int ret; |
| 11126 | |
| 11127 | /* Argument is expected. */ |
| 11128 | if (!arg) |
| 11129 | return -1; |
| 11130 | size = arg->size; |
| 11131 | /* Bit-mask fill is not supported. */ |
| 11132 | if (arg->mask || size != sizeof(tmp)) |
| 11133 | goto error; |
| 11134 | /* Only network endian is supported. */ |
| 11135 | if (!arg->hton) |
| 11136 | goto error; |
| 11137 | memcpy(str2, str, len); |
| 11138 | str2[len] = '\0'; |
| 11139 | ret = inet_pton(AF_INET, str2, &tmp); |
| 11140 | if (ret != 1) { |
| 11141 | /* Attempt integer parsing. */ |
| 11142 | push_args(ctx, arg); |
| 11143 | return parse_int(ctx, token, str, len, buf, size); |
| 11144 | } |
| 11145 | if (!ctx->object) |
| 11146 | return len; |
| 11147 | buf = (uint8_t *)ctx->object + arg->offset; |
| 11148 | memcpy(buf, &tmp, size); |
| 11149 | if (ctx->objmask) |
| 11150 | memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); |
| 11151 | return len; |
| 11152 | error: |
| 11153 | push_args(ctx, arg); |
| 11154 | return -1; |
| 11155 | } |
| 11156 | |
| 11157 | /** |
| 11158 | * Parse an IPv6 address. |