* Parse a prefix length and generate a bit-mask. * * Last argument (ctx->args) is retrieved to determine mask size, storage * location and whether the result must use network byte ordering. */
| 7671 | * location and whether the result must use network byte ordering. |
| 7672 | */ |
| 7673 | static int |
| 7674 | parse_prefix(struct context *ctx, const struct token *token, |
| 7675 | const char *str, unsigned int len, |
| 7676 | void *buf, unsigned int size) |
| 7677 | { |
| 7678 | const struct arg *arg = pop_args(ctx); |
| 7679 | static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; |
| 7680 | char *end; |
| 7681 | uintmax_t u; |
| 7682 | unsigned int bytes; |
| 7683 | unsigned int extra; |
| 7684 | |
| 7685 | (void)token; |
| 7686 | /* Argument is expected. */ |
| 7687 | if (!arg) |
| 7688 | return -1; |
| 7689 | errno = 0; |
| 7690 | u = strtoumax(str, &end, 0); |
| 7691 | if (errno || (size_t)(end - str) != len) |
| 7692 | goto error; |
| 7693 | if (arg->mask) { |
| 7694 | uintmax_t v = 0; |
| 7695 | |
| 7696 | extra = arg_entry_bf_fill(NULL, 0, arg); |
| 7697 | if (u > extra) |
| 7698 | goto error; |
| 7699 | if (!ctx->object) |
| 7700 | return len; |
| 7701 | extra -= u; |
| 7702 | while (u--) |
| 7703 | (v <<= 1, v |= 1); |
| 7704 | v <<= extra; |
| 7705 | if (!arg_entry_bf_fill(ctx->object, v, arg) || |
| 7706 | !arg_entry_bf_fill(ctx->objmask, -1, arg)) |
| 7707 | goto error; |
| 7708 | return len; |
| 7709 | } |
| 7710 | bytes = u / 8; |
| 7711 | extra = u % 8; |
| 7712 | size = arg->size; |
| 7713 | if (bytes > size || bytes + !!extra > size) |
| 7714 | goto error; |
| 7715 | if (!ctx->object) |
| 7716 | return len; |
| 7717 | buf = (uint8_t *)ctx->object + arg->offset; |
| 7718 | #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN |
| 7719 | if (!arg->hton) { |
| 7720 | memset((uint8_t *)buf + size - bytes, 0xff, bytes); |
| 7721 | memset(buf, 0x00, size - bytes); |
| 7722 | if (extra) |
| 7723 | ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; |
| 7724 | } else |
| 7725 | #endif |
| 7726 | { |
| 7727 | memset(buf, 0xff, bytes); |
| 7728 | memset((uint8_t *)buf + bytes, 0x00, size - bytes); |
| 7729 | if (extra) |
| 7730 | ((uint8_t *)buf)[bytes] = conv[extra]; |
nothing calls this directly
no test coverage detected