Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 102868
b: refs/heads/master
c: 7d5d552
h: refs/heads/master
v: v3
  • Loading branch information
YOSHIFUJI Hideaki committed Jun 11, 2008
1 parent e836e3b commit eaf05ee
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 74 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 81b302a321a0d99ff172b8cb2a8de17bff2f9499
refs/heads/master: 7d5d5525bd88313e6fd90c0659665aee5114bc2d
2 changes: 2 additions & 0 deletions trunk/include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ extern void tcp_parse_options(struct sk_buff *skb,
struct tcp_options_received *opt_rx,
int estab);

extern u8 *tcp_parse_md5sig_option(struct tcphdr *th);

/*
* TCP v4 functions exported for the inet6 API
*/
Expand Down
40 changes: 40 additions & 0 deletions trunk/net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -3450,6 +3450,43 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
return 1;
}

#ifdef CONFIG_TCP_MD5SIG
/*
* Parse MD5 Signature option
*/
u8 *tcp_parse_md5sig_option(struct tcphdr *th)
{
int length = (th->doff << 2) - sizeof (*th);
u8 *ptr = (u8*)(th + 1);

/* If the TCP option is too short, we can short cut */
if (length < TCPOLEN_MD5SIG)
return NULL;

while (length > 0) {
int opcode = *ptr++;
int opsize;

switch(opcode) {
case TCPOPT_EOL:
return NULL;
case TCPOPT_NOP:
length--;
continue;
default:
opsize = *ptr++;
if (opsize < 2 || opsize > length)
return NULL;
if (opcode == TCPOPT_MD5SIG)
return ptr;
}
ptr += opsize - 2;
length -= opsize;
}
return NULL;
}
#endif

static inline void tcp_store_ts_recent(struct tcp_sock *tp)
{
tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
Expand Down Expand Up @@ -5467,6 +5504,9 @@ EXPORT_SYMBOL(sysctl_tcp_ecn);
EXPORT_SYMBOL(sysctl_tcp_reordering);
EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
EXPORT_SYMBOL(tcp_parse_options);
#ifdef CONFIG_TCP_MD5SIG
EXPORT_SYMBOL(tcp_parse_md5sig_option);
#endif
EXPORT_SYMBOL(tcp_rcv_established);
EXPORT_SYMBOL(tcp_rcv_state_process);
EXPORT_SYMBOL(tcp_initialize_rcv_mss);
42 changes: 1 addition & 41 deletions trunk/net/ipv4/tcp_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1134,52 +1134,12 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)
struct tcp_md5sig_key *hash_expected;
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
int length = (th->doff << 2) - sizeof(struct tcphdr);
int genhash;
unsigned char *ptr;
unsigned char newhash[16];

hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr);
hash_location = tcp_parse_md5sig_option(th);

/*
* If the TCP option length is less than the TCP_MD5SIG
* option length, then we can shortcut
*/
if (length < TCPOLEN_MD5SIG) {
if (hash_expected)
return 1;
else
return 0;
}

/* Okay, we can't shortcut - we have to grub through the options */
ptr = (unsigned char *)(th + 1);
while (length > 0) {
int opcode = *ptr++;
int opsize;

switch (opcode) {
case TCPOPT_EOL:
goto done_opts;
case TCPOPT_NOP:
length--;
continue;
default:
opsize = *ptr++;
if (opsize < 2)
goto done_opts;
if (opsize > length)
goto done_opts;

if (opcode == TCPOPT_MD5SIG) {
hash_location = ptr;
goto done_opts;
}
}
ptr += opsize-2;
length -= opsize;
}
done_opts:
/* We've parsed the options - do we have a hash? */
if (!hash_expected && !hash_location)
return 0;
Expand Down
33 changes: 1 addition & 32 deletions trunk/net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,43 +844,12 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
struct tcp_md5sig_key *hash_expected;
struct ipv6hdr *ip6h = ipv6_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
int length = (th->doff << 2) - sizeof (*th);
int genhash;
u8 *ptr;
u8 newhash[16];

hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
hash_location = tcp_parse_md5sig_option(th);

/* If the TCP option is too short, we can short cut */
if (length < TCPOLEN_MD5SIG)
return hash_expected ? 1 : 0;

/* parse options */
ptr = (u8*)(th + 1);
while (length > 0) {
int opcode = *ptr++;
int opsize;

switch(opcode) {
case TCPOPT_EOL:
goto done_opts;
case TCPOPT_NOP:
length--;
continue;
default:
opsize = *ptr++;
if (opsize < 2 || opsize > length)
goto done_opts;
if (opcode == TCPOPT_MD5SIG) {
hash_location = ptr;
goto done_opts;
}
}
ptr += opsize - 2;
length -= opsize;
}

done_opts:
/* do we have a hash as expected? */
if (!hash_expected) {
if (!hash_location)
Expand Down

0 comments on commit eaf05ee

Please sign in to comment.