From 4a64c3d2a1da648ab4c494647718414b9eb4102c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:25 -0500 Subject: [PATCH] Import 1.0.7 --- Makefile | 2 +- net/inet/icmp.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ net/inet/tcp.c | 10 ++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b91716ee1cfe..d4089b3419c0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 0 -SUBLEVEL = 6 +SUBLEVEL = 7 all: Version zImage diff --git a/net/inet/icmp.c b/net/inet/icmp.c index 51e6a05ef3fd..e1874f2cf372 100644 --- a/net/inet/icmp.c +++ b/net/inet/icmp.c @@ -285,6 +285,65 @@ icmp_echo(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, } +/* Handle ICMP Timestamp requests. */ +static void +icmp_timestamp(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, + unsigned long saddr, unsigned long daddr, int len, + struct options *opt) +{ + struct icmphdr *icmphr; + struct sk_buff *skb2; + int size, offset; + unsigned long *timeptr, midtime; + extern struct timeval xtime; /* kernel/time.c */ + + size = sizeof(struct sk_buff) + dev->hard_header_len + 64 + len; + if (! (skb2 = alloc_skb(size, GFP_ATOMIC))) { + skb->sk = NULL; + kfree_skb(skb, FREE_READ); + return; + } + skb2->sk = NULL; + skb2->mem_addr = skb2; + skb2->mem_len = size; + skb2->free = 1; + + /* Build Layer 2-3 headers for message back to source */ + offset = ip_build_header(skb2, daddr, saddr, &dev, IPPROTO_ICMP, opt, len, + skb->ip_hdr->tos, 255); + if (offset < 0) { + printk("ICMP: Could not build IP Header for ICMP TIMESTAMP Response\n"); + kfree_skb(skb2, FREE_WRITE); + skb->sk = NULL; + kfree_skb(skb, FREE_READ); + return; + } + + /* Re-adjust length according to actual IP header size. */ + skb2->len = offset + len; + + /* Build ICMP_TIMESTAMP Response message. */ + icmphr = (struct icmphdr *) ((char *) (skb2 + 1) + offset); + memcpy((char *) icmphr, (char *) icmph, len); + icmphr->type = ICMP_TIMESTAMPREPLY; + icmphr->code = icmphr->checksum = 0; + + /* fill in the current time as ms since midnight UT: */ + midtime = (xtime.tv_sec % 86400) * 1000 + xtime.tv_usec / 1000; + timeptr = (unsigned long *) (icmphr + 1); + /* the originate timestamp (timeptr [0]) is still in the copy: */ + timeptr [1] = timeptr [2] = htonl(midtime); + + icmphr->checksum = ip_compute_csum((unsigned char *) icmphr, len); + + /* Ship it out - free it when done */ + ip_queue_xmit((struct sock *) NULL, dev, skb2, 1); + + skb->sk = NULL; + kfree_skb(skb, FREE_READ); +} + + /* Handle the ICMP INFORMATION REQUEST. */ static void icmp_info(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev, @@ -400,6 +459,13 @@ icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt, skb1->sk = NULL; kfree_skb(skb1, FREE_READ); return(0); + case ICMP_TIMESTAMP: + icmp_timestamp(icmph, skb1, dev, saddr, daddr, len, opt); + return 0; + case ICMP_TIMESTAMPREPLY: + skb1->sk = NULL; + kfree_skb(skb1, FREE_READ); + return(0); case ICMP_INFO_REQUEST: icmp_info(icmph, skb1, dev, saddr, daddr, len, opt); return 0; diff --git a/net/inet/tcp.c b/net/inet/tcp.c index 260e2ad01c41..5d278dfda935 100644 --- a/net/inet/tcp.c +++ b/net/inet/tcp.c @@ -3404,6 +3404,16 @@ if (inet_debug == DBG_SLIP) printk("\rtcp_rcv: not in seq\n"); release_sock(sk); return(0); + case TCP_SYN_RECV: + if (th->syn) { + /* Probably a retransmitted syn */ + printk("syn while in TCP_SYN_RECV\n"); + kfree_skb(skb, FREE_READ); + release_sock(sk); + return(0); + } + + default: if (!tcp_sequence(sk, th, len, opt, saddr,dev)) { kfree_skb(skb, FREE_READ); -- 2.39.5