Netfilter 连接跟踪与状态检测的实现(2)

2020-05-22 00:00:00 函数 连接 初始化 协议 数据包

5.resolve_normal_ct
        resolve_normal_ct 函数是连接跟踪中重要的函数之一,它的主要功能就是判断数据包在连接跟踪表是否存在,如果不存在,则为数据包分配相应的连接跟踪节点空间并初始化,然后设置连接状态:


  1. /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
  2. static inline struct ip_conntrack *
  3. resolve_normal_ct(struct sk_buff *skb,
  4.                   struct ip_conntrack_protocol *proto,
  5.                   int *set_reply,
  6.                   unsigned int hooknum,
  7.                   enum ip_conntrack_info *ctinfo)
  8. {
  9.         struct ip_conntrack_tuple tuple;
  10.         struct ip_conntrack_tuple_hash *h;
  11.         struct ip_conntrack *ct;

  12.         IP_NF_ASSERT((skb->nh.iph->frag_off & htons(IP_OFFSET)) == 0);

  13. /*前面提到过,需要将一个数据包转换成tuple,这个转换,就是通过ip_ct_get_tuple函数实现的*/
  14.         if (!ip_ct_get_tuple(skb->nh.iph, skb, skb->nh.iph->ihl*4, 
  15.                                 &tuple,proto))
  16.                 return NULL;

  17.         /*查看数据包对应的tuple在连接跟踪表中是否存在 */
  18.         h = ip_conntrack_find_get(&tuple, NULL);
  19.         if (!h) {
  20.                 /*如果不存在,初始化之*/
  21. h = init_conntrack(&tuple, proto, skb);
  22.                 if (!h)
  23.                         return NULL;
  24.                 if (IS_ERR(h))
  25.                         return (void *)h;
  26.         }
  27. /*根据hash表节点,取得数据包对应的连接跟踪结构*/
  28.         ct = tuplehash_to_ctrack(h);

  29.         /* 判断连接的方向 */
  30.         if (DIRECTION(h) == IP_CT_DIR_REPLY) {
  31.                 *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
  32.                 /* Please set reply bit if this packet OK */
  33.                 *set_reply = 1;
  34.         } else {
  35.                 /* Once we've had two way comms, always ESTABLISHED. */
  36.                 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
  37.                         DEBUGP("ip_conntrack_in: normal packet for %p\n",
  38.                                ct);
  39.                         *ctinfo = IP_CT_ESTABLISHED;
  40.                 } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
  41.                         DEBUGP("ip_conntrack_in: related packet for %p\n",
  42.                                ct);
  43.                         *ctinfo = IP_CT_RELATED;
  44.                 } else {
  45.                         DEBUGP("ip_conntrack_in: new packet for %p\n",
  46.                                ct);
  47.                         *ctinfo = IP_CT_NEW;
  48.                 }
  49.                 *set_reply = 0;
  50.         }
  51. /*设置skb的对应成员,如使用计数器、数据包状态标记*/
  52.         skb->nfct = &ct->ct_general;
  53.         skb->nfctinfo = *ctinfo;
  54.         return ct;
  55. }

相关文章