Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Aug 2002 04:18:48 -0700 (PDT)
From:      Praveen Khurjekar <praveen@codito.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/42121: IP timestamp options processing 
Message-ID:  <200208281118.g7SBImkF022694@www.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         42121
>Category:       misc
>Synopsis:       IP timestamp options processing
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 28 04:20:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Praveen Khurjekar
>Release:        4.5
>Organization:
Codito Technologies
>Environment:
FreeBSD  4.5-RELEASE FreeBSD 4.5-RELEASE #0: Mon Jan 28 14:31:56 GMT 2002     murray@builder.freebsdmall.com:/usr/src/sys/compile/GENERIC  i386 
>Description:
Bug in IP options processing (timestamp with address ,timestamp
with prespecified address)

The stack doesnt seem to modify the IP header properly while 
processing packets with timestamp with address (IOPT_TS_TSANDADDR) 
and timestamp with prespecified address (IOPT_TS_PRESPEC) options.
the address of the system whose time stamp is to be recorded is being 
overwritten by the timestamp of the system in both the cases.


in the following ping outputs the timestamp of 192.168.1.174 (freebsd box) is written where its system address should have been written.timestamp remains zero.
[root@saturn root]# ping -c 2 -T tsandaddr 192.168.1.174
PING 192.168.1.174 (192.168.1.174) from 192.168.1.59 : 56(124) bytes of data.
64 bytes from 192.168.1.174: icmp_seq=0 ttl=64 time=36.125 msec
TS: 	192.168.1.59	38510053 absolute
	0.153.188.112	-38510053
	192.168.1.59	38510099 absolute

Warning: time of day goes back, taking countermeasures.
64 bytes from 192.168.1.174: icmp_seq=1 ttl=64 time=5.180 msec
TS: 	192.168.1.59	38511049 absolute
	0.153.192.78	-38511049
	192.168.1.59	38511054 absolute


--- 192.168.1.174 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/mdev = 5.180/20.652/36.125/15.473 ms

[root@saturn root]# ping -c 2 -T tsprespec 192.168.1.174  192.168.1.174
PING 192.168.1.174 (192.168.1.174) from 192.168.1.59 : 56(124) bytes of data.
Warning: time of day goes back, taking countermeasures.
64 bytes from 192.168.1.174: icmp_seq=0 ttl=64 time=4.672 msec
TS: 	0.159.112.67	0 absolute
Unrecorded hops: 1

64 bytes from 192.168.1.174: icmp_seq=1 ttl=64 time=3.241 msec
TS: 	0.159.116.43	0 absolute
Unrecorded hops: 1


--- 192.168.1.174 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/mdev = 3.241/3.956/4.672/0.718 ms

     
>How-To-Repeat:
ping freebsd host with timestamp options      
>Fix:
I think this could be corrected by increasing off by sizeof(struct in_addr)
in funtion ip_dooptions while processing IOPT_TS_TSANDADDR , IPOT_TS_PRESPEC
the following code is from freebsd 4.6 source

		case IPOPT_TS:
#ifdef IPSTEALTH
        	if (ipstealth && pass == 0)
			break;
#endif
                        code = cp - (u_char *)ip;
                        if (optlen < 4 || optlen > 40) {
                                code = &cp[IPOPT_OLEN] - (u_char *)ip;
                                goto bad;
                        }
                        if ((off = cp[IPOPT_OFFSET]) < 5) {
                                code = &cp[IPOPT_OLEN] - (u_char *)ip;
                                goto bad;
                        }
                        if (off > optlen - (int)sizeof(int32_t)) {
                                cp[IPOPT_OFFSET + 1] += (1 << 4);
                                if ((cp[IPOPT_OFFSET + 1] & 0xf0) == 0) {
                                        code = &cp[IPOPT_OFFSET] - (u_char *)ip;
                                        goto bad;
                                }
                                break;
                        }
                        off--;                          /* 0 origin */
                        sin = (struct in_addr *)(cp + off);
                        switch (cp[IPOPT_OFFSET + 1] & 0x0f) {

                        case IPOPT_TS_TSONLY:
                                break;

                        case IPOPT_TS_TSANDADDR:
                                if (off + sizeof(n_time) +
                                    sizeof(struct in_addr) > optlen) {
                                        code = &cp[IPOPT_OFFSET] - (u_char *)ip;
                                        goto bad;
                                }
                                ipaddr.sin_addr = dst;
                                ia = (INA)ifaof_ifpforaddr((SA)&ipaddr,
                                                            m->m_pkthdr.rcvif);
                                if (ia == 0)
                                        continue;
                                (void)memcpy(sin, &IA_SIN(ia)->sin_addr,
                                    sizeof(struct in_addr));
                                cp[IPOPT_OFFSET] += sizeof(struct in_addr);
change             -----------> off += sizeof(struct in_addr);
				break;


                         case IPOPT_TS_PRESPEC:
                                if (off + sizeof(n_time) +
                                    sizeof(struct in_addr) > optlen) {
                                        code = &cp[IPOPT_OFFSET] - (u_char *)ip;
                                        goto bad;
                                }
                                (void)memcpy(&ipaddr.sin_addr, sin,
                                    sizeof(struct in_addr));
                                if (ifa_ifwithaddr((SA)&ipaddr) == 0)
                                        continue;
                                cp[IPOPT_OFFSET] += sizeof(struct in_addr);
change             -----------> off += sizeof(struct in_addr);    
				break;

                        default:
                                code = &cp[IPOPT_OFFSET + 1] - (u_char *)ip;
                                goto bad;
                        }
                        ntime = iptime();
                        (void)memcpy(cp + off, &ntime, sizeof(n_time));
                        cp[IPOPT_OFFSET] += sizeof(n_time);
                }

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208281118.g7SBImkF022694>