diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/sockfs/socksubr.c | 36 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/icmp.c | 36 | ||||
-rw-r--r-- | usr/src/uts/common/inet/ip/icmp_opt_data.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/inet/rawip_impl.h | 10 | ||||
-rw-r--r-- | usr/src/uts/common/inet/udp/udp.c | 38 | ||||
-rw-r--r-- | usr/src/uts/common/inet/udp/udp_opt_data.c | 9 | ||||
-rw-r--r-- | usr/src/uts/common/inet/udp_impl.h | 11 | ||||
-rw-r--r-- | usr/src/uts/common/sys/socket.h | 9 |
8 files changed, 132 insertions, 19 deletions
diff --git a/usr/src/uts/common/fs/sockfs/socksubr.c b/usr/src/uts/common/fs/sockfs/socksubr.c index 45a7959e1d..33bd2d699c 100644 --- a/usr/src/uts/common/fs/sockfs/socksubr.c +++ b/usr/src/uts/common/fs/sockfs/socksubr.c @@ -1652,6 +1652,42 @@ so_opt2cmsg(mblk_t *mp, void *opt, t_uscalar_t optlen, int oldflg, if (error != 0) return (error); } + } else if (tohp->level == SOL_SOCKET && + tohp->name == SCM_TIMESTAMP) { + timestruc_t *timestamp; + + if (oldflg) + continue; + + cmsg->cmsg_level = tohp->level; + cmsg->cmsg_type = tohp->name; + + timestamp = + (timestruc_t *)P2ROUNDUP((intptr_t)&tohp[1], + sizeof (intptr_t)); + + if (get_udatamodel() == DATAMODEL_NATIVE) { + struct timeval *time_native; + + cmsg->cmsg_len = sizeof (struct timeval) + + sizeof (struct cmsghdr); + time_native = + (struct timeval *)CMSG_CONTENT(cmsg); + time_native->tv_sec = timestamp->tv_sec; + time_native->tv_usec = + timestamp->tv_nsec / (NANOSEC / MICROSEC); + } else { + struct timeval32 *time32; + + cmsg->cmsg_len = sizeof (struct timeval32) + + sizeof (struct cmsghdr); + time32 = (struct timeval32 *)CMSG_CONTENT(cmsg); + time32->tv_sec = (time32_t)timestamp->tv_sec; + time32->tv_usec = + (int32_t)(timestamp->tv_nsec / + (NANOSEC / MICROSEC)); + } + } else { if (oldflg) continue; diff --git a/usr/src/uts/common/inet/ip/icmp.c b/usr/src/uts/common/inet/ip/icmp.c index 4dec0c7b4c..445b18f868 100644 --- a/usr/src/uts/common/inet/ip/icmp.c +++ b/usr/src/uts/common/inet/ip/icmp.c @@ -42,6 +42,7 @@ #include <sys/kmem.h> #include <sys/policy.h> #include <sys/zone.h> +#include <sys/time.h> #include <sys/socket.h> #include <sys/isa_defs.h> @@ -1508,6 +1509,9 @@ icmp_opt_get(queue_t *q, int level, int name, uchar_t *ptr) case SO_DGRAM_ERRIND: *i1 = icmp->icmp_dgram_errind; break; + case SO_TIMESTAMP: + *i1 = icmp->icmp_timestamp; + break; /* * Following three not meaningful for icmp * Action is same as "default" to which we fallthrough @@ -1957,6 +1961,11 @@ icmp_opt_set(queue_t *q, uint_t optset_context, int level, int name, if (!checkonly) icmp->icmp_dgram_errind = onoff; break; + case SO_TIMESTAMP: + if (!checkonly) { + icmp->icmp_timestamp = onoff; + } + break; /* * Following three not meaningful for icmp * Action is same as "default" so we keep them @@ -3068,6 +3077,16 @@ icmp_rput(queue_t *q, mblk_t *mp) udi_size += sizeof (struct T_opthdr) + sizeof (uint_t); } + /* + * If SO_TIMESTAMP is set allocate the appropriate sized + * buffer. Since gethrestime() expects a pointer aligned + * argument, we allocate space necessary for extra + * alignment (even though it might not be used). + */ + if (icmp->icmp_timestamp) { + udi_size += sizeof (struct T_opthdr) + + sizeof (timestruc_t) + _POINTER_ALIGNMENT; + } mp1 = allocb(udi_size, BPRI_MED); if (mp1 == NULL) { freemsg(mp); @@ -3118,6 +3137,23 @@ icmp_rput(queue_t *q, mblk_t *mp) freeb(options_mp); udi_size -= toh->len; } + if (icmp->icmp_timestamp) { + struct T_opthdr *toh; + + toh = (struct T_opthdr *)dstopt; + toh->level = SOL_SOCKET; + toh->name = SCM_TIMESTAMP; + toh->len = sizeof (struct T_opthdr) + + sizeof (timestruc_t) + _POINTER_ALIGNMENT; + toh->status = 0; + dstopt += sizeof (struct T_opthdr); + /* Align for gethrestime() */ + dstopt = (char *)P2ROUNDUP((intptr_t)dstopt, + sizeof (intptr_t)); + gethrestime((timestruc_t *)dstopt); + dstopt += sizeof (timestruc_t); + udi_size -= toh->len; + } /* Consumed all of allocated space */ ASSERT(udi_size == 0); diff --git a/usr/src/uts/common/inet/ip/icmp_opt_data.c b/usr/src/uts/common/inet/ip/icmp_opt_data.c index b1f83571f7..8ada45dc0c 100644 --- a/usr/src/uts/common/inet/ip/icmp_opt_data.c +++ b/usr/src/uts/common/inet/ip/icmp_opt_data.c @@ -85,6 +85,8 @@ opdes_t icmp_opt_arr[] = { { SO_RCVBUF, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 }, { SO_DGRAM_ERRIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 }, +{ SO_TIMESTAMP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 + }, { IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, (OP_PASSNEXT|OP_VARLEN|OP_NODEFAULT), diff --git a/usr/src/uts/common/inet/rawip_impl.h b/usr/src/uts/common/inet/rawip_impl.h index 42a4534304..5af03c3521 100644 --- a/usr/src/uts/common/inet/rawip_impl.h +++ b/usr/src/uts/common/inet/rawip_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -98,8 +97,9 @@ typedef struct icmp_s { icmp_restricted : 1, /* opened by non-privileged user */ icmp_ipv6_recvrtdstopts : 1, /* Obsolete IPV6_RECVRTHDRDSTOPTS */ icmp_old_ipv6_recvdstopts : 1, /* Old ver of IPV6_RECVDSTOPTS */ + icmp_timestamp : 1, /* SO_TIMESTAMP "socket" option */ - icmp_pad_to_bit_31: 9; + icmp_pad_to_bit_31: 8; uint8_t icmp_type_of_service; uint8_t icmp_ttl; /* TTL or hoplimit */ diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c index 9273d3dd92..16966452b1 100644 --- a/usr/src/uts/common/inet/udp/udp.c +++ b/usr/src/uts/common/inet/udp/udp.c @@ -35,6 +35,7 @@ const char udp_version[] = "%Z%%M% %I% %E% SMI"; #include <sys/stropts.h> #include <sys/strlog.h> #include <sys/strsun.h> +#include <sys/time.h> #define _SUN_TPI_VERSION 2 #include <sys/tihdr.h> #include <sys/timod.h> @@ -213,6 +214,7 @@ udp_stat_t udp_statistics = { { "udp_in_recvrthdr", KSTAT_DATA_UINT64 }, { "udp_in_recvpktinfo", KSTAT_DATA_UINT64 }, { "udp_in_recvtclass", KSTAT_DATA_UINT64 }, + { "udp_in_timestamp", KSTAT_DATA_UINT64 }, #ifdef DEBUG { "udp_data_conn", KSTAT_DATA_UINT64 }, { "udp_data_notconn", KSTAT_DATA_UINT64 }, @@ -2974,6 +2976,9 @@ udp_opt_get(queue_t *q, t_scalar_t level, t_scalar_t name, uchar_t *ptr) case SO_RECVUCRED: *i1 = udp->udp_recvucred; break; /* goto sizeof (int) option return */ + case SO_TIMESTAMP: + *i1 = udp->udp_timestamp; + break; default: return (-1); } @@ -3323,6 +3328,10 @@ udp_opt_set(queue_t *q, uint_t optset_context, int level, if (!checkonly) udp->udp_recvucred = onoff; break; + case SO_TIMESTAMP: + if (!checkonly) + udp->udp_timestamp = onoff; + break; default: *outlenp = 0; return (EINVAL); @@ -4374,7 +4383,17 @@ udp_input(conn_t *connp, mblk_t *mp) udi_size += sizeof (struct T_opthdr) + sizeof (uint8_t); UDP_STAT(udp_in_recvttl); } - + /* + * If SO_TIMESTAMP is set allocate the appropriate sized + * buffer. Since gethrestime() expects a pointer aligned + * argument, we allocate space necessary for extra + * alignment (even though it might not be used). + */ + if (udp->udp_timestamp) { + udi_size += sizeof (struct T_opthdr) + + sizeof (timestruc_t) + _POINTER_ALIGNMENT; + UDP_STAT(udp_in_timestamp); + } ASSERT(IPH_HDR_LENGTH((ipha_t *)rptr) == IP_SIMPLE_HDR_LENGTH); /* Allocate a message block for the T_UNITDATA_IND structure. */ @@ -4504,6 +4523,23 @@ udp_input(conn_t *connp, mblk_t *mp) dstopt += sizeof (uint8_t); udi_size -= toh->len; } + if (udp->udp_timestamp) { + struct T_opthdr *toh; + + toh = (struct T_opthdr *)dstopt; + toh->level = SOL_SOCKET; + toh->name = SCM_TIMESTAMP; + toh->len = sizeof (struct T_opthdr) + + sizeof (timestruc_t) + _POINTER_ALIGNMENT; + toh->status = 0; + dstopt += sizeof (struct T_opthdr); + /* Align for gethrestime() */ + dstopt = (char *)P2ROUNDUP((intptr_t)dstopt, + sizeof (intptr_t)); + gethrestime((timestruc_t *)dstopt); + dstopt += sizeof (timestruc_t); + udi_size -= toh->len; + } /* Consumed all of allocated space */ ASSERT(udi_size == 0); diff --git a/usr/src/uts/common/inet/udp/udp_opt_data.c b/usr/src/uts/common/inet/udp/udp_opt_data.c index 328f2cb44b..df3f224eb8 100644 --- a/usr/src/uts/common/inet/udp/udp_opt_data.c +++ b/usr/src/uts/common/inet/udp/udp_opt_data.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -81,6 +80,8 @@ opdes_t udp_opt_arr[] = { 0 }, { SO_RECVUCRED, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 }, +{ SO_TIMESTAMP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, OP_PASSNEXT, sizeof (int), 0 + }, { IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, (OP_PASSNEXT|OP_VARLEN|OP_NODEFAULT), 40, -1 /* not initialized */ }, { T_IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, diff --git a/usr/src/uts/common/inet/udp_impl.h b/usr/src/uts/common/inet/udp_impl.h index 66faf934a8..b943dcdccd 100644 --- a/usr/src/uts/common/inet/udp_impl.h +++ b/usr/src/uts/common/inet/udp_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -122,7 +121,8 @@ typedef struct udp_s { udp_issocket : 1, /* socket mode */ udp_direct_sockfs : 1, /* direct calls to/from sockfs */ - udp_pad_to_bit_31 : 4; + udp_timestamp : 1, /* SO_TIMESTAMP "socket" option */ + udp_pad_to_bit_31 : 3; uint8_t udp_type_of_service; /* IP_TOS option */ uint8_t udp_ttl; /* TTL or hoplimit */ @@ -210,6 +210,7 @@ typedef struct { /* Class "net" kstats */ kstat_named_t udp_in_recvrthdr; kstat_named_t udp_in_recvpktinfo; kstat_named_t udp_in_recvtclass; + kstat_named_t udp_in_timestamp; #ifdef DEBUG kstat_named_t udp_data_conn; kstat_named_t udp_data_notconn; diff --git a/usr/src/uts/common/sys/socket.h b/usr/src/uts/common/sys/socket.h index b31bcbed66..18acac99b0 100644 --- a/usr/src/uts/common/sys/socket.h +++ b/usr/src/uts/common/sys/socket.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -149,6 +148,8 @@ typedef void *_RESTRICT_KYWD Psocklen_t; #define SO_SECATTR 0x1011 /* socket's security attributes */ #define SCM_UCRED 0x1012 /* sender's ucred */ +#define SO_TIMESTAMP 0x1013 /* socket-level timestamp option */ +#define SCM_TIMESTAMP SO_TIMESTAMP /* socket control message timestamp */ #ifdef _KERNEL #define SO_SRCADDR 0x2001 /* Internal: AF_UNIX source address */ |