From 82571026b9771c4035b0c62abbbe588fe73373ea Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 24 Oct 2006 15:18:36 -0700 Subject: [PATCH 1/6] [IPV4] ipconfig: fix RARP ic_servaddr breakage memcpy 4 bytes to address of auto unsigned long variable followed by comparison with u32 is a bloody bad idea. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- net/ipv4/ipconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f8ce84759159..955a07abb91d 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -420,7 +420,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt { struct arphdr *rarp; unsigned char *rarp_ptr; - unsigned long sip, tip; + u32 sip, tip; unsigned char *sha, *tha; /* s for "source", t for "target" */ struct ic_device *d; From 2fab22f2d3290ff7c602fe62f22e825c48e97a06 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 24 Oct 2006 15:34:00 -0700 Subject: [PATCH 2/6] [XFRM]: Fix xfrm_state accounting xfrm_state_num needs to be increased for XFRM_STATE_ACQ states created by xfrm_state_find() to prevent the counter from going negative when the state is destroyed. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/xfrm/xfrm_state.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 84bbf8474f3e..899de9ed22a6 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -505,6 +505,14 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) x->id.proto, family); } +static void xfrm_hash_grow_check(int have_hash_collision) +{ + if (have_hash_collision && + (xfrm_state_hmask + 1) < xfrm_state_hashmax && + xfrm_state_num > xfrm_state_hmask) + schedule_work(&xfrm_hash_work); +} + struct xfrm_state * xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, struct flowi *fl, struct xfrm_tmpl *tmpl, @@ -598,6 +606,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; add_timer(&x->timer); + xfrm_state_num++; + xfrm_hash_grow_check(x->bydst.next != NULL); } else { x->km.state = XFRM_STATE_DEAD; xfrm_state_put(x); @@ -614,14 +624,6 @@ out: return x; } -static void xfrm_hash_grow_check(int have_hash_collision) -{ - if (have_hash_collision && - (xfrm_state_hmask + 1) < xfrm_state_hashmax && - xfrm_state_num > xfrm_state_hmask) - schedule_work(&xfrm_hash_work); -} - static void __xfrm_state_insert(struct xfrm_state *x) { unsigned int h; From 51d8b1a65291a6956b79374b6adbbadc2263bcf6 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 24 Oct 2006 16:14:04 -0700 Subject: [PATCH 3/6] [NETFILTER]: Fix ip6_tables protocol bypass bug As reported by Mark Dowd , ip6_tables is susceptible to a fragmentation attack causing false negatives on protocol matches. When the protocol header doesn't follow the fragment header immediately, the fragment header contains the protocol number of the next extension header. When the extension header and the protocol header are sent in a second fragment a rule like "ip6tables .. -p udp -j DROP" will never match. Drop fragments that are at offset 0 and don't contain the final protocol header regardless of the ruleset, since this should not happen normally. With help from Yasuyuki KOZAKAI . Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6_tables.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 4ab368fa0b8f..f0328c7bc1c9 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -111,7 +111,7 @@ ip6_packet_match(const struct sk_buff *skb, const char *outdev, const struct ip6t_ip6 *ip6info, unsigned int *protoff, - int *fragoff) + int *fragoff, int *hotdrop) { size_t i; unsigned long ret; @@ -169,9 +169,11 @@ ip6_packet_match(const struct sk_buff *skb, unsigned short _frag_off; protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); - if (protohdr < 0) + if (protohdr < 0) { + if (_frag_off == 0) + *hotdrop = 1; return 0; - + } *fragoff = _frag_off; dprintf("Packet protocol %hi ?= %s%hi.\n", @@ -290,7 +292,7 @@ ip6t_do_table(struct sk_buff **pskb, IP_NF_ASSERT(e); IP_NF_ASSERT(back); if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, - &protoff, &offset)) { + &protoff, &offset, &hotdrop)) { struct ip6t_entry_target *t; if (IP6T_MATCH_ITERATE(e, do_match, From 6d381634d213580d40d431e7664dfb45f641b884 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 24 Oct 2006 16:15:10 -0700 Subject: [PATCH 4/6] [NETFILTER]: Fix ip6_tables extension header bypass bug As reported by Mark Dowd , ip6_tables is susceptible to a fragmentation attack causing false negatives on extension header matches. When extension headers occur in the non-first fragment after the fragment header (possibly with an incorrect nexthdr value in the fragment header) a rule looking for this extension header will never match. Drop fragments that are at offset 0 and don't contain the final protocol header regardless of the ruleset, since this should not happen normally. Since all extension headers are before the protocol header this makes sure an extension header is either not present or in the first fragment, where we can properly parse it. With help from Yasuyuki KOZAKAI . Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6_tables.c | 11 +++++++---- net/ipv6/netfilter/ip6t_ah.c | 7 ++++++- net/ipv6/netfilter/ip6t_frag.c | 7 ++++++- net/ipv6/netfilter/ip6t_hbh.c | 7 ++++++- net/ipv6/netfilter/ip6t_rt.c | 7 ++++++- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f0328c7bc1c9..53bf977cca63 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1440,6 +1440,9 @@ static void __exit ip6_tables_fini(void) * If target header is found, its offset is set in *offset and return protocol * number. Otherwise, return -1. * + * If the first fragment doesn't contain the final protocol header or + * NEXTHDR_NONE it is considered invalid. + * * Note that non-1st fragment is special case that "the protocol number * of last header" is "next header" field in Fragment header. In this case, * *offset is meaningless and fragment offset is stored in *fragoff if fragoff @@ -1463,12 +1466,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { if (target < 0) break; - return -1; + return -ENOENT; } hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); if (hp == NULL) - return -1; + return -EBADMSG; if (nexthdr == NEXTHDR_FRAGMENT) { unsigned short _frag_off, *fp; fp = skb_header_pointer(skb, @@ -1477,7 +1480,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, sizeof(_frag_off), &_frag_off); if (fp == NULL) - return -1; + return -EBADMSG; _frag_off = ntohs(*fp) & ~0x7; if (_frag_off) { @@ -1488,7 +1491,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, *fragoff = _frag_off; return hp->nexthdr; } - return -1; + return -ENOENT; } hdrlen = 8; } else if (nexthdr == NEXTHDR_AUTH) diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index ec1b1608156c..46486645eb75 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c @@ -54,9 +54,14 @@ match(const struct sk_buff *skb, const struct ip6t_ah *ahinfo = matchinfo; unsigned int ptr; unsigned int hdrlen = 0; + int err; - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0) + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); + if (err < 0) { + if (err != -ENOENT) + *hotdrop = 1; return 0; + } ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); if (ah == NULL) { diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 78d9c8b9e28a..cd22eaaccdca 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c @@ -52,9 +52,14 @@ match(const struct sk_buff *skb, struct frag_hdr _frag, *fh; const struct ip6t_frag *fraginfo = matchinfo; unsigned int ptr; + int err; - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); + if (err < 0) { + if (err != -ENOENT) + *hotdrop = 1; return 0; + } fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); if (fh == NULL) { diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index d32a205e3af2..3f25babe0440 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c @@ -65,9 +65,14 @@ match(const struct sk_buff *skb, u8 _opttype, *tp = NULL; u8 _optlen, *lp = NULL; unsigned int optlen; + int err; - if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0) + err = ipv6_find_hdr(skb, &ptr, match->data, NULL); + if (err < 0) { + if (err != -ENOENT) + *hotdrop = 1; return 0; + } oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); if (oh == NULL) { diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index bcb2e168a5bc..54d7d14134fd 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c @@ -58,9 +58,14 @@ match(const struct sk_buff *skb, unsigned int hdrlen = 0; unsigned int ret = 0; struct in6_addr *ap, _addr; + int err; - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0) + err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); + if (err < 0) { + if (err != -ENOENT) + *hotdrop = 1; return 0; + } rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); if (rh == NULL) { From 977a415f2b70b5693aaa23b1a16ad57ea20a1dce Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 24 Oct 2006 16:16:39 -0700 Subject: [PATCH 5/6] [ATM] horizon: read_bia() needs to be __devinit Thanks to Randy Dunlap. Signed-off-by: David S. Miller --- drivers/atm/horizon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 44268cba5a5a..4dc10105d610 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -1789,7 +1789,7 @@ static inline void CLOCK_IT (const hrz_dev *dev, u32 ctrl) WRITE_IT_WAIT(dev, ctrl | SEEPROM_SK); } -static u16 __init read_bia (const hrz_dev * dev, u16 addr) +static u16 __devinit read_bia (const hrz_dev * dev, u16 addr) { u32 ctrl = rd_regl (dev, CONTROL_0_REG); From 0e64e94e477f8ed04e9295b11a5898d443c28a47 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 24 Oct 2006 16:17:51 -0700 Subject: [PATCH 6/6] [DCCP]: Update documentation references. Updates the references to spec documents throughout the code, taking into account that * the DCCP, CCID 2, and CCID 3 drafts all became RFCs in March this year * RFC 1063 was obsoleted by RFC 1191 * draft-ietf-tcpimpl-pmtud-0x.txt was published as an Informational RFC, RFC 2923 on 2000-09-22. All references verified. Signed-off-by: Gerrit Renker Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/dccp/Kconfig | 6 +++--- net/dccp/ackvec.c | 12 ++++++------ net/dccp/ackvec.h | 3 +-- net/dccp/ccids/Kconfig | 17 ++++++++--------- net/dccp/ccids/ccid2.c | 2 +- net/dccp/ccids/ccid3.c | 3 +-- net/dccp/dccp.h | 2 +- net/dccp/input.c | 4 ++-- net/dccp/ipv4.c | 4 ++-- net/dccp/ipv6.c | 2 +- net/dccp/options.c | 2 +- 11 files changed, 27 insertions(+), 30 deletions(-) diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig index e2a095d0fd80..ef8919cca74b 100644 --- a/net/dccp/Kconfig +++ b/net/dccp/Kconfig @@ -4,15 +4,15 @@ menu "DCCP Configuration (EXPERIMENTAL)" config IP_DCCP tristate "The DCCP Protocol (EXPERIMENTAL)" ---help--- - Datagram Congestion Control Protocol + Datagram Congestion Control Protocol (RFC 4340) - From draft-ietf-dccp-spec-11 . + From http://www.ietf.org/rfc/rfc4340.txt: The Datagram Congestion Control Protocol (DCCP) is a transport protocol that implements bidirectional, unicast connections of congestion-controlled, unreliable datagrams. It should be suitable for use by applications such as streaming media, Internet telephony, - and on-line games + and on-line games. To compile this protocol support as a module, choose M here: the module will be called dccp. diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index 4d176d33983f..f8208874ac7d 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -113,7 +113,7 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) memcpy(to, from, len); /* - * From draft-ietf-dccp-spec-11.txt: + * From RFC 4340, A.2: * * For each acknowledgement it sends, the HC-Receiver will add an * acknowledgement record. ack_seqno will equal the HC-Receiver @@ -224,7 +224,7 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av, } /* - * Implements the draft-ietf-dccp-spec-11.txt Appendix A + * Implements the RFC 4340, Appendix A */ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, const u64 ackno, const u8 state) @@ -237,7 +237,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, * We may well decide to do buffer compression, etc, but for now lets * just drop. * - * From Appendix A: + * From Appendix A.1.1 (`New Packets'): * * Of course, the circular buffer may overflow, either when the * HC-Sender is sending data at a very high rate, when the @@ -274,9 +274,9 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, /* * A.1.2. Old Packets * - * When a packet with Sequence Number S arrives, and - * S <= buf_ackno, the HC-Receiver will scan the table - * for the byte corresponding to S. (Indexing structures + * When a packet with Sequence Number S <= buf_ackno + * arrives, the HC-Receiver will scan the table for + * the byte corresponding to S. (Indexing structures * could reduce the complexity of this scan.) */ u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h index 2424effac7f6..cf8f20ce23a9 100644 --- a/net/dccp/ackvec.h +++ b/net/dccp/ackvec.h @@ -28,8 +28,7 @@ /** struct dccp_ackvec - ack vector * - * This data structure is the one defined in the DCCP draft - * Appendix A. + * This data structure is the one defined in RFC 4340, Appendix A. * * @dccpav_buf_head - circular buffer head * @dccpav_buf_tail - circular buffer tail diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig index 32752f750447..8533dabfb9f8 100644 --- a/net/dccp/ccids/Kconfig +++ b/net/dccp/ccids/Kconfig @@ -22,11 +22,11 @@ config IP_DCCP_CCID2 for lost packets, would prefer CCID 2 to CCID 3. On-line games may also prefer CCID 2. - CCID 2 is further described in: - http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid2-10.txt + CCID 2 is further described in RFC 4341, + http://www.ietf.org/rfc/rfc4341.txt - This text was extracted from: - http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt + This text was extracted from RFC 4340 (sec. 10.1), + http://www.ietf.org/rfc/rfc4340.txt If in doubt, say M. @@ -53,15 +53,14 @@ config IP_DCCP_CCID3 suitable than CCID 2 for applications such streaming media where a relatively smooth sending rate is of importance. - CCID 3 is further described in: - - http://www.icir.org/kohler/dccp/draft-ietf-dccp-ccid3-11.txt. + CCID 3 is further described in RFC 4342, + http://www.ietf.org/rfc/rfc4342.txt The TFRC congestion control algorithms were initially described in RFC 3448. - This text was extracted from: - http://www.icir.org/kohler/dccp/draft-ietf-dccp-spec-13.txt + This text was extracted from RFC 4340 (sec. 10.2), + http://www.ietf.org/rfc/rfc4340.txt If in doubt, say M. diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 2efb505aeb35..2fbb84bf4e26 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -23,7 +23,7 @@ */ /* - * This implementation should follow: draft-ietf-dccp-ccid2-10.txt + * This implementation should follow RFC 4341 * * BUGS: * - sequence number wrapping diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 67d2dc0e7c67..cec23ad286de 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -379,8 +379,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) packet->dccphtx_seqno = dp->dccps_gss; /* * Check if win_count have changed - * Algorithm in "8.1. Window Counter Valuer" in - * draft-ietf-dccp-ccid3-11.txt + * Algorithm in "8.1. Window Counter Value" in RFC 4342. */ quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count); if (likely(hctx->ccid3hctx_rtt > 8)) diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 0a21be437ed3..272e8584564e 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -50,7 +50,7 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo); #define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT * state, about 60 seconds */ -/* draft-ietf-dccp-spec-11.txt initial RTO value */ +/* RFC 1122, 4.2.3.1 initial RTO value */ #define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ)) /* Maximal interval between probes for local resources. */ diff --git a/net/dccp/input.c b/net/dccp/input.c index 7f9dc6ac58c9..1d24881ac0ab 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -216,11 +216,11 @@ send_sync: dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNCACK); /* - * From the draft: + * From RFC 4340, sec. 5.7 * * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets * MAY have non-zero-length application data areas, whose - * contents * receivers MUST ignore. + * contents receivers MUST ignore. */ goto discard; } diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index aaaf4d09516b..e08e7688a263 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -183,7 +183,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk, dccp_sync_mss(sk, mtu); /* - * From: draft-ietf-dccp-spec-11.txt + * From RFC 4340, sec. 14.1: * * DCCP-Sync packets are the best choice for upward * probing, since DCCP-Sync probes do not risk application @@ -733,7 +733,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) dccp_hdr_reset(skb)->dccph_reset_code = DCCP_SKB_CB(rxskb)->dccpd_reset_code; - /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */ + /* See "8.3.1. Abnormal Termination" in RFC 4340 */ seqno = 0; if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index c8bf89bfb088..eb0ff7ab05ed 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -550,7 +550,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb) dccp_hdr_reset(skb)->dccph_reset_code = DCCP_SKB_CB(rxskb)->dccpd_reset_code; - /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */ + /* See "8.3.1. Abnormal Termination" in RFC 4340 */ seqno = 0; if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); diff --git a/net/dccp/options.c b/net/dccp/options.c index 07a34696ac97..fb0db1f7cd7b 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -215,7 +215,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) elapsed_time); break; /* - * From draft-ietf-dccp-spec-11.txt: + * From RFC 4340, sec. 10.3: * * Option numbers 128 through 191 are for * options sent from the HC-Sender to the