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

Posted khldragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于协议标识符的实现方法相关的知识,希望对你有一定的参考价值。

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

2、实现要点

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)

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)

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

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;

以上是关于关于协议标识符的实现方法的主要内容,如果未能解决你的问题,请参考以下文章

href="javascript:;"

跨域访问方法介绍--使用片段识别符传值

在 PHP 重定向期间处理片段标识符

a标签调用js的几种方法

关于代码片段的时间复杂度

几个关于js数组方法reduce的经典片段