summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2016-07-28 17:23:47 +0200
committerDonald Sharp <sharpd@cumulusnetwroks.com>2016-07-28 13:27:47 +0200
commitd6f4a61dde127c6154f7933b0a4003740b6a0768 (patch)
treebc622e9e39732618d03d7133a051eb0d13fcb954 /lib
parentlib: linklist: clean up insert-before/after dups (diff)
downloadfrr-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.c77
-rw-r--r--lib/stream.h4
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 *);