diff options
author | wollman <wollman@FreeBSD.org> | 1996-05-09 20:15:26 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1996-05-09 20:15:26 +0000 |
commit | 9ea36adbecaec6093c2c6769fbc0e405e5618487 (patch) | |
tree | b2796b2139f8fbb109be2d52262cfb5aa78d7df7 /sys/netinet/udp_usrreq.c | |
parent | 86058739b95ae00ed08a591f6e8001326915086f (diff) | |
download | FreeBSD-src-9ea36adbecaec6093c2c6769fbc0e405e5618487.zip FreeBSD-src-9ea36adbecaec6093c2c6769fbc0e405e5618487.tar.gz |
Make it possible to return more than one piece of control information
(PR #1178).
Define a new SO_TIMESTAMP socket option for datagram sockets to return
packet-arrival timestamps as control information (PR #1179).
Submitted by: Louis Mamakos <loiue@TransSys.com>
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r-- | sys/netinet/udp_usrreq.c | 36 |
1 files changed, 34 insertions, 2 deletions
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. */ |