summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/uipc_socket.c4
-rw-r--r--sys/kern/uipc_syscalls.c35
-rw-r--r--sys/netinet/udp_usrreq.c36
-rw-r--r--sys/sys/socket.h4
4 files changed, 64 insertions, 15 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 72a4567..b58eb51 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
- * $Id: uipc_socket.c,v 1.16 1996/03/11 15:37:31 davidg Exp $
+ * $Id: uipc_socket.c,v 1.17 1996/04/16 03:50:08 davidg Exp $
*/
#include <sys/param.h>
@@ -893,6 +893,7 @@ sosetopt(so, level, optname, m0)
case SO_REUSEADDR:
case SO_REUSEPORT:
case SO_OOBINLINE:
+ case SO_TIMESTAMP:
if (m == NULL || m->m_len < sizeof (int)) {
error = EINVAL;
goto bad;
@@ -1017,6 +1018,7 @@ sogetopt(so, level, optname, mp)
case SO_REUSEPORT:
case SO_BROADCAST:
case SO_OOBINLINE:
+ case SO_TIMESTAMP:
*mtod(m, int *) = so->so_options & optname;
break;
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index b366e94..6e17484 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94
- * $Id: uipc_syscalls.c,v 1.15 1996/02/24 13:38:07 phk Exp $
+ * $Id: uipc_syscalls.c,v 1.16 1996/03/11 15:37:33 davidg Exp $
*/
#include "opt_ktrace.h"
@@ -636,7 +636,8 @@ recvit(p, s, mp, namelenp, retsize)
register struct iovec *iov;
register int i;
int len, error;
- struct mbuf *from = 0, *control = 0;
+ struct mbuf *m, *from = 0, *control = 0;
+ caddr_t ctlbuf;
#ifdef KTRACE
struct iovec *ktriov = NULL;
#endif
@@ -735,17 +736,29 @@ recvit(p, s, mp, namelenp, retsize)
}
#endif
len = mp->msg_controllen;
- if (len <= 0 || control == 0)
- len = 0;
- else {
- if (len >= control->m_len)
- len = control->m_len;
- else
+ m = control;
+ mp->msg_controllen = 0;
+ ctlbuf = (caddr_t) mp->msg_control;
+
+ while (m && len > 0) {
+ unsigned int tocopy;
+
+ if (len >= m->m_len)
+ tocopy = m->m_len;
+ else {
mp->msg_flags |= MSG_CTRUNC;
- error = copyout((caddr_t)mtod(control, caddr_t),
- (caddr_t)mp->msg_control, (unsigned)len);
+ tocopy = len;
+ }
+
+ if (error = copyout((caddr_t)mtod(m, caddr_t),
+ ctlbuf, tocopy))
+ goto out;
+
+ ctlbuf += tocopy;
+ len -= tocopy;
+ m = m->m_next;
}
- mp->msg_controllen = len;
+ mp->msg_controllen = ctlbuf - mp->msg_control;
}
out:
if (from)
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index e2e52a9..e51b320 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95
- * $Id: udp_usrreq.c,v 1.24 1996/05/02 05:31:13 fenner Exp $
+ * $Id: udp_usrreq.c,v 1.25 1996/05/02 05:54:14 fenner Exp $
*/
#include <sys/param.h>
@@ -95,6 +95,7 @@ static int udp_output __P((struct inpcb *, struct mbuf *, struct mbuf *,
struct mbuf *));
static void udp_notify __P((struct inpcb *, int));
static struct mbuf *udp_saveopt __P((caddr_t, int, int));
+static struct mbuf *udp_timestamp __P((void));
void
udp_init()
@@ -304,9 +305,14 @@ udp_input(m, iphlen)
*/
udp_in.sin_port = uh->uh_sport;
udp_in.sin_addr = ip->ip_src;
- if (inp->inp_flags & INP_CONTROLOPTS) {
+ if (inp->inp_flags & INP_CONTROLOPTS
+ || inp->inp_socket->so_options & SO_TIMESTAMP) {
struct mbuf **mp = &opts;
+ if (inp->inp_socket->so_options & SO_TIMESTAMP) {
+ if (*mp = udp_timestamp())
+ mp = &(*mp)->m_next;
+ }
if (inp->inp_flags & INP_RECVDSTADDR) {
*mp = udp_saveopt((caddr_t) &ip->ip_dst,
sizeof(struct in_addr), IP_RECVDSTADDR);
@@ -373,6 +379,32 @@ udp_saveopt(p, size, type)
}
/*
+ * Create an mbuf with the SCM_TIMESTAMP socket option data (struct timeval)
+ * inside. This really isn't UDP specific; but there's not really a better
+ * place for it yet..
+ */
+static struct mbuf *
+udp_timestamp()
+{
+ register struct cmsghdr *cp;
+ struct mbuf *m;
+ struct timeval tv;
+
+ MGET(m, M_DONTWAIT, MT_CONTROL);
+ if (m == 0)
+ return (struct mbuf *) 0;
+
+ microtime(&tv);
+ cp = (struct cmsghdr *) mtod(m, struct cmsghdr *);
+ cp->cmsg_len =
+ m->m_len = sizeof(*cp) + sizeof(struct timeval);
+ cp->cmsg_level = SOL_SOCKET;
+ cp->cmsg_type = SCM_TIMESTAMP;
+ (void) memcpy(CMSG_DATA(cp), &tv, sizeof(struct timeval));
+ return (m);
+}
+
+/*
* Notify a udp user of an asynchronous error;
* just wake up so that he can collect error status.
*/
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index ed301e6..505a90f 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)socket.h 8.4 (Berkeley) 2/21/94
- * $Id: socket.h,v 1.9 1996/01/30 23:01:22 mpp Exp $
+ * $Id: socket.h,v 1.10 1996/02/07 16:19:02 wollman Exp $
*/
#ifndef _SYS_SOCKET_H_
@@ -63,6 +63,7 @@
#define SO_LINGER 0x0080 /* linger on close if data present */
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
+#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */
/*
* Additional options, not kept in so_options.
@@ -296,6 +297,7 @@ struct cmsghdr {
/* "Socket"-level control message types: */
#define SCM_RIGHTS 0x01 /* access rights (array of int) */
+#define SCM_TIMESTAMP 0x02 /* timestamp (struct timeval) */
/*
* 4.3 compat sockaddr, move to compat file later
OpenPOWER on IntegriCloud