diff --git a/doc/changelog.txt b/doc/changelog.txt index f8826c7..9ee6d9f 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -3,6 +3,8 @@ HEAD ==== - xt_TARPIT: fix kernel warning about RTAX_HOPLIMIT being used - xt_TEE: abort build when the feature is already provided by mainline +- xt_psd: restore functionality with UDP +- xt_psd: support UDPLITE v1.37 (2011-06-25) diff --git a/extensions/xt_psd.c b/extensions/xt_psd.c index 59e3780..46b2831 100644 --- a/extensions/xt_psd.c +++ b/extensions/xt_psd.c @@ -103,8 +103,12 @@ static bool xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match) { const struct iphdr *iph; - const struct tcphdr *tcph; - struct tcphdr _tcph; + const struct tcphdr *tcph = NULL; + const struct udphdr *udph; + union { + struct tcphdr tcph; + struct udphdr udph; + } _buf; struct in_addr addr; u_int16_t src_port,dest_port; u_int8_t tcp_flags, proto; @@ -125,29 +129,9 @@ xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match) /* TCP or UDP ? */ proto = iph->protocol; - - if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) { - pr_debug("protocol not supported\n"); - return false; - } - /* Get the source address, source & destination ports, and TCP flags */ addr.s_addr = iph->saddr; - - tcph = skb_header_pointer(pskb, match->thoff, sizeof(_tcph), &_tcph); - if (tcph == NULL) - return false; - - /* Yep, it's dirty */ - src_port = tcph->source; - dest_port = tcph->dest; - - if (proto == IPPROTO_TCP) - tcp_flags = *((u_int8_t*)tcph + 13); - else - tcp_flags = 0x00; - /* We're using IP address 0.0.0.0 for a special purpose here, so don't let * them spoof us. [DHCP needs this feature - HW] */ if (addr.s_addr == 0) { @@ -155,6 +139,29 @@ xt_psd_match(const struct sk_buff *pskb, struct xt_action_param *match) return false; } + if (proto == IPPROTO_TCP) { + tcph = skb_header_pointer(pskb, match->thoff, + sizeof(_buf.tcph), &_buf.tcph); + if (tcph == NULL) + return false; + + /* Yep, it's dirty */ + src_port = tcph->source; + dest_port = tcph->dest; + tcp_flags = *((u_int8_t*)tcph + 13); + } else if (proto == IPPROTO_UDP || proto == IPPROTO_UDPLITE) { + udph = skb_header_pointer(pskb, match->thoff, + sizeof(_buf.udph), &_buf.udph); + if (udph == NULL) + return false; + src_port = udph->source; + dest_port = udph->dest; + tcp_flags = 0; + } else { + pr_debug("protocol not supported\n"); + return false; + } + /* Use jiffies here not to depend on someone setting the time while we're * running; we need to be careful with possible return value overflows. */ now = jiffies;