



免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本文档的Copyleft归wwwlkk所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。 E-mail: 来源: /?business&aid=6&un=wwwlkk#7struct nlmsghdr _u32nlmsg_len;/* Length of message including header */_u16nlmsg_type;/* Message content */子系统id号_u16nlmsg_flags;/* Additional flags */_u32nlmsg_seq;/* Sequence number */_u32nlmsg_pid;/* Sending process port ID */;struct nlattr _u16 nla_len;_u16 nla_type;/* * * +-+- - -+- - - - - - - - - -+- - -+ * | Header | Pad | Payload | Pad | * | (struct nlattr) | ing | | ing | * +-+-+- - - - - - - - - -+- - -+ * nla_len - */使用netlink Message and Attributes Interface时,使用nla_parse解析属性时要求每一个属性类型都是唯一的,也就是如下所示: nlmsghdr | Pad | Family Header | Pad | attri1 | Pad | attri value | Pad | attri2 | Pad | attri value | Pad | attri3 | .其实,一个对象的属性本来就是唯一的。但是如果一个属性下面又分了多个属性,怎么办?NLA_F_NESTED粉末登场了。使用NLA_F_NESTED可以达到属性多级嵌套,其数据结构如下: nlmsghdr | Pad | Family Header | Pad | attri1 | Pad | attri value | attri2 | Pad | attri:NLA_F_NESTED | Pad | attri2_1 | Pad | attri value | Pad | attri2_2 | Pad | . 通过nla_parse得到attri2的属性值,再通过nla_parse_nested得到嵌套在attri2里面的属性值。IPSET_CMD_CREATE用户空间parse_commandline() 1| ipset_parse_setname(session, IPSET_SETNAME, arg0);将集合名写入session-data-setname2| ipset_session_data_set() 3| ipset_data_set(ipset_session_data(session), opt, value) 4| ipset_data_flags_set(data, IPSET_FLAG(opt); 5| data-bits |= flags; 设置标志位 1| ipset_parse_typename(session, IPSET_OPT_TYPENAME, arg1); 2| typename = ipset_typename_resolve(str); 用户空间检查集合类型2| type = ipset_type_get(session, IPSET_CMD_CREATE);内核空间查找用户名 3| create_type_get(session); 4| ret = ipset_cmd(session, IPSET_CMD_TYPE, 0);发送检查消息到内核 4| ipset_data_set(data, IPSET_OPT_TYPE, match); 设置结构struct ipset_type 3| ipset_session_data_set(session, IPSET_OPT_TYPE, type);结构struct ipset_type1| type = ipset_type_get(session, cmd);获得集合类型结构struct ipset_type2| ret = call_parser(&argc, argv, type-argsIPSET_CREATE);解析类型参数 3| 遍历参数列表 struct ipset_arg1| ipset_call_parser(session, arg, argv1); 2| arg-parse(session, arg-opt, str); 3| 具体的例子ipset_parse_uint32() 4|ipset_session_data_set(session, opt, &value); 其中enum ipset_opt opt 1| check_mandatory(type, cmd);检查强制性属性是否有 1| check_allowed(type, cmd)根据type-fullcmd和data-bits检查已经设置的选项 1| ret = ipset_cmd(session, cmd, restore_line);发送真正的命令到内核2| ret = build_msg(session, aggregate);组建netlink消息 3| struct nlmsghdr *nlh = session-buffer; 3|ADDATTR_SETNAME(session, nlh, data); 3|ADDATTR(session, nlh, data, IPSET_ATTR_TYPENAME, AF_INET, cmd_attrs); 3|ADDATTR_RAW(session, nlh, &type-revision,IPSET_ATTR_REVISION, cmd_attrs); 3|open_nested(session, nlh, IPSET_ATTR_DATA); 4|session-nestedsession-nestid+ = mnl_attr_nest_start(nlh, attr); 5|struct nlattr *start = mnl_nlmsg_get_payload_tail(nlh); 5|start-nla_type = NLA_F_NESTED | type; 3|addattr_create(session, nlh, data, type-family); 4|根据data-bits遍历已设置的选项 5|ADDATTR_IF(session, nlh, data, i, family, create_attrs); 6|ipset_data_test(data, attrstype.opt) ? data2attr(session, nlh, data, type, family, attrs) : 0 3|close_nested(session, nlh); 4|mnl_attr_nest_end(nlh, session-nestedsession-nestid-1); 5| start-nla_len = mnl_nlmsg_get_payload_tail(nlh) - (void *)start; 2|ret = ipset_commit(session);向内核发送命令 3|ret = session-transport-query(session-handle,session-buffer,session-bufsize); 4| ipset_mnl_query(struct ipset_handle *handle, void *buffer, size_t len) 5|mnl_socket_sendto(handle-h, nlh, nlh-nlmsg_len) 5|ret = mnl_socket_recvfrom(handle-h, buffer, len); 6|ret = mnl_cb_run2(buffer, ret, 这个是libmnl库函数 handle-seq, handle-portid, handle-cb_ctlNLMSG_MIN_TYPE, handle-data, handle-cb_ctl, NLMSG_MIN_TYPE); 7| _mnl_cb_run() 8|遍历每个nlmsghdr消息 9| while (mnl_nlmsg_ok(nlh, len) 9| if (nlh-nlmsg_type = NLMSG_MIN_TYPE) list命令时调用 10| ret = cb_data(nlh, data); 9| nlh = mnl_nlmsg_next(nlh, &len);mnl_cb_run2()回调函数如下:static mnl_cb_t cb_ctl = NLMSG_NOOP = callback_noop,NLMSG_ERROR = callback_error,NLMSG_DONE = callback_done,NLMSG_OVERRUN = callback_noop,NLMSG_MIN_TYPE = callback_data,;IPSET_CMD_LIST命令调用callback_data(const struct nlmsghdr *nlh, void *data) 1| mnl_attr_parse(nlh, nfmsglen, cmd_attr_cb, nla)解析属性 1| callback_list(session, nla, cmd);2| ATTR2DATA(session, nla, IPSET_ATTR_SETNAME, cmd_attrs);2|ATTR2DATA(session, nla, IPSET_ATTR_FAMILY, cmd_attrs);2|ATTR2DATA(session, nla, IPSET_ATTR_TYPENAME, cmd_attrs);2|ATTR2DATA(session, nla, IPSET_ATTR_REVISION, cmd_attrs);2|if (nlaIPSET_ATTR_ADT != NULL)解析嵌套属性 3|mnl_attr_for_each_nested(tb, nlaIPSET_ATTR_ADT) 4|list_adt(session, adt) 5for (arg = type-argsIPSET_ADD; arg != NULL & arg-print; arg+) 6|safe_snprintf(session, %s , arg-name0); 6|safe_dprintf(session, arg-print, arg-opt);内核调用流程:Nfnetlink接收流程:nfnetlink_rcv_msg() 1|type = nlh-nlmsg_type; 1|ss = nfnetlink_get_subsys(type); 获得子系统结构 1|nc = nfnetlink_find_client(type, ss); 获得子系统回调函数 2|u_int8_t cb_id = NFNL_MSG_TYPE(type); 2|return &ss-cbcb_id; 1|err = nla_parse(cda, ss-cbcb_id.attr_count,attr, attrlen, ss-cbcb_id.policy); 1|err = nc-call(net-nfnl, skb, nlh, (const struct nlattr *)cda);调用相应回调函数IPSET_CMD_CREATE内核流程ip_set_create() 1|name = nla_data(attrIPSET_ATTR_SETNAME); 1|typename = nla_data(attrIPSET_ATTR_TYPENAME); 1|family = nla_get_u8(attrIPSET_ATTR_FAMILY); 1|evision = nla_get_u8(attrIPSET_ATTR_REVISION); 1|set = kzalloc(sizeof(struct ip_set), GFP_KERNEL); 1|ret = find_set_type_get(typename, family, revision, &(set-type); 2|*found = find_set_type(name, family, revision); 3|list_for_each_entry_rcu(type, &ip_set_type_list, list 1|nla_parse_nested(tb, IPSET_ATTR_CREATE_MAX, attrIPSET_ATTR_DATA, set-type-create_policy)解析选项嵌套属性 2|nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); 1|ret = set-type-create(set, tb, flags);调用集合类型回调函数 1|ret = find_free_id(set-name, &index, &clash)查找第一个空闲位置 2|for (i = 0; i variant-destroy(set);2|module_put(set-type-me);2|kfree(set);IPSET_CMD_ADD内核流程ip_set_uadd() 1|set = find_set(nla_data(attrIPSET_ATTR_SETNAME);查找集合 2|ip_set_id_t index = find_set_id(name); 2|return index = IPSET_INVALID_ID ? NULL : ip_set_listindex; 1|nla_parse_nested(tb, IPSET_ATTR_ADT_MAX, attrIPSET_ATTR_DATA, set-type-adt_policy) 解析选项嵌套属性 1|call_ad(ctnl, skb, set, tb, IPSET_ADD, flags,use_lineno);调用回调函数 2|ret = set-variant-uadt(set, tb, adt, &lineno, flags);Netfilter模块matches调用流程static struct xt_match set_matches _read_mostly = .name= set,.family= NFPROTO_IPV4,.revision= 0,.match= set_match_v0,.matchsize= sizeof(struct xt_set_info_match_v0),.checkentry= set_match_v0_checkentry,.destroy= set_match_v0_destroy,.me= THIS_MODULE,set_match_v0_checkentry(const struct xt_mtchk_param *par) 1|index = ip_set_nfnl_get_byindex(info-match_set.index);set_match_v0(const struct sk_buff *skb, con
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 健康咨询摆摊方案模板
- 咖啡馆营销策划方案
- 钢结构发泡保温施工方案
- 住宅建筑方案设计总说明
- 活动方案策划科技馆
- 户外拓展方案咨询
- 500人相亲活动方案策划
- 城市管理行业工艺流程与标准制定
- 2025国家电网安规变电部分考试题库与答案
- 房建工程外墙涂料开裂施工方案
- 中小学资助工作宣传与培训计划
- 2025年云南空港百事特商务有限公司招聘笔试参考题库含答案解析
- 向量的数量积说课
- 油气开采技术进步与挑战-洞察分析
- 小学生兴趣英语课件
- 【MOOC】国际金融学-湖南大学 中国大学慕课MOOC答案
- 九年级化学人教版基于特定需求设计和制作简易供氧器(教学设计)
- SCAMPER创新思维模型
- 乡镇庆中秋迎国庆活动方案
- 山东科学技术出版社小学一年级上册综合实践活动教案
- 港区泊位码头工程施工组织设计(图文)
评论
0/150
提交评论