diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2007-10-24 08:12:09 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2007-10-24 08:12:09 -0400 |
commit | fde20105f332614b23a3131d706cd90bdd7db72d (patch) | |
tree | 217c186a8c038a7a6d7bcc775081f9566b903e36 | |
parent | 03cf786c4e83dba404ad23ca58f49147ae52dffd (diff) |
[DCCP]: Retrieve packet sequence number for error reporting
This fixes a problem when analysing erroneous packets in dccp_v{4,6}_err:
* dccp_hdr_seq currently takes an skb
* however, the transport headers in the skb are shifted, due to the
preceding IPv4/v6 header.
Fixed for v4 and v6 by changing dccp_hdr_seq to take a struct dccp_hdr as
argument. Verified that the correct sequence number is now reported in the
error handler.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | include/linux/dccp.h | 10 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 4 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 4 |
3 files changed, 8 insertions, 10 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h index f3fc4392e93d..55d28cb97596 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h | |||
@@ -270,10 +270,9 @@ static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen) | |||
270 | return memset(skb_transport_header(skb), 0, headlen); | 270 | return memset(skb_transport_header(skb), 0, headlen); |
271 | } | 271 | } |
272 | 272 | ||
273 | static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb) | 273 | static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh) |
274 | { | 274 | { |
275 | return (struct dccp_hdr_ext *)(skb_transport_header(skb) + | 275 | return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh)); |
276 | sizeof(struct dccp_hdr)); | ||
277 | } | 276 | } |
278 | 277 | ||
279 | static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh) | 278 | static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh) |
@@ -287,13 +286,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb) | |||
287 | return __dccp_basic_hdr_len(dh); | 286 | return __dccp_basic_hdr_len(dh); |
288 | } | 287 | } |
289 | 288 | ||
290 | static inline __u64 dccp_hdr_seq(const struct sk_buff *skb) | 289 | static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh) |
291 | { | 290 | { |
292 | const struct dccp_hdr *dh = dccp_hdr(skb); | ||
293 | __u64 seq_nr = ntohs(dh->dccph_seq); | 291 | __u64 seq_nr = ntohs(dh->dccph_seq); |
294 | 292 | ||
295 | if (dh->dccph_x != 0) | 293 | if (dh->dccph_x != 0) |
296 | seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low); | 294 | seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low); |
297 | else | 295 | else |
298 | seq_nr += (u32)dh->dccph_seq2 << 16; | 296 | seq_nr += (u32)dh->dccph_seq2 << 16; |
299 | 297 | ||
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 222549ab274a..3f1578db93e8 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -241,7 +241,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) | |||
241 | goto out; | 241 | goto out; |
242 | 242 | ||
243 | dp = dccp_sk(sk); | 243 | dp = dccp_sk(sk); |
244 | seq = dccp_hdr_seq(skb); | 244 | seq = dccp_hdr_seq(dh); |
245 | if (sk->sk_state != DCCP_LISTEN && | 245 | if (sk->sk_state != DCCP_LISTEN && |
246 | !between48(seq, dp->dccps_swl, dp->dccps_swh)) { | 246 | !between48(seq, dp->dccps_swl, dp->dccps_swh)) { |
247 | NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); | 247 | NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); |
@@ -795,7 +795,7 @@ static int dccp_v4_rcv(struct sk_buff *skb) | |||
795 | 795 | ||
796 | dh = dccp_hdr(skb); | 796 | dh = dccp_hdr(skb); |
797 | 797 | ||
798 | DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); | 798 | DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); |
799 | DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; | 799 | DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; |
800 | 800 | ||
801 | dccp_pr_debug("%8.8s " | 801 | dccp_pr_debug("%8.8s " |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index bbadd6681b83..62428ff137dd 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -173,7 +173,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
173 | 173 | ||
174 | icmpv6_err_convert(type, code, &err); | 174 | icmpv6_err_convert(type, code, &err); |
175 | 175 | ||
176 | seq = DCCP_SKB_CB(skb)->dccpd_seq; | 176 | seq = dccp_hdr_seq(dh); |
177 | /* Might be for an request_sock */ | 177 | /* Might be for an request_sock */ |
178 | switch (sk->sk_state) { | 178 | switch (sk->sk_state) { |
179 | struct request_sock *req, **prev; | 179 | struct request_sock *req, **prev; |
@@ -787,7 +787,7 @@ static int dccp_v6_rcv(struct sk_buff *skb) | |||
787 | 787 | ||
788 | dh = dccp_hdr(skb); | 788 | dh = dccp_hdr(skb); |
789 | 789 | ||
790 | DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); | 790 | DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); |
791 | DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; | 791 | DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; |
792 | 792 | ||
793 | if (dccp_packet_without_ack(skb)) | 793 | if (dccp_packet_without_ack(skb)) |