diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2016-07-28 17:23:47 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetwroks.com> | 2016-07-28 13:27:47 +0200 |
commit | d6f4a61dde127c6154f7933b0a4003740b6a0768 (patch) | |
tree | bc622e9e39732618d03d7133a051eb0d13fcb954 /lib | |
parent | lib: linklist: clean up insert-before/after dups (diff) | |
download | frr-d6f4a61dde127c6154f7933b0a4003740b6a0768.tar.xz frr-d6f4a61dde127c6154f7933b0a4003740b6a0768.zip |
lib: add 3-byte stream functions
This will be used for BGP MPLS labels.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/stream.c | 77 | ||||
-rw-r--r-- | lib/stream.h | 4 |
2 files changed, 81 insertions, 0 deletions
diff --git a/lib/stream.c b/lib/stream.c index 4c237563a..fe77e2a2a 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -373,6 +373,47 @@ stream_getw_from (struct stream *s, size_t from) return w; } +/* Get next 3-byte from the stream. */ +u_int32_t +stream_get3_from (struct stream *s, size_t from) +{ + u_int32_t l; + + STREAM_VERIFY_SANE(s); + + if (!GETP_VALID (s, from + 3)) + { + STREAM_BOUND_WARN (s, "get 3byte"); + return 0; + } + + l = s->data[from++] << 16; + l |= s->data[from++] << 8; + l |= s->data[from]; + + return l; +} + +u_int32_t +stream_get3 (struct stream *s) +{ + u_int32_t l; + + STREAM_VERIFY_SANE(s); + + if (STREAM_READABLE (s) < 3) + { + STREAM_BOUND_WARN (s, "get 3byte"); + return 0; + } + + l = s->data[s->getp++] << 16; + l |= s->data[s->getp++] << 8; + l |= s->data[s->getp++]; + + return l; +} + /* Get next long word from the stream. */ u_int32_t stream_getl_from (struct stream *s, size_t from) @@ -568,6 +609,25 @@ stream_putw (struct stream *s, u_int16_t w) /* Put long word to the stream. */ int +stream_put3 (struct stream *s, u_int32_t l) +{ + STREAM_VERIFY_SANE (s); + + if (STREAM_WRITEABLE (s) < 3) + { + STREAM_BOUND_WARN (s, "put"); + return 0; + } + + s->data[s->endp++] = (u_char)(l >> 16); + s->data[s->endp++] = (u_char)(l >> 8); + s->data[s->endp++] = (u_char)l; + + return 3; +} + +/* Put long word to the stream. */ +int stream_putl (struct stream *s, u_int32_t l) { STREAM_VERIFY_SANE (s); @@ -644,6 +704,23 @@ stream_putw_at (struct stream *s, size_t putp, u_int16_t w) } int +stream_put3_at (struct stream *s, size_t putp, u_int32_t l) +{ + STREAM_VERIFY_SANE(s); + + if (!PUT_AT_VALID (s, putp + 3)) + { + STREAM_BOUND_WARN (s, "put"); + return 0; + } + s->data[putp] = (u_char)(l >> 16); + s->data[putp + 1] = (u_char)(l >> 8); + s->data[putp + 2] = (u_char)l; + + return 3; +} + +int stream_putl_at (struct stream *s, size_t putp, u_int32_t l) { STREAM_VERIFY_SANE(s); diff --git a/lib/stream.h b/lib/stream.h index 738034438..4e9b21df5 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -167,6 +167,8 @@ extern int stream_putc (struct stream *, u_char); extern int stream_putc_at (struct stream *, size_t, u_char); extern int stream_putw (struct stream *, u_int16_t); extern int stream_putw_at (struct stream *, size_t, u_int16_t); +extern int stream_put3 (struct stream *, u_int32_t); +extern int stream_put3_at (struct stream *, size_t, u_int32_t); extern int stream_putl (struct stream *, u_int32_t); extern int stream_putl_at (struct stream *, size_t, u_int32_t); extern int stream_putq (struct stream *, uint64_t); @@ -186,6 +188,8 @@ extern u_char stream_getc (struct stream *); extern u_char stream_getc_from (struct stream *, size_t); extern u_int16_t stream_getw (struct stream *); extern u_int16_t stream_getw_from (struct stream *, size_t); +extern u_int32_t stream_get3 (struct stream *); +extern u_int32_t stream_get3_from (struct stream *, size_t); extern u_int32_t stream_getl (struct stream *); extern u_int32_t stream_getl_from (struct stream *, size_t); extern uint64_t stream_getq (struct stream *); |