关于协议标识符的实现方法

1.1、协议标识符(协议头部)设计例子

协议头部一般规定字段及字段大小,以此来约束协议适用范围和使用场景

/** Size of bit-fields in XSP header */
#define XSP_ID_PROTOCOL_SIZE    3
#define XSP_ID_PRIO_SIZE        3
#define XSP_ID_HOST_SIZE        4
#define XSP_ID_PORT_SIZE        5
#define XSP_ID_FLAGS_SIZE       8

1.2、实现要点

1.2.1、字段最大值

/** Highest number to be entered in field */
#define XSP_ID_PROTOCOL_MAX     ((1 << (XSP_ID_PROTOCOL_SIZE)) - 1)
#define XSP_ID_PRIO_MAX         ((1 << (XSP_ID_PRIO_SIZE)) - 1)
#define XSP_ID_HOST_MAX         ((1 << (XSP_ID_HOST_SIZE)) - 1)
#define XSP_ID_PORT_MAX         ((1 << (XSP_ID_PORT_SIZE)) - 1)
#define XSP_ID_FLAGS_MAX        ((1 << (XSP_ID_FLAGS_SIZE)) - 1)

1.2.2、字段掩码

/** Identifier field masks */
#define XSP_ID_PROTOCOL_MASK    ((uint32_t) XSP_ID_PROTOCOL_MAX << (XSP_ID_FLAGS_SIZE + 2 * XSP_ID_PORT_SIZE + 2 * XSP_ID_HOST_SIZE + XSP_ID_PROTOCOL_SIZE))
#define XSP_ID_PRIO_MASK        ((uint32_t) XSP_ID_PRIO_MAX     << (XSP_ID_FLAGS_SIZE + 2 * XSP_ID_PORT_SIZE + 2 * XSP_ID_HOST_SIZE))
#define XSP_ID_SRC_MASK         ((uint32_t) XSP_ID_HOST_MAX     << (XSP_ID_FLAGS_SIZE + 2 * XSP_ID_PORT_SIZE + 1 * XSP_ID_HOST_SIZE))
#define XSP_ID_DST_MASK         ((uint32_t) XSP_ID_HOST_MAX     << (XSP_ID_FLAGS_SIZE + 2 * XSP_ID_PORT_SIZE))
#define XSP_ID_DPORT_MASK       ((uint32_t) XSP_ID_PORT_MAX     << (XSP_ID_FLAGS_SIZE + 1 * XSP_ID_PORT_SIZE))
#define XSP_ID_SPORT_MASK       ((uint32_t) XSP_ID_PORT_MAX     << (XSP_ID_FLAGS_SIZE))
#define XSP_ID_FLAGS_MASK       ((uint32_t) XSP_ID_FLAGS_MAX    << (0))

#define XSP_ID_CONN_MASK        (XSP_ID_SRC_MASK | XSP_ID_DST_MASK | XSP_ID_DPORT_MASK | XSP_ID_SPORT_MASK)

1.2.3、头部位数核算

#if XSP_ID_PROTOCOL_SIZE + XSP_ID_PRIO_SIZE + 2 * XSP_ID_HOST_SIZE + 2 * XSP_ID_PORT_SIZE + XSP_ID_FLAGS_SIZE != 32 && __GNUC__
#error "Header lenght must be 32 bits"
#endif

1.2.4、适用于标识符实现的数据结构

This union defines a XSP identifier and allows access to the individual fields or the entire identifier.
联合体的所有成员变量都存在同一个内存位置,可以访问一个域或者全部域的标识符,后者用于对比是否是同一个packet。

typedef union {
  uint32_t ext;
  struct __attribute__((__packed__)) {

#if defined(_XSP_BIG_ENDIAN_) && !defined(_XSP_LITTLE_ENDIAN_)

    unsigned int protocol   : XSP_ID_PROTOCOL_SIZE;
    unsigned int pri        : XSP_ID_PRIO_SIZE;
    unsigned int src        : XSP_ID_HOST_SIZE;
    unsigned int dst        : XSP_ID_HOST_SIZE;
    unsigned int dport      : XSP_ID_PORT_SIZE;
    unsigned int sport      : XSP_ID_PORT_SIZE;
    unsigned int flags      : XSP_ID_FLAGS_SIZE;

#elif defined(_XSP_LITTLE_ENDIAN_) && !defined(_XSP_BIG_ENDIAN_)

    unsigned int flags      : XSP_ID_FLAGS_SIZE;
    unsigned int sport      : XSP_ID_PORT_SIZE;
    unsigned int dport      : XSP_ID_PORT_SIZE;
    unsigned int dst        : XSP_ID_HOST_SIZE;
    unsigned int src        : XSP_ID_HOST_SIZE;
    unsigned int pri        : XSP_ID_PRIO_SIZE;
    unsigned int protocol   : XSP_ID_PROTOCOL_SIZE;

#else

  #error "Must define one of _XSP_BIG_ENDIAN_ or _XSP_LITTLE_ENDIAN_ in XSP_platform.h"

#endif

  };
} XSP_id_t;
posted @ 2020-02-11 14:04  khldragon  阅读(362)  评论(0编辑  收藏  举报