diff options
Diffstat (limited to 'lib/stream.c')
| -rw-r--r-- | lib/stream.c | 72 |
1 files changed, 67 insertions, 5 deletions
diff --git a/lib/stream.c b/lib/stream.c index 17520f978e..768114e69b 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -55,15 +55,19 @@ DEFINE_MTYPE_STATIC(LIB, STREAM_FIFO, "Stream FIFO") * using stream_put..._at() functions. */ #define STREAM_WARN_OFFSETS(S) \ - flog_warn(EC_LIB_STREAM, \ - "&(struct stream): %p, size: %lu, getp: %lu, endp: %lu\n", \ - (void *)(S), (unsigned long)(S)->size, \ - (unsigned long)(S)->getp, (unsigned long)(S)->endp) + do { \ + flog_warn(EC_LIB_STREAM, \ + "&(struct stream): %p, size: %lu, getp: %lu, endp: %lu\n", \ + (void *)(S), (unsigned long)(S)->size, \ + (unsigned long)(S)->getp, (unsigned long)(S)->endp); \ + zlog_backtrace(LOG_WARNING); \ + } while (0) #define STREAM_VERIFY_SANE(S) \ do { \ - if (!(GETP_VALID(S, (S)->getp) && ENDP_VALID(S, (S)->endp))) \ + if (!(GETP_VALID(S, (S)->getp) && ENDP_VALID(S, (S)->endp))) { \ STREAM_WARN_OFFSETS(S); \ + } \ assert(GETP_VALID(S, (S)->getp)); \ assert(ENDP_VALID(S, (S)->endp)); \ } while (0) @@ -582,6 +586,43 @@ uint32_t stream_get_ipv4(struct stream *s) return l; } +bool stream_get_ipaddr(struct stream *s, struct ipaddr *ip) +{ + uint16_t ipa_len; + + STREAM_VERIFY_SANE(s); + + /* Get address type. */ + if (STREAM_READABLE(s) < sizeof(uint16_t)) { + STREAM_BOUND_WARN2(s, "get ipaddr"); + return false; + } + ip->ipa_type = stream_getw(s); + + /* Get address value. */ + switch (ip->ipa_type) { + case IPADDR_V4: + ipa_len = IPV4_MAX_BYTELEN; + break; + case IPADDR_V6: + ipa_len = IPV6_MAX_BYTELEN; + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown ip address-family: %u", __func__, + ip->ipa_type); + return false; + } + if (STREAM_READABLE(s) < ipa_len) { + STREAM_BOUND_WARN2(s, "get ipaddr"); + return false; + } + memcpy(&ip->ip, s->data + s->getp, ipa_len); + s->getp += ipa_len; + + return true; +} + float stream_getf(struct stream *s) { union { @@ -848,6 +889,27 @@ int stream_put_in_addr(struct stream *s, const struct in_addr *addr) return sizeof(uint32_t); } +bool stream_put_ipaddr(struct stream *s, struct ipaddr *ip) +{ + stream_putw(s, ip->ipa_type); + + switch (ip->ipa_type) { + case IPADDR_V4: + stream_put_in_addr(s, &ip->ipaddr_v4); + break; + case IPADDR_V6: + stream_write(s, (uint8_t *)&ip->ipaddr_v6, 16); + break; + default: + flog_err(EC_LIB_DEVELOPMENT, + "%s: unknown ip address-family: %u", __func__, + ip->ipa_type); + return false; + } + + return true; +} + /* Put in_addr at location in the stream. */ int stream_put_in_addr_at(struct stream *s, size_t putp, const struct in_addr *addr) |
