Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/net/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 26 kB image not shown  

Quelle  ioam6_parser.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0+
/*
 * Author: Justin Iurman (justin.iurman@uliege.be)
 *
 * IOAM tester for IPv6, see ioam6.sh for details on each test case.
 */

#include <arpa/inet.h>
#include <errno.h>
#include <limits.h>
#include <linux/const.h>
#include <linux/if_ether.h>
#include <linux/ioam6.h>
#include <linux/ipv6.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

struct ioam_config {
 __u32 id;
 __u64 wide;
 __u16 ingr_id;
 __u16 egr_id;
 __u32 ingr_wide;
 __u32 egr_wide;
 __u32 ns_data;
 __u64 ns_wide;
 __u32 sc_id;
 __u8 hlim;
 char *sc_data;
};

/*
 * Be careful if you modify structs below - everything MUST be kept synchronized
 * with configurations inside ioam6.sh and always reflect the same.
 */


static struct ioam_config node1 = {
 .id = 1,
 .wide = 11111111,
 .ingr_id = 0xffff, /* default value */
 .egr_id = 101,
 .ingr_wide = 0xffffffff, /* default value */
 .egr_wide = 101101,
 .ns_data = 0xdeadbeef,
 .ns_wide = 0xcafec0caf00dc0de,
 .sc_id = 777,
 .sc_data = "something that will be 4n-aligned",
 .hlim = 64,
};

static struct ioam_config node2 = {
 .id = 2,
 .wide = 22222222,
 .ingr_id = 201,
 .egr_id = 202,
 .ingr_wide = 201201,
 .egr_wide = 202202,
 .ns_data = 0xffffffff, /* default value */
 .ns_wide = 0xffffffffffffffff, /* default value */
 .sc_id = 0xffffff, /* default value */
 .sc_data = NULL,
 .hlim = 63,
};

enum {
 /**********
 * OUTPUT *
 **********/

 __TEST_OUT_MIN,

 TEST_OUT_UNDEF_NS,
 TEST_OUT_NO_ROOM,
 TEST_OUT_NO_ROOM_OSS,
 TEST_OUT_BIT0,
 TEST_OUT_BIT1,
 TEST_OUT_BIT2,
 TEST_OUT_BIT3,
 TEST_OUT_BIT4,
 TEST_OUT_BIT5,
 TEST_OUT_BIT6,
 TEST_OUT_BIT7,
 TEST_OUT_BIT8,
 TEST_OUT_BIT9,
 TEST_OUT_BIT10,
 TEST_OUT_BIT11,
 TEST_OUT_BIT22,
 TEST_OUT_SIZE4,
 TEST_OUT_SIZE8,
 TEST_OUT_SIZE12,
 TEST_OUT_SIZE16,
 TEST_OUT_SIZE20,
 TEST_OUT_SIZE24,
 TEST_OUT_SIZE28,
 TEST_OUT_SIZE32,
 TEST_OUT_SIZE36,
 TEST_OUT_SIZE40,
 TEST_OUT_SIZE44,
 TEST_OUT_SIZE48,
 TEST_OUT_SIZE52,
 TEST_OUT_SIZE56,
 TEST_OUT_SIZE60,
 TEST_OUT_SIZE64,
 TEST_OUT_SIZE68,
 TEST_OUT_SIZE72,
 TEST_OUT_SIZE76,
 TEST_OUT_SIZE80,
 TEST_OUT_SIZE84,
 TEST_OUT_SIZE88,
 TEST_OUT_SIZE92,
 TEST_OUT_SIZE96,
 TEST_OUT_SIZE100,
 TEST_OUT_SIZE104,
 TEST_OUT_SIZE108,
 TEST_OUT_SIZE112,
 TEST_OUT_SIZE116,
 TEST_OUT_SIZE120,
 TEST_OUT_SIZE124,
 TEST_OUT_SIZE128,
 TEST_OUT_SIZE132,
 TEST_OUT_SIZE136,
 TEST_OUT_SIZE140,
 TEST_OUT_SIZE144,
 TEST_OUT_SIZE148,
 TEST_OUT_SIZE152,
 TEST_OUT_SIZE156,
 TEST_OUT_SIZE160,
 TEST_OUT_SIZE164,
 TEST_OUT_SIZE168,
 TEST_OUT_SIZE172,
 TEST_OUT_SIZE176,
 TEST_OUT_SIZE180,
 TEST_OUT_SIZE184,
 TEST_OUT_SIZE188,
 TEST_OUT_SIZE192,
 TEST_OUT_SIZE196,
 TEST_OUT_SIZE200,
 TEST_OUT_SIZE204,
 TEST_OUT_SIZE208,
 TEST_OUT_SIZE212,
 TEST_OUT_SIZE216,
 TEST_OUT_SIZE220,
 TEST_OUT_SIZE224,
 TEST_OUT_SIZE228,
 TEST_OUT_SIZE232,
 TEST_OUT_SIZE236,
 TEST_OUT_SIZE240,
 TEST_OUT_SIZE244,
 TEST_OUT_FULL_SUPP_TRACE,

