扩展netfilter中udp的contrack字段

最近遇到这样的一个问题:

在router背后有2台pc,通过dhcprelay的方式从外面的dhcpserver获取ip地址。

问题描述:

但是当地址租期到一定的时间后,两台pc会去发单播包续自己的ip地址。但是server回这些单播地址的时候,会把ack包回给第一台机器。第二台机器续包不成功之后,会发广播包出去,被router上面的dhcprelay进程处理,然后从外面的dhcpserver获得ip地址。该问题不影响功能使用

 

问题原因:

因为单播包,这两台pc建立了连线记录,期望relay的包的记录是一样的,所以这样会产生,这些relay会来的包都匹配了第一条连线记录,所以ack没有回到第二台机器。

 

解决办法:

为简单起见,可以扩展udp的连线记录字段,dhcp包有一个id字段是唯一的,在udp记录中增加id。

ip_conntrack_tuple结构体添加一个int变量xid。

+++ ip_conntrack_proto_udp.c 2009-10-13 14:23:09.000000000 +0800

@@ -5,6 +5,14 @@

 #include <linux/in.h>

 #include <linux/udp.h>

 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>

+struct bootp_hdr { /* BOOTP packet format */

+ u8 op; /* 1=request, 2=reply */

+ u8 htype; /* HW address type */

+ u8 hlen; /* HW address length */

+ u8 hops; /* Used only by gateways */

+ u32 xid; /* Transaction ID */

+ char *other;

+};

 

 

@@ -15,6 +23,7 @@ static int udp_pkt_to_tuple(const void *

 {

  const struct udphdr *hdr = datah;

+ struct bootp_hdr *bootp_h = (void *)hdr + 8;

 

+ if((ntohs(hdr->source) == 68)||(ntohs(hdr->dest) == 67)||(ntohs(hdr->source)==67)||(ntohs(hdr->dest)==68))

+ {

+ printk("in the %s the source port %d dest port %d./n",__FUNCTION__,ntohs(hdr->source),ntohs(hdr->dest));

+ if(NULL == bootp_h)

+ tuple->dst.u.udp.xid = 0;

+ else

+ tuple->dst.u.udp.xid = (unsigned int)(bootp_h->xid);

 

 

tuple->dst.u.udp.xid = orig->dst.u.udp.xid;

 

最后测试成功。

你可能感兴趣的:(扩展netfilter中udp的contrack字段)