Back to index

glibc  2.9
test-inet6_opt.c
Go to the documentation of this file.
00001 #include <netinet/in.h>
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 
00006 #define OPT_X 42
00007 #define OPT_Y 43
00008 #define OPT_Z 44
00009 
00010 static void *
00011 encode_inet6_opt (socklen_t *elp)
00012 {
00013   void *eb = NULL;
00014   socklen_t el;
00015   int cl;
00016   void *db;
00017   int offset;
00018   uint8_t val1;
00019   uint16_t val2;
00020   uint32_t val4;
00021   uint64_t val8;
00022 
00023   *elp = 0;
00024 #define CHECK() \
00025   if (cl == -1)                                         \
00026     {                                            \
00027       printf ("cl == -1 on line %d\n", __LINE__);       \
00028       free (eb);                                 \
00029       return NULL;                               \
00030     }
00031 
00032   /* Estimate the length */
00033   cl = inet6_opt_init (NULL, 0);
00034   CHECK ();
00035   cl = inet6_opt_append (NULL, 0, cl, OPT_X, 12, 8, NULL);
00036   CHECK ();
00037   cl = inet6_opt_append (NULL, 0, cl, OPT_Y, 7, 4, NULL);
00038   CHECK ();
00039   cl = inet6_opt_append (NULL, 0, cl, OPT_Z, 7, 1, NULL);
00040   CHECK ();
00041   cl = inet6_opt_finish (NULL, 0, cl);
00042   CHECK ();
00043   el = cl;
00044 
00045   eb = malloc (el + 8);
00046   if (eb == NULL)
00047     {
00048       puts ("malloc failed");
00049       return NULL;
00050     }
00051   /* Canary.  */
00052   memcpy (eb + el, "deadbeef", 8);
00053 
00054   cl = inet6_opt_init (eb, el);
00055   CHECK ();
00056 
00057   cl = inet6_opt_append (eb, el, cl, OPT_X, 12, 8, &db);
00058   CHECK ();
00059   val4 = 0x12345678;
00060   offset = inet6_opt_set_val (db, 0, &val4, sizeof  (val4));
00061   val8 = 0x0102030405060708LL;
00062   inet6_opt_set_val (db, offset, &val8, sizeof  (val8));
00063 
00064   cl = inet6_opt_append (eb, el, cl, OPT_Y, 7, 4, &db);
00065   CHECK ();
00066   val1 = 0x01;
00067   offset = inet6_opt_set_val (db, 0, &val1, sizeof  (val1));
00068   val2 = 0x1331;
00069   offset = inet6_opt_set_val (db, offset, &val2, sizeof  (val2));
00070   val4 = 0x01020304;
00071   inet6_opt_set_val (db, offset, &val4, sizeof  (val4));
00072 
00073   cl = inet6_opt_append (eb, el, cl, OPT_Z, 7, 1, &db);
00074   CHECK ();
00075   inet6_opt_set_val (db, 0, (void *) "abcdefg", 7);
00076 
00077   cl = inet6_opt_finish (eb, el, cl);
00078   CHECK ();
00079 
00080   if (memcmp (eb + el, "deadbeef", 8) != 0)
00081     {
00082       puts ("Canary corrupted");
00083       free (eb);
00084       return NULL;
00085     }
00086   *elp = el;
00087   return eb;
00088 }
00089 
00090 int
00091 decode_inet6_opt (void *eb, socklen_t el)
00092 {
00093   int ret = 0;
00094   int seq = 0;
00095   int cl = 0;
00096   int offset;
00097   uint8_t type;
00098   socklen_t len;
00099   uint8_t val1;
00100   uint16_t val2;
00101   uint32_t val4;
00102   uint64_t val8;
00103   void *db;
00104   char buf[8];
00105 
00106   while ((cl = inet6_opt_next (eb, el, cl, &type, &len, &db)) != -1)
00107     switch (type)
00108       {
00109       case OPT_X:
00110        if (seq++ != 0)
00111          {
00112            puts ("OPT_X is not first");
00113            ret = 1;
00114          }
00115        if (len != 12)
00116          {
00117            printf ("OPT_X's length %d != 12\n", len);
00118            ret = 1;
00119          }
00120        offset = inet6_opt_get_val (db, 0, &val4, sizeof (val4));
00121        if (val4 != 0x12345678)
00122          {
00123            printf ("OPT_X's val4 %x != 0x12345678\n", val4);
00124            ret = 1;
00125          }
00126        offset = inet6_opt_get_val (db, offset, &val8, sizeof (val8));
00127        if (offset != len || val8 != 0x0102030405060708LL)
00128          {
00129            printf ("OPT_X's val8 %llx != 0x0102030405060708\n",
00130                   (long long) val8);
00131            ret = 1;
00132          }
00133        break;
00134       case OPT_Y:
00135        if (seq++ != 1)
00136          {
00137            puts ("OPT_Y is not second");
00138            ret = 1;
00139          }
00140        if (len != 7)
00141          {
00142            printf ("OPT_Y's length %d != 7\n", len);
00143            ret = 1;
00144          }
00145        offset = inet6_opt_get_val (db, 0, &val1, sizeof (val1));
00146        if (val1 != 0x01)
00147          {
00148            printf ("OPT_Y's val1 %x != 0x01\n", val1);
00149            ret = 1;
00150          }
00151        offset = inet6_opt_get_val (db, offset, &val2, sizeof (val2));
00152        if (val2 != 0x1331)
00153          {
00154            printf ("OPT_Y's val2 %x != 0x1331\n", val2);
00155            ret = 1;
00156          }
00157        offset = inet6_opt_get_val (db, offset, &val4, sizeof (val4));
00158        if (offset != len || val4 != 0x01020304)
00159          {
00160            printf ("OPT_Y's val4 %x != 0x01020304\n", val4);
00161            ret = 1;
00162          }
00163        break;
00164       case OPT_Z:
00165        if (seq++ != 2)
00166          {
00167            puts ("OPT_Z is not third");
00168            ret = 1;
00169          }
00170        if (len != 7)
00171          {
00172            printf ("OPT_Z's length %d != 7\n", len);
00173            ret = 1;
00174          }
00175        offset = inet6_opt_get_val (db, 0, buf, 7);
00176        if (offset != len || memcmp (buf, "abcdefg", 7) != 0)
00177          {
00178            buf[7] = '\0';
00179            printf ("OPT_Z's buf \"%s\" != \"abcdefg\"\n", buf);
00180            ret = 1;
00181          }
00182        break;
00183       default:
00184        printf ("Unknown option %d\n", type);
00185        ret = 1;
00186        break;
00187       }
00188   if (seq != 3)
00189     {
00190       puts ("Didn't see all of OPT_X, OPT_Y and OPT_Z");
00191       ret = 1;
00192     }
00193   return ret;
00194 }
00195 
00196 int
00197 main (void)
00198 {
00199   void *eb;
00200   socklen_t el;
00201   eb = encode_inet6_opt (&el);
00202   if (eb == NULL)
00203     return 1;
00204   if (decode_inet6_opt (eb, el))
00205     return 1;
00206   return 0;
00207 }