 __TEST_OUT_MAX,

 /*********
 * INPUT *
 *********/

 __TEST_IN_MIN,

 TEST_IN_UNDEF_NS,
 TEST_IN_NO_ROOM,
 TEST_IN_NO_ROOM_OSS,
 TEST_IN_DISABLED,
 TEST_IN_OFLAG,
 TEST_IN_BIT0,
 TEST_IN_BIT1,
 TEST_IN_BIT2,
 TEST_IN_BIT3,
 TEST_IN_BIT4,
 TEST_IN_BIT5,
 TEST_IN_BIT6,
 TEST_IN_BIT7,
 TEST_IN_BIT8,
 TEST_IN_BIT9,
 TEST_IN_BIT10,
 TEST_IN_BIT11,
 TEST_IN_BIT22,
 TEST_IN_SIZE4,
 TEST_IN_SIZE8,
 TEST_IN_SIZE12,
 TEST_IN_SIZE16,
 TEST_IN_SIZE20,
 TEST_IN_SIZE24,
 TEST_IN_SIZE28,
 TEST_IN_SIZE32,
 TEST_IN_SIZE36,
 TEST_IN_SIZE40,
 TEST_IN_SIZE44,
 TEST_IN_SIZE48,
 TEST_IN_SIZE52,
 TEST_IN_SIZE56,
 TEST_IN_SIZE60,
 TEST_IN_SIZE64,
 TEST_IN_SIZE68,
 TEST_IN_SIZE72,
 TEST_IN_SIZE76,
 TEST_IN_SIZE80,
 TEST_IN_SIZE84,
 TEST_IN_SIZE88,
 TEST_IN_SIZE92,
 TEST_IN_SIZE96,
 TEST_IN_SIZE100,
 TEST_IN_SIZE104,
 TEST_IN_SIZE108,
 TEST_IN_SIZE112,
 TEST_IN_SIZE116,
 TEST_IN_SIZE120,
 TEST_IN_SIZE124,
 TEST_IN_SIZE128,
 TEST_IN_SIZE132,
 TEST_IN_SIZE136,
 TEST_IN_SIZE140,
 TEST_IN_SIZE144,
 TEST_IN_SIZE148,
 TEST_IN_SIZE152,
 TEST_IN_SIZE156,
 TEST_IN_SIZE160,
 TEST_IN_SIZE164,
 TEST_IN_SIZE168,
 TEST_IN_SIZE172,
 TEST_IN_SIZE176,
 TEST_IN_SIZE180,
 TEST_IN_SIZE184,
 TEST_IN_SIZE188,
 TEST_IN_SIZE192,
 TEST_IN_SIZE196,
 TEST_IN_SIZE200,
 TEST_IN_SIZE204,
 TEST_IN_SIZE208,
 TEST_IN_SIZE212,
 TEST_IN_SIZE216,
 TEST_IN_SIZE220,
 TEST_IN_SIZE224,
 TEST_IN_SIZE228,
 TEST_IN_SIZE232,
 TEST_IN_SIZE236,
 TEST_IN_SIZE240,
 TEST_IN_SIZE244,
 TEST_IN_FULL_SUPP_TRACE,

 __TEST_IN_MAX,

 __TEST_MAX,
};

