huangcm
2025-02-24 69ed55dec4b2116a19e4cca4393cbc014fce5fb2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
 * Copyright (C)2003,2004 USAGI/WIDE Project
 *
 * Header for use in defining a given L3 protocol for connection tracking.
 *
 * Author:
 *    Yasuyuki Kozakai @USAGI    <yasuyuki.kozakai@toshiba.co.jp>
 *
 * Derived from include/netfilter_ipv4/ip_conntrack_protocol.h
 */
 
#ifndef _NF_CONNTRACK_L3PROTO_H
#define _NF_CONNTRACK_L3PROTO_H
#include <linux/netlink.h>
#include <net/netlink.h>
#include <linux/seq_file.h>
#include <net/netfilter/nf_conntrack.h>
 
struct nf_conntrack_l3proto {
   /* L3 Protocol Family number. ex) PF_INET */
   u_int16_t l3proto;
 
   /* Protocol name */
   const char *name;
 
   /*
    * Try to fill in the third arg: nhoff is offset of l3 proto
         * hdr.  Return true if possible.
    */
   bool (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int nhoff,
                struct nf_conntrack_tuple *tuple);
 
   /*
    * Invert the per-proto part of the tuple: ie. turn xmit into reply.
    * Some packets can't be inverted: return 0 in that case.
    */
   bool (*invert_tuple)(struct nf_conntrack_tuple *inverse,
                const struct nf_conntrack_tuple *orig);
 
   /* Print out the per-protocol part of the tuple. */
   void (*print_tuple)(struct seq_file *s,
               const struct nf_conntrack_tuple *);
 
   /*
    * Called before tracking. 
    *    *dataoff: offset of protocol header (TCP, UDP,...) in skb
    *    *protonum: protocol number
    */
   int (*get_l4proto)(const struct sk_buff *skb, unsigned int nhoff,
              unsigned int *dataoff, u_int8_t *protonum);
 
   int (*tuple_to_nlattr)(struct sk_buff *skb,
                  const struct nf_conntrack_tuple *t);
 
   /*
    * Calculate size of tuple nlattr
    */
   int (*nlattr_tuple_size)(void);
 
   int (*nlattr_to_tuple)(struct nlattr *tb[],
                  struct nf_conntrack_tuple *t);
   const struct nla_policy *nla_policy;
 
   size_t nla_size;
 
   /* Init l3proto pernet data */
   int (*init_net)(struct net *net);
 
   /* Module (if any) which this is connected to. */
   struct module *me;
};
 
extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX];
 
/* Protocol pernet registration. */
int nf_ct_l3proto_pernet_register(struct net *net,
                 struct nf_conntrack_l3proto *proto);
void nf_ct_l3proto_pernet_unregister(struct net *net,
                    struct nf_conntrack_l3proto *proto);
 
/* Protocol global registration. */
int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto);
void nf_ct_l3proto_unregister(struct nf_conntrack_l3proto *proto);
 
struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);
 
/* Existing built-in protocols */
extern struct nf_conntrack_l3proto nf_conntrack_l3proto_generic;
 
static inline struct nf_conntrack_l3proto *
__nf_ct_l3proto_find(u_int16_t l3proto)
{
   if (unlikely(l3proto >= AF_MAX))
       return &nf_conntrack_l3proto_generic;
   return rcu_dereference(nf_ct_l3protos[l3proto]);
}
 
#endif /*_NF_CONNTRACK_L3PROTO_H*/