diff options
author | Ulrich Drepper <drepper@redhat.com> | 2007-03-15 20:05:19 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2007-03-15 20:05:19 +0000 |
commit | 6cb988fa7b81cd5f850c3f31fbae318a1df63521 (patch) | |
tree | 26930174d009a8c58f2ed1b5f3e9f9ff089e09c6 /inet/test-inet6_opt.c | |
parent | 02c906999c8500a43005e47f5810883b3a5189d8 (diff) | |
download | glibc-6cb988fa7b81cd5f850c3f31fbae318a1df63521.tar.gz |
[BZ #4181]
2007-03-15 Jakub Jelinek <jakub@redhat.com>
[BZ #4181]
* inet/inet6_opt.c (add_padding): Only insert padding if npad > 0.
(inet6_opt_append): Don't check extlen is big enough if extbuf
is NULL.
(inet6_opt_finish): Likewise.
* inet/Makefile (tests): Add test-inet6_opt.
* inet/test-inet6_opt.c: New test.
* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Never
reallocate the buffer, instead fail for MSG_TRUNC or for EBUSY
NLMSG_ERR. Instead use a page sized buffer.
* sysdeps/unix/sysv/linux/check_pf.c (make_request): Use page sized
buffer.
Diffstat (limited to 'inet/test-inet6_opt.c')
-rw-r--r-- | inet/test-inet6_opt.c | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/inet/test-inet6_opt.c b/inet/test-inet6_opt.c new file mode 100644 index 0000000000..4db9b59389 --- /dev/null +++ b/inet/test-inet6_opt.c @@ -0,0 +1,207 @@ +#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define OPT_X 42 +#define OPT_Y 43 +#define OPT_Z 44 + +static void * +encode_inet6_opt (socklen_t *elp) +{ + void *eb = NULL; + socklen_t el; + int cl; + void *db; + int offset; + uint8_t val1; + uint16_t val2; + uint32_t val4; + uint64_t val8; + + *elp = 0; +#define CHECK() \ + if (cl == -1) \ + { \ + printf ("cl == -1 on line %d\n", __LINE__); \ + free (eb); \ + return NULL; \ + } + + /* Estimate the length */ + cl = inet6_opt_init (NULL, 0); + CHECK (); + cl = inet6_opt_append (NULL, 0, cl, OPT_X, 12, 8, NULL); + CHECK (); + cl = inet6_opt_append (NULL, 0, cl, OPT_Y, 7, 4, NULL); + CHECK (); + cl = inet6_opt_append (NULL, 0, cl, OPT_Z, 7, 1, NULL); + CHECK (); + cl = inet6_opt_finish (NULL, 0, cl); + CHECK (); + el = cl; + + eb = malloc (el + 8); + if (eb == NULL) + { + puts ("malloc failed"); + return NULL; + } + /* Canary. */ + memcpy (eb + el, "deadbeef", 8); + + cl = inet6_opt_init (eb, el); + CHECK (); + + cl = inet6_opt_append (eb, el, cl, OPT_X, 12, 8, &db); + CHECK (); + val4 = 0x12345678; + offset = inet6_opt_set_val (db, 0, &val4, sizeof (val4)); + val8 = 0x0102030405060708LL; + inet6_opt_set_val (db, offset, &val8, sizeof (val8)); + + cl = inet6_opt_append (eb, el, cl, OPT_Y, 7, 4, &db); + CHECK (); + val1 = 0x01; + offset = inet6_opt_set_val (db, 0, &val1, sizeof (val1)); + val2 = 0x1331; + offset = inet6_opt_set_val (db, offset, &val2, sizeof (val2)); + val4 = 0x01020304; + inet6_opt_set_val (db, offset, &val4, sizeof (val4)); + + cl = inet6_opt_append (eb, el, cl, OPT_Z, 7, 1, &db); + CHECK (); + inet6_opt_set_val (db, 0, (void *) "abcdefg", 7); + + cl = inet6_opt_finish (eb, el, cl); + CHECK (); + + if (memcmp (eb + el, "deadbeef", 8) != 0) + { + puts ("Canary corrupted"); + free (eb); + return NULL; + } + *elp = el; + return eb; +} + +int +decode_inet6_opt (void *eb, socklen_t el) +{ + int ret = 0; + int seq = 0; + int cl = 0; + int offset; + uint8_t type; + socklen_t len; + uint8_t val1; + uint16_t val2; + uint32_t val4; + uint64_t val8; + void *db; + char buf[8]; + + while ((cl = inet6_opt_next (eb, el, cl, &type, &len, &db)) != -1) + switch (type) + { + case OPT_X: + if (seq++ != 0) + { + puts ("OPT_X is not first"); + ret = 1; + } + if (len != 12) + { + printf ("OPT_X's length %d != 12\n", len); + ret = 1; + } + offset = inet6_opt_get_val (db, 0, &val4, sizeof (val4)); + if (val4 != 0x12345678) + { + printf ("OPT_X's val4 %x != 0x12345678\n", val4); + ret = 1; + } + offset = inet6_opt_get_val (db, offset, &val8, sizeof (val8)); + if (offset != len || val8 != 0x0102030405060708LL) + { + printf ("OPT_X's val8 %llx != 0x0102030405060708\n", + (long long) val8); + ret = 1; + } + break; + case OPT_Y: + if (seq++ != 1) + { + puts ("OPT_Y is not second"); + ret = 1; + } + if (len != 7) + { + printf ("OPT_Y's length %d != 7\n", len); + ret = 1; + } + offset = inet6_opt_get_val (db, 0, &val1, sizeof (val1)); + if (val1 != 0x01) + { + printf ("OPT_Y's val1 %x != 0x01\n", val1); + ret = 1; + } + offset = inet6_opt_get_val (db, offset, &val2, sizeof (val2)); + if (val2 != 0x1331) + { + printf ("OPT_Y's val2 %x != 0x1331\n", val2); + ret = 1; + } + offset = inet6_opt_get_val (db, offset, &val4, sizeof (val4)); + if (offset != len || val4 != 0x01020304) + { + printf ("OPT_Y's val4 %x != 0x01020304\n", val4); + ret = 1; + } + break; + case OPT_Z: + if (seq++ != 2) + { + puts ("OPT_Z is not third"); + ret = 1; + } + if (len != 7) + { + printf ("OPT_Z's length %d != 7\n", len); + ret = 1; + } + offset = inet6_opt_get_val (db, 0, buf, 7); + if (offset != len || memcmp (buf, "abcdefg", 7) != 0) + { + buf[7] = '\0'; + printf ("OPT_Z's buf \"%s\" != \"abcdefg\"\n", buf); + ret = 1; + } + break; + default: + printf ("Unknown option %d\n", type); + ret = 1; + break; + } + if (seq != 3) + { + puts ("Didn't see all of OPT_X, OPT_Y and OPT_Z"); + ret = 1; + } + return ret; +} + +int +main (void) +{ + void *eb; + socklen_t el; + eb = encode_inet6_opt (&el); + if (eb == NULL) + return 1; + if (decode_inet6_opt (eb, el)) + return 1; + return 0; +} |