static int check_header(int tid, struct ioam6_trace_hdr *trace,
   __u32 trace_type, __u8 trace_size, __u16 ioam_ns)
{
 if (__be16_to_cpu(trace->namespace_id) != ioam_ns ||
     __be32_to_cpu(trace->type_be32) != (trace_type << 8))
  return 1;

 switch (tid) {
 case TEST_OUT_UNDEF_NS:
 case TEST_IN_UNDEF_NS:
 case TEST_IN_DISABLED:
  return trace->overflow == 1 ||
         trace->nodelen != 1 ||
         trace->remlen != 1;

 case TEST_OUT_NO_ROOM:
 case TEST_IN_NO_ROOM:
 case TEST_IN_OFLAG:
  return trace->overflow == 0 ||
         trace->nodelen != 2 ||
         trace->remlen != 1;

 case TEST_OUT_NO_ROOM_OSS:
  return trace->overflow == 0 ||
         trace->nodelen != 0 ||
         trace->remlen != 1;

 case TEST_IN_NO_ROOM_OSS:
 case TEST_OUT_BIT22:
 case TEST_IN_BIT22:
  return trace->overflow == 1 ||
         trace->nodelen != 0 ||
         trace->remlen != 0;

 case TEST_OUT_BIT0:
 case TEST_IN_BIT0:
 case TEST_OUT_BIT1:
 case TEST_IN_BIT1:
 case TEST_OUT_BIT2:
 case TEST_IN_BIT2:
 case TEST_OUT_BIT3:
 case TEST_IN_BIT3:
 case TEST_OUT_BIT4:
 case TEST_IN_BIT4:
 case TEST_OUT_BIT5:
 case TEST_IN_BIT5:
 case TEST_OUT_BIT6:
 case TEST_IN_BIT6:
 case TEST_OUT_BIT7:
 case TEST_IN_BIT7:
 case TEST_OUT_BIT11:
 case TEST_IN_BIT11:
  return trace->overflow == 1 ||
         trace->nodelen != 1 ||
         trace->remlen != 0;

 case TEST_OUT_BIT8:
 case TEST_IN_BIT8:
 case TEST_OUT_BIT9:
 case TEST_IN_BIT9:
 case TEST_OUT_BIT10:
 case TEST_IN_BIT10:
  return trace->overflow == 1 ||
         trace->nodelen != 2 ||
         trace->remlen != 0;

 case TEST_OUT_SIZE4:
 case TEST_OUT_SIZE8:
 case TEST_OUT_SIZE12:
 case TEST_OUT_SIZE16:
 case TEST_OUT_SIZE20:
 case TEST_OUT_SIZE24:
 case TEST_OUT_SIZE28:
 case TEST_OUT_SIZE32:
 case TEST_OUT_SIZE36:
 case TEST_OUT_SIZE40:
 case TEST_OUT_SIZE44:
 case TEST_OUT_SIZE48:
 case TEST_OUT_SIZE52:
 case TEST_OUT_SIZE56:
 case TEST_OUT_SIZE60:
 case TEST_OUT_SIZE64:
 case TEST_OUT_SIZE68:
 case TEST_OUT_SIZE72:
 case TEST_OUT_SIZE76:
 case TEST_OUT_SIZE80:
 case TEST_OUT_SIZE84:
 case TEST_OUT_SIZE88:
 case TEST_OUT_SIZE92:
 case TEST_OUT_SIZE96:
 case TEST_OUT_SIZE100:
 case TEST_OUT_SIZE104:
 case TEST_OUT_SIZE108:
 case TEST_OUT_SIZE112:
 case TEST_OUT_SIZE116:
 case TEST_OUT_SIZE120:
 case TEST_OUT_SIZE124:
 case TEST_OUT_SIZE128:
 case TEST_OUT_SIZE132:
 case TEST_OUT_SIZE136:
 case TEST_OUT_SIZE140:
 case TEST_OUT_SIZE144:
 case TEST_OUT_SIZE148:
 case TEST_OUT_SIZE152:
 case TEST_OUT_SIZE156:
 case TEST_OUT_SIZE160:
 case TEST_OUT_SIZE164:
 case TEST_OUT_SIZE168:
 case TEST_OUT_SIZE172:
 case TEST_OUT_SIZE176:
 case TEST_OUT_SIZE180:
 case TEST_OUT_SIZE184:
 case TEST_OUT_SIZE188:
 case TEST_OUT_SIZE192:
 case TEST_OUT_SIZE196:
 case TEST_OUT_SIZE200:
 case TEST_OUT_SIZE204:
 case TEST_OUT_SIZE208:
 case TEST_OUT_SIZE212:
 case TEST_OUT_SIZE216:
 case TEST_OUT_SIZE220:
 case TEST_OUT_SIZE224:
 case TEST_OUT_SIZE228:
 case TEST_OUT_SIZE232:
 case TEST_OUT_SIZE236:
 case TEST_OUT_SIZE240:
 case TEST_OUT_SIZE244:
  return trace->overflow == 1 ||
         trace->nodelen != 1 ||
         trace->remlen != trace_size / 4;

 case TEST_IN_SIZE4:
 case TEST_IN_SIZE8:
 case TEST_IN_SIZE12:
 case TEST_IN_SIZE16:
 case TEST_IN_SIZE20:
 case TEST_IN_SIZE24:
 case TEST_IN_SIZE28:
 case TEST_IN_SIZE32:
 case TEST_IN_SIZE36:
 case TEST_IN_SIZE40:
 case TEST_IN_SIZE44:
 case TEST_IN_SIZE48:
 case TEST_IN_SIZE52:
 case TEST_IN_SIZE56:
 case TEST_IN_SIZE60:
 case TEST_IN_SIZE64:
 case TEST_IN_SIZE68:
 case TEST_IN_SIZE72:
 case TEST_IN_SIZE76:
 case TEST_IN_SIZE80:
 case TEST_IN_SIZE84:
 case TEST_IN_SIZE88:
 case TEST_IN_SIZE92:
 case TEST_IN_SIZE96:
 case TEST_IN_SIZE100:
 case TEST_IN_SIZE104:
 case TEST_IN_SIZE108:
 case TEST_IN_SIZE112:
 case TEST_IN_SIZE116:
 case TEST_IN_SIZE120:
 case TEST_IN_SIZE124:
 case TEST_IN_SIZE128:
 case TEST_IN_SIZE132:
 case TEST_IN_SIZE136:
 case TEST_IN_SIZE140:
 case TEST_IN_SIZE144:
 case TEST_IN_SIZE148:
 case TEST_IN_SIZE152:
 case TEST_IN_SIZE156:
 case TEST_IN_SIZE160:
 case TEST_IN_SIZE164:
 case TEST_IN_SIZE168:
 case TEST_IN_SIZE172:
 case TEST_IN_SIZE176:
 case TEST_IN_SIZE180:
 case TEST_IN_SIZE184:
 case TEST_IN_SIZE188:
 case TEST_IN_SIZE192:
 case TEST_IN_SIZE196:
 case TEST_IN_SIZE200:
 case TEST_IN_SIZE204:
 case TEST_IN_SIZE208:
 case TEST_IN_SIZE212:
 case TEST_IN_SIZE216:
 case TEST_IN_SIZE220:
 case TEST_IN_SIZE224:
 case TEST_IN_SIZE228:
 case TEST_IN_SIZE232:
 case TEST_IN_SIZE236:
 case TEST_IN_SIZE240:
 case TEST_IN_SIZE244:
  return trace->overflow == 1 ||
         trace->nodelen != 1 ||
         trace->remlen != (trace_size / 4) - trace->nodelen;

 case TEST_OUT_FULL_SUPP_TRACE:
 case TEST_IN_FULL_SUPP_TRACE:
  return trace->overflow == 1 ||
         trace->nodelen != 15 ||
         trace->remlen != 0;

 default:
  break;
 }

 return 1;
}

