aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2007-10-24 08:12:09 -0400
committerArnaldo Carvalho de Melo <acme@ghostprotocols.net>2007-10-24 08:12:09 -0400
commitfde20105f332614b23a3131d706cd90bdd7db72d (patch)
tree217c186a8c038a7a6d7bcc775081f9566b903e36
parent03cf786c4e83dba404ad23ca58f49147ae52dffd (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.h10
-rw-r--r--net/dccp/ipv4.c4
-rw-r--r--net/dccp/ipv6.c4
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
273static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb) 273static 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
279static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh) 278static 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
290static inline __u64 dccp_hdr_seq(const struct sk_buff *skb) 289static 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))