summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/sockfs/socksubr.c36
-rw-r--r--usr/src/uts/common/inet/ip/icmp.c36
-rw-r--r--usr/src/uts/common/inet/ip/icmp_opt_data.c2
-rw-r--r--usr/src/uts/common/inet/rawip_impl.h10
-rw-r--r--usr/src/uts/common/inet/udp/udp.c38
-rw-r--r--usr/src/uts/common/inet/udp/udp_opt_data.c9
-rw-r--r--usr/src/uts/common/inet/udp_impl.h11
-rw-r--r--usr/src/uts/common/sys/socket.h9
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 */