static int check_data(struct ioam6_trace_hdr *trace, __u8 trace_size,
        const struct ioam_config cnf, bool is_output)
{
 unsigned int len, i;
 __u8 aligned;
 __u64 raw64;
 __u32 raw32;
 __u8 *p;

 if (trace->type.bit12 | trace->type.bit13 | trace->type.bit14 |
     trace->type.bit15 | trace->type.bit16 | trace->type.bit17 |
     trace->type.bit18 | trace->type.bit19 | trace->type.bit20 |
     trace->type.bit21 | trace->type.bit23)
  return 1;

 for (i = 0; i < trace->remlen * 4; i++) {
  if (trace->data[i] != 0)
   return 1;
 }

 if (trace->remlen * 4 == trace_size)
  return 0;

 p = trace->data + trace->remlen * 4;

 if (trace->type.bit0) {
  raw32 = __be32_to_cpu(*((__u32 *)p));
  if (cnf.hlim != (raw32 >> 24) || cnf.id != (raw32 & 0xffffff))
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit1) {
  raw32 = __be32_to_cpu(*((__u32 *)p));
  if (cnf.ingr_id != (raw32 >> 16) ||
      cnf.egr_id != (raw32 & 0xffff))
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit2) {
  raw32 = __be32_to_cpu(*((__u32 *)p));
  if ((is_output && raw32 != 0xffffffff) ||
      (!is_output && (raw32 == 0 || raw32 == 0xffffffff)))
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit3) {
  raw32 = __be32_to_cpu(*((__u32 *)p));
  if ((is_output && raw32 != 0xffffffff) ||
      (!is_output && (raw32 == 0 || raw32 == 0xffffffff)))
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit4) {
  if (__be32_to_cpu(*((__u32 *)p)) != 0xffffffff)
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit5) {
  if (__be32_to_cpu(*((__u32 *)p)) != cnf.ns_data)
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit6) {
  if (__be32_to_cpu(*((__u32 *)p)) == 0xffffffff)
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit7) {
  if (__be32_to_cpu(*((__u32 *)p)) != 0xffffffff)
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit8) {
  raw64 = __be64_to_cpu(*((__u64 *)p));
  if (cnf.hlim != (raw64 >> 56) ||
      cnf.wide != (raw64 & 0xffffffffffffff))
   return 1;
  p += sizeof(__u64);
 }

 if (trace->type.bit9) {
  if (__be32_to_cpu(*((__u32 *)p)) != cnf.ingr_wide)
   return 1;
  p += sizeof(__u32);

  if (__be32_to_cpu(*((__u32 *)p)) != cnf.egr_wide)
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit10) {
  if (__be64_to_cpu(*((__u64 *)p)) != cnf.ns_wide)
   return 1;
  p += sizeof(__u64);
 }

 if (trace->type.bit11) {
  if (__be32_to_cpu(*((__u32 *)p)) != 0xffffffff)
   return 1;
  p += sizeof(__u32);
 }

 if (trace->type.bit22) {
  len = cnf.sc_data ? strlen(cnf.sc_data) : 0;
  aligned = cnf.sc_data ? __ALIGN_KERNEL(len, 4) : 0;

  raw32 = __be32_to_cpu(*((__u32 *)p));
  if (aligned != (raw32 >> 24) * 4 ||
      cnf.sc_id != (raw32 & 0xffffff))
   return 1;
  p += sizeof(__u32);

  if (cnf.sc_data) {
   if (strncmp((char *)p, cnf.sc_data, len))
    return 1;

   p += len;
   aligned -= len;

   while (aligned--) {
    if (*p != '\0')
     return 1;
    p += sizeof(__u8);
   }
  }
 }

 return 0;
}

static int check_ioam_trace(int tid, struct ioam6_trace_hdr *trace,
       __u32 trace_type, __u8 trace_size, __u16 ioam_ns)
{
 if (check_header(tid, trace, trace_type, trace_size, ioam_ns))
  return 1;

 if (tid > __TEST_OUT_MIN && tid < __TEST_OUT_MAX)
  return check_data(trace, trace_size, node1, true);

 if (tid > __TEST_IN_MIN && tid < __TEST_IN_MAX)
  return check_data(trace, trace_size, node2, false);

 return 1;
}

static int str2id(const char *tname)
{
 if (!strcmp("output_undef_ns", tname))
  return TEST_OUT_UNDEF_NS;
 if (!strcmp("output_no_room", tname))
  return TEST_OUT_NO_ROOM;
 if (!strcmp("output_no_room_oss", tname))
  return TEST_OUT_NO_ROOM_OSS;
 if (!strcmp("output_bit0", tname))
  return TEST_OUT_BIT0;
 if (!strcmp("output_bit1", tname))
  return TEST_OUT_BIT1;
 if (!strcmp("output_bit2", tname))
  return TEST_OUT_BIT2;
 if (!strcmp("output_bit3", tname))
  return TEST_OUT_BIT3;
 if (!strcmp("output_bit4", tname))
  return TEST_OUT_BIT4;
 if (!strcmp("output_bit5", tname))
  return TEST_OUT_BIT5;
 if (!strcmp("output_bit6", tname))
  return TEST_OUT_BIT6;
 if (!strcmp("output_bit7", tname))
  return TEST_OUT_BIT7;
 if (!strcmp("output_bit8", tname))
  return TEST_OUT_BIT8;
 if (!strcmp("output_bit9", tname))
  return TEST_OUT_BIT9;
 if (!strcmp("output_bit10", tname))
  return TEST_OUT_BIT10;
 if (!strcmp("output_bit11", tname))
  return TEST_OUT_BIT11;
 if (!strcmp("output_bit22", tname))
  return TEST_OUT_BIT22;
 if (!strcmp("output_size4", tname))
  return TEST_OUT_SIZE4;
 if (!strcmp("output_size8", tname))
  return TEST_OUT_SIZE8;
 if (!strcmp("output_size12", tname))
  return TEST_OUT_SIZE12;
 if (!strcmp("output_size16", tname))
  return TEST_OUT_SIZE16;
 if (!strcmp("output_size20", tname))
  return TEST_OUT_SIZE20;
 if (!strcmp("output_size24", tname))
  return TEST_OUT_SIZE24;
 if (!strcmp("output_size28", tname))
  return TEST_OUT_SIZE28;
 if (!strcmp("output_size32", tname))
  return TEST_OUT_SIZE32;
 if (!strcmp("output_size36", tname))
  return TEST_OUT_SIZE36;
 if (!strcmp("output_size40", tname))
  return TEST_OUT_SIZE40;
 if (!strcmp("output_size44", tname))
  return TEST_OUT_SIZE44;
 if (!strcmp("output_size48", tname))
  return TEST_OUT_SIZE48;
 if (!strcmp("output_size52", tname))
  return TEST_OUT_SIZE52;
 if (!strcmp("output_size56", tname))
  return TEST_OUT_SIZE56;
 if (!strcmp("output_size60", tname))
  return TEST_OUT_SIZE60;
 if (!strcmp("output_size64", tname))
  return TEST_OUT_SIZE64;
 if (!strcmp("output_size68", tname))
  return TEST_OUT_SIZE68;
 if (!strcmp("output_size72", tname))
  return TEST_OUT_SIZE72;
 if (!strcmp("output_size76", tname))
  return TEST_OUT_SIZE76;
 if (!strcmp("output_size80", tname))
  return TEST_OUT_SIZE80;
 if (!strcmp("output_size84", tname))
  return TEST_OUT_SIZE84;
 if (!strcmp("output_size88", tname))
  return TEST_OUT_SIZE88;
 if (!strcmp("output_size92", tname))
  return TEST_OUT_SIZE92;
 if (!strcmp("output_size96", tname))
  return TEST_OUT_SIZE96;
 if (!strcmp("output_size100", tname))
  return TEST_OUT_SIZE100;
 if (!strcmp("output_size104", tname))
  return TEST_OUT_SIZE104;
 if (!strcmp("output_size108", tname))
  return TEST_OUT_SIZE108;
 if (!strcmp("output_size112", tname))
  return TEST_OUT_SIZE112;
 if (!strcmp("output_size116", tname))
  return TEST_OUT_SIZE116;
 if (!strcmp("output_size120", tname))
  return TEST_OUT_SIZE120;
 if (!strcmp("output_size124", tname))
  return TEST_OUT_SIZE124;
 if (!strcmp("output_size128", tname))
  return TEST_OUT_SIZE128;
 if (!strcmp("output_size132", tname))
  return TEST_OUT_SIZE132;
 if (!strcmp("output_size136", tname))
  return TEST_OUT_SIZE136;
 if (!strcmp("output_size140", tname))
  return TEST_OUT_SIZE140;
 if (!strcmp("output_size144", tname))
  return TEST_OUT_SIZE144;
 if (!strcmp("output_size148", tname))
  return TEST_OUT_SIZE148;
 if (!strcmp("output_size152", tname))
  return TEST_OUT_SIZE152;
 if (!strcmp("output_size156", tname))
  return TEST_OUT_SIZE156;
 if (!strcmp("output_size160", tname))
  return TEST_OUT_SIZE160;
 if (!strcmp("output_size164", tname))
  return TEST_OUT_SIZE164;
 if (!strcmp("output_size168", tname))
  return TEST_OUT_SIZE168;
 if (!strcmp("output_size172", tname))
  return TEST_OUT_SIZE172;
 if (!strcmp("output_size176", tname))
  return TEST_OUT_SIZE176;
 if (!strcmp("output_size180", tname))
  return TEST_OUT_SIZE180;
 if (!strcmp("output_size184", tname))
  return TEST_OUT_SIZE184;
 if (!strcmp("output_size188", tname))
  return TEST_OUT_SIZE188;
 if (!strcmp("output_size192", tname))
  return TEST_OUT_SIZE192;
 if (!strcmp("output_size196", tname))
  return TEST_OUT_SIZE196;
 if (!strcmp("output_size200", tname))
  return TEST_OUT_SIZE200;
 if (!strcmp("output_size204", tname))
  return TEST_OUT_SIZE204;
 if (!strcmp("output_size208", tname))
  return TEST_OUT_SIZE208;
 if (!strcmp("output_size212", tname))
  return TEST_OUT_SIZE212;
 if (!strcmp("output_size216", tname))
  return TEST_OUT_SIZE216;
 if (!strcmp("output_size220", tname))
  return TEST_OUT_SIZE220;
 if (!strcmp("output_size224", tname))
  return TEST_OUT_SIZE224;
 if (!strcmp("output_size228", tname))
  return TEST_OUT_SIZE228;
 if (!strcmp("output_size232", tname))
  return TEST_OUT_SIZE232;
 if (!strcmp("output_size236", tname))
  return TEST_OUT_SIZE236;
 if (!strcmp("output_size240", tname))
  return TEST_OUT_SIZE240;
 if (!strcmp("output_size244", tname))
  return TEST_OUT_SIZE244;
 if (!strcmp("output_full_supp_trace", tname))
  return TEST_OUT_FULL_SUPP_TRACE;
 if (!strcmp("input_undef_ns", tname))
  return TEST_IN_UNDEF_NS;
 if (!strcmp("input_no_room", tname))
  return TEST_IN_NO_ROOM;
 if (!strcmp("input_no_room_oss", tname))
  return TEST_IN_NO_ROOM_OSS;
 if (!strcmp("input_disabled", tname))
  return TEST_IN_DISABLED;
 if (!strcmp("input_oflag", tname))
  return TEST_IN_OFLAG;
 if (!strcmp("input_bit0", tname))
  return TEST_IN_BIT0;
 if (!strcmp("input_bit1", tname))
  return TEST_IN_BIT1;
 if (!strcmp("input_bit2", tname))
  return TEST_IN_BIT2;
 if (!strcmp("input_bit3", tname))
  return TEST_IN_BIT3;
 if (!strcmp("input_bit4", tname))
  return TEST_IN_BIT4;
 if (!strcmp("input_bit5", tname))
  return TEST_IN_BIT5;
 if (!strcmp("input_bit6", tname))
  return TEST_IN_BIT6;
 if (!strcmp("input_bit7", tname))
  return TEST_IN_BIT7;
 if (!strcmp("input_bit8", tname))
  return TEST_IN_BIT8;
 if (!strcmp("input_bit9", tname))
  return TEST_IN_BIT9;
 if (!strcmp("input_bit10", tname))
  return TEST_IN_BIT10;
 if (!strcmp("input_bit11", tname))
  return TEST_IN_BIT11;
 if (!strcmp("input_bit22", tname))
  return TEST_IN_BIT22;
 if (!strcmp("input_size4", tname))
  return TEST_IN_SIZE4;
 if (!strcmp("input_size8", tname))
  return TEST_IN_SIZE8;
 if (!strcmp("input_size12", tname))
  return TEST_IN_SIZE12;
 if (!strcmp("input_size16", tname))
  return TEST_IN_SIZE16;
 if (!strcmp("input_size20", tname))
  return TEST_IN_SIZE20;
 if (!strcmp("input_size24", tname))
  return TEST_IN_SIZE24;
 if (!strcmp("input_size28", tname))
  return TEST_IN_SIZE28;
 if (!strcmp("input_size32", tname))
  return TEST_IN_SIZE32;
 if (!strcmp("input_size36", tname))
  return TEST_IN_SIZE36;
 if (!strcmp("input_size40", tname))
  return TEST_IN_SIZE40;
 if (!strcmp("input_size44", tname))
  return TEST_IN_SIZE44;
 if (!strcmp("input_size48", tname))
  return TEST_IN_SIZE48;
 if (!strcmp("input_size52", tname))
  return TEST_IN_SIZE52;
 if (!strcmp("input_size56", tname))
  return TEST_IN_SIZE56;
 if (!strcmp("input_size60", tname))
  return TEST_IN_SIZE60;
 if (!strcmp("input_size64", tname))
  return TEST_IN_SIZE64;
 if (!strcmp("input_size68", tname))
  return TEST_IN_SIZE68;
 if (!strcmp("input_size72", tname))
  return TEST_IN_SIZE72;
 if (!strcmp("input_size76", tname))
  return TEST_IN_SIZE76;
 if (!strcmp("input_size80", tname))
  return TEST_IN_SIZE80;
 if (!strcmp("input_size84", tname))
  return TEST_IN_SIZE84;
 if (!strcmp("input_size88", tname))
  return TEST_IN_SIZE88;
 if (!strcmp("input_size92", tname))
  return TEST_IN_SIZE92;
 if (!strcmp("input_size96", tname))
  return TEST_IN_SIZE96;
 if (!strcmp("input_size100", tname))
  return TEST_IN_SIZE100;
 if (!strcmp("input_size104", tname))
  return TEST_IN_SIZE104;
 if (!strcmp("input_size108", tname))
  return TEST_IN_SIZE108;
 if (!strcmp("input_size112", tname))
  return TEST_IN_SIZE112;
 if (!strcmp("input_size116", tname))
  return TEST_IN_SIZE116;
 if (!strcmp("input_size120", tname))
  return TEST_IN_SIZE120;
 if (!strcmp("input_size124", tname))
  return TEST_IN_SIZE124;
 if (!strcmp("input_size128", tname))
  return TEST_IN_SIZE128;
 if (!strcmp("input_size132", tname))
  return TEST_IN_SIZE132;
 if (!strcmp("input_size136", tname))
  return TEST_IN_SIZE136;
 if (!strcmp("input_size140", tname))
  return TEST_IN_SIZE140;
 if (!strcmp("input_size144", tname))
  return TEST_IN_SIZE144;
 if (!strcmp("input_size148", tname))
  return TEST_IN_SIZE148;
 if (!strcmp("input_size152", tname))
  return TEST_IN_SIZE152;
 if (!strcmp("input_size156", tname))
  return TEST_IN_SIZE156;
 if (!strcmp("input_size160", tname))
  return TEST_IN_SIZE160;
 if (!strcmp("input_size164", tname))
  return TEST_IN_SIZE164;
 if (!strcmp("input_size168", tname))
  return TEST_IN_SIZE168;
 if (!strcmp("input_size172", tname))
  return TEST_IN_SIZE172;
 if (!strcmp("input_size176", tname))
  return TEST_IN_SIZE176;
 if (!strcmp("input_size180", tname))
  return TEST_IN_SIZE180;
 if (!strcmp("input_size184", tname))
  return TEST_IN_SIZE184;
 if (!strcmp("input_size188", tname))
  return TEST_IN_SIZE188;
 if (!strcmp("input_size192", tname))
  return TEST_IN_SIZE192;
 if (!strcmp("input_size196", tname))
  return TEST_IN_SIZE196;
 if (!strcmp("input_size200", tname))
  return TEST_IN_SIZE200;
 if (!strcmp("input_size204", tname))
  return TEST_IN_SIZE204;
 if (!strcmp("input_size208", tname))
  return TEST_IN_SIZE208;
 if (!strcmp("input_size212", tname))
  return TEST_IN_SIZE212;
 if (!strcmp("input_size216", tname))
  return TEST_IN_SIZE216;
 if (!strcmp("input_size220", tname))
  return TEST_IN_SIZE220;
 if (!strcmp("input_size224", tname))
  return TEST_IN_SIZE224;
 if (!strcmp("input_size228", tname))
  return TEST_IN_SIZE228;
 if (!strcmp("input_size232", tname))
  return TEST_IN_SIZE232;
 if (!strcmp("input_size236", tname))
  return TEST_IN_SIZE236;
 if (!strcmp("input_size240", tname))
  return TEST_IN_SIZE240;
 if (!strcmp("input_size244", tname))
  return TEST_IN_SIZE244;
 if (!strcmp("input_full_supp_trace", tname))
  return TEST_IN_FULL_SUPP_TRACE;

 return -1;
}

static int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2)
{
 return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
  (a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
  (a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
  (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0;
}

static int get_u32(__u32 *val, const char *arg, int base)
{
 unsigned long res;
 char *ptr;

 if (!arg || !*arg)
  return -1;
 res = strtoul(arg, &ptr, base);

 if (!ptr || ptr == arg || *ptr)
  return -1;

 if (res == ULONG_MAX && errno == ERANGE)
  return -1;

 if (res > 0xFFFFFFFFUL)
  return -1;

 *val = res;
 return 0;
}

static int get_u16(__u16 *val, const char *arg, int base)
{
 unsigned long res;
 char *ptr;

 if (!arg || !*arg)
  return -1;
 res = strtoul(arg, &ptr, base);

 if (!ptr || ptr == arg || *ptr)
  return -1;

 if (res == ULONG_MAX && errno == ERANGE)
  return -1;

 if (res > 0xFFFFUL)
  return -1;

 *val = res;
 return 0;
}

static int get_u8(__u8 *val, const char *arg, int base)
{
 unsigned long res;
 char *ptr;

 if (!arg || !*arg)
  return -1;
 res = strtoul(arg, &ptr, base);

 if (!ptr || ptr == arg || *ptr)
  return -1;

 if (res == ULONG_MAX && errno == ERANGE)
  return -1;

 if (res > 0xFFUL)
  return -1;

 *val = res;
 return 0;
}

int main(int argc, char **argv)
{
 __u8 buffer[512], *ptr, nexthdr, tr_size;
 struct ioam6_trace_hdr *trace;
 unsigned int hoplen, ret = 1;
 struct ipv6_hopopt_hdr *hbh;
 int fd, size, testname_id;
 struct in6_addr src, dst;
 struct ioam6_hdr *ioam6;
 struct timeval timeout;
 struct ipv6hdr *ipv6;
 __u32 tr_type;
 __u16 ioam_ns;

 if (argc != 9)
  goto out;

 testname_id = str2id(argv[2]);

 if (testname_id < 0 ||
     inet_pton(AF_INET6, argv[3], &src) != 1 ||
     inet_pton(AF_INET6, argv[4], &dst) != 1 ||
     get_u32(&tr_type, argv[5], 16) ||
     get_u8(&tr_size, argv[6], 0) ||
     get_u16(&ioam_ns, argv[7], 0))
  goto out;

 nexthdr = (!strcmp(argv[8], "encap") ? IPPROTO_IPV6 : IPPROTO_ICMPV6);

 hoplen = sizeof(*hbh);
 hoplen += 2; // 2-byte padding for alignment
 hoplen += sizeof(*ioam6); // IOAM option header
 hoplen += sizeof(*trace); // IOAM trace header
 hoplen += tr_size; // IOAM trace size
 hoplen += (tr_size % 8); // optional padding

 fd = socket(AF_PACKET, SOCK_DGRAM, __cpu_to_be16(ETH_P_IPV6));
 if (fd < 0)
  goto out;

 if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
         argv[1], strlen(argv[1])))
  goto close;

 timeout.tv_sec = 1;
 timeout.tv_usec = 0;
 if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,
         (const char *)&timeout, sizeof(timeout)))
  goto close;
recv:
 size = recv(fd, buffer, sizeof(buffer), 0);
 if (size <= 0)
  goto close;

 ipv6 = (struct ipv6hdr *)buffer;

 /* Skip packets that do not have the expected src/dst address or that
 * do not have a Hop-by-hop.
 */

 if (!ipv6_addr_equal(&ipv6->saddr, &src) ||
     !ipv6_addr_equal(&ipv6->daddr, &dst) ||
     ipv6->nexthdr != IPPROTO_HOPOPTS)
  goto recv;

 /* Check Hbh's Next Header and Size. */
 hbh = (struct ipv6_hopopt_hdr *)(buffer + sizeof(*ipv6));
 if (hbh->nexthdr != nexthdr || hbh->hdrlen != (hoplen >> 3) - 1)
  goto close;

 /* Check we have a 2-byte padding for alignment. */
 ptr = (__u8 *)hbh + sizeof(*hbh);
 if (ptr[0] != IPV6_TLV_PADN && ptr[1] != 0)
  goto close;

 /* Check we now have the IOAM option. */
 ptr += 2;
 if (ptr[0] != IPV6_TLV_IOAM)
  goto close;

 /* Check its size and the IOAM option type. */
 ioam6 = (struct ioam6_hdr *)ptr;
 if (ioam6->opt_len != sizeof(*ioam6) - 2 + sizeof(*trace) + tr_size ||
     ioam6->type != IOAM6_TYPE_PREALLOC)
  goto close;

 trace = (struct ioam6_trace_hdr *)(ptr + sizeof(*ioam6));

 /* Check the trailing 4-byte padding (potentially). */
 ptr = (__u8 *)trace + sizeof(*trace) + tr_size;
 if (tr_size % 8 && ptr[0] != IPV6_TLV_PADN && ptr[1] != 2 &&
     ptr[2] != 0 && ptr[3] != 0)
  goto close;

 /* Check the IOAM header and data. */
 ret = check_ioam_trace(testname_id, trace, tr_type, tr_size, ioam_ns);
close:
 close(fd);
out:
 return ret;
}

Messung V0.5
C=94 H=95 G=94

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.