#include #include #include #include /* Generic structure for encapsulation of optional route information. It is reminiscent of sockaddr, but with sa_family replaced with attribute type. */ #define COMMNL_TALKRCV_TIMEOUT (2) /*超时时间10毫秒*1次*/ struct rtattr { unsigned short rta_len; unsigned short rta_type; }; /* Macros to handle rtattributes */ #define RTA_ALIGNTO 4U #define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) ) #define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \ (rta)->rta_len >= sizeof(struct rtattr) && \ (rta)->rta_len <= (len)) #define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \ (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len))) #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) #define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len)) #define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0))) #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) #define NLMSG_TAIL(nmsg) \ ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) #define NEW_NL_MSG(msg_type,datasize) \ malloc(); typedef int (*nl_ext_ack_fn_t)(const char *errmsg, uint32_t off, const struct nlmsghdr *inner_nlh); struct pdelivnl_ctrl_data { int nsid; }; struct upmnl_handle { int fd; struct sockaddr_nl local;/*里面包含协议号,加入的组,pid*/ struct sockaddr_nl peer; int proto; __u32 seq;/*目前发送消息的序列号*/ //__u32 dump; //FILE *dump_fp; //#define RTNL_HANDLE_F_LISTEN_ALL_NSID 0x01 //#define RTNL_HANDLE_F_SUPPRESS_NLERR 0x02 //#define RTNL_HANDLE_F_STRICT_CHK 0x04 int flags; // int debug_flags; }; //#define NETLINK_DEBUG() if(debug_flags) /*应用模块提供的报文处理回调函数原型*/ typedef int (*pdelivnl_listen_filter_t)(struct pdelivnl_ctrl_data *, struct nlmsghdr *n, void *); void printf_mem(unsigned char * p,int len); /****************************************************************/ /*函数功能:给netlink消息添加可选的ATTR属性。*/ /*输入参数: */ /*n:需要添加attr属性的netlink消息头;*/ /*maxlen:整个netlink消息可以空间的大小;*/ /*type:添加的attr的类型*/ /*data:添加的attr的值*/ /*输出参数: 无*/ /*返回值:0通道创建成果;< 0,失败 */ /****************************************************************/ int commnl_addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen); int commnl_addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data); int commnl_addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data); int commnl_addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data); int commnl_addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data); int commnl_addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *str); /****************************************************************/ /*函数功能:创建一个新的内核配置下发通道,给内核态的安全接入模块下发配置, */ /*可以支持多实例,即多个用户态模块可以同时给内核态的安全接入模块下发配置。*/ /*输入参数:无 */ /*输出参数: struct upmnl_handle * upmh ,存放创建的通道相关信息。*/ /*返回值:0通道创建成果;< 0,失败 */ /****************************************************************/ int commcfgnl_open(); void commcfgnl_close(); /****************************************************************/ /*函数功能:创建一个新的包接收通道,接收需要上送DPI的原始报文, */ /*报文内容从链路层头开始。可以支持多实例,即多个收包模块可以同时*/ /*收到同一份报文的拷贝。 */ /*输入参数:无 */ /*输出参数: struct upmnl_handle * upmh ,存放创建的通道相关信息。*/ /*返回值:0通道创建成果;< 0,失败 */ /****************************************************************/ int pdelivnl_open(unsigned int group); void pdelivnl_close(unsigned int group); //int upnl_dump_type(struct upmnl_handle *upmh, unsigned int type); /****************************************************************/ /*函数功能:在已经创建好的包接收通道上,循环接收报文。*/ /*输入参数:*/ /*nl:监听的通道所属的组。 */ /*handler:报文处理回调函数,在接收到报文时调用。 */ /*jarg :用户自定义上下文信息,在报文处理回调函数调用是,会将jarg当做参数传入。*/ /*输出参数: 无*/ /*返回值:0成功;< 0,失败 */ /****************************************************************/ int pdelivnl_listen(int group, pdelivnl_listen_filter_t handler, void *jarg); /****************************************************************/ /*函数功能:在已经创建好的包接收通道上,循环接收报文。*/ /*输入参数:*/ /*nl:监听的通道。 */ /*handler:报文处理回调函数,在接收到报文时调用。 */ /*jarg :用户自定义上下文信息,在报文处理回调函数调用是,会将jarg当做参数传入。*/ /*输出参数: 无*/ /*返回值:0成功;< 0,失败 */ /****************************************************************/ int conmnl_listen(struct upmnl_handle *nl, pdelivnl_listen_filter_t handler, void *jarg); /****************************************************************/ /*函数功能:发送配置消息,并同步等待内核应答。*/ /*输入参数:*/ /*nl:监听的通道。 */ /*n:需要发送的配置消息。 */ /*输出参数: */ /*answer :接收到内核应答消息。*/ /*返回值:0成功;< 0,失败 */ /****************************************************************/ int commnl_talk(struct upmnl_handle *nl, struct nlmsghdr *n, struct nlmsghdr **answer); int commcfg_talk(struct nlmsghdr *n, struct nlmsghdr **answer); int pdeliv_talk(int group,struct nlmsghdr *n, struct nlmsghdr **answer); /****************************************************************/ /*函数功能:发送配置消息,不等待内核应答。*/ /*输入参数:*/ /*nl:发送的通道。 */ /*n:需要发送的配置消息。 */ /*输出参数: */ /*返回值:0成功;< 0,失败 */ /****************************************************************/ int commcfg_send(struct nlmsghdr *n); int pdelivnl_send(int group,struct nlmsghdr *n); int pdeliv_main(pdelivnl_listen_filter_t process_pkt); void nl_debugfs(struct nlmsghdr *n); void nl_debugfs_extack(struct nlmsghdr *n);