我们都用过iptables中的set mark功能吧。那么如果说我们自己希望在内核模块中为每一个内核模块添加一个mark,然后根据这个mark在用户态做一些处理呢?
对于如何写一个netfilter就不做过多解释了。
我们来看看如何打mark,如下,我们为tcp的去12345的端口每个连接添加一个mark值为0x12345.
unsigned int send_hook_func(void *priv, struct sk_buff *skb,const struct nf_hook_state *state)
{
struct iphdr *iph;
struct tcphdr *tcph = NULL;
unsigned int dport = 0;
if (!skb) {
return NF_ACCEPT;
}
iph = (struct iphdr *) skb_network_header(skb);
if (!iph) {
printk("no ip header\n");
return NF_ACCEPT;
}
if(iph->protocol == IPPROTO_TCP)
{
tcph = (struct tcphdr *) ((__u32 *) iph + iph->ihl);
dport = htons((unsigned short int)tcph->dest);
if (tcph->syn && dport == 12345)
{
printk("tcp dest port is:%d\n", dport);
skb->mark = 0x12345;
enum ip_conntrack_info ctinfo;
struct nf_conn *ct;
ct = nf_ct_get(skb, &ctinfo);
if(ct != NULL)
{
u_int32_t newmark;
newmark = 0x12345;
if (ct->mark != newmark) {
ct->mark = newmark;
nf_conntrack_event_cache(IPCT_MARK, ct);
}
}
}
}
return NF_ACCEPT;
}