FreeBSD/contrib/bsnmp/snmpd/main.c
/*
 * Input from a datagram socket.
 * Each receive should return one datagram.
 */
Input from a datagram socket.
Each receive should return one datagram.
Input from a datagram socket . Each receive should return one datagram .
static int
recv_dgram(struct port_input *pi, struct in_addr *laddr)
{
	u_char embuf[1000];
	char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) +
	    CMSG_SPACE(sizeof(struct in_addr))];
	struct msghdr msg;
	struct iovec iov[1];
	ssize_t len;
	struct cmsghdr *cmsg;
	struct sockcred *cred = NULL;
	if (pi->buf == NULL) {
		if ((pi->buf = buf_alloc(0)) == NULL) {
			(void)recvfrom(pi->fd, embuf, sizeof(embuf),
			    0, NULL, NULL);
			return (-1);
		}
		pi->buflen = buf_size(0);
	}
	msg.msg_name = pi->peer;
	msg.msg_namelen = pi->peerlen;
	msg.msg_iov = iov;
	msg.msg_iovlen = 1;
	memset(cbuf, 0, sizeof(cbuf));
	msg.msg_control = cbuf;
	msg.msg_controllen = sizeof(cbuf);
	msg.msg_flags = 0;
	iov[0].iov_base = pi->buf;
	iov[0].iov_len = pi->buflen;
	len = recvmsg(pi->fd, &msg, 0);
	if (len == -1 || len == 0)
		return (-1);
	if (msg.msg_flags & MSG_TRUNC) {
		snmpd_stats.silentDrops++;
		snmpd_stats.inTooLong++;
		return (-1);
	}
	pi->length = (size_t)len;
	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
	    cmsg = CMSG_NXTHDR(&msg, cmsg)) {
		if (cmsg->cmsg_level == IPPROTO_IP &&
		    cmsg->cmsg_type == IP_RECVDSTADDR)
			memcpy(laddr, CMSG_DATA(cmsg), sizeof(struct in_addr));
		if (cmsg->cmsg_level == SOL_SOCKET &&
		    cmsg->cmsg_type == SCM_CREDS)
			cred = (struct sockcred *)CMSG_DATA(cmsg);
	}
	if (pi->cred)
		check_priv_dgram(pi, cred);
	return (0);
}
static int recv_dgram ( struct port_input * pi , struct in_addr * laddr ) { u_char embuf [ 1000 ] ; char cbuf [ CMSG_SPACE ( SOCKCREDSIZE ( CMGROUP_MAX ) ) + CMSG_SPACE ( sizeof ( struct in_addr ) ) ] ; struct msghdr msg ; struct iovec iov [ 1 ] ; ssize_t len ; struct cmsghdr * cmsg ; struct sockcred * cred = NULL ; if ( pi -> buf == NULL ) { if ( ( pi -> buf = buf_alloc ( 0 ) ) == NULL ) { ( void ) recvfrom ( pi -> fd , embuf , sizeof ( embuf ) , 0 , NULL , NULL ) ; return ( -1 ) ; } pi -> buflen = buf_size ( 0 ) ; } msg . msg_name = pi -> peer ; msg . msg_namelen = pi -> peerlen ; msg . msg_iov = iov ; msg . msg_iovlen = 1 ; memset ( cbuf , 0 , sizeof ( cbuf ) ) ; msg . msg_control = cbuf ; msg . msg_controllen = sizeof ( cbuf ) ; msg . msg_flags = 0 ; iov [ 0 ] . iov_base = pi -> buf ; iov [ 0 ] . iov_len = pi -> buflen ; len = recvmsg ( pi -> fd , & msg , 0 ) ; if ( len == -1 || len == 0 ) return ( -1 ) ; if ( msg . msg_flags & MSG_TRUNC ) { snmpd_stats . silentDrops ++ ; snmpd_stats . inTooLong ++ ; return ( -1 ) ; } pi -> length = ( size_t ) len ; for ( cmsg = CMSG_FIRSTHDR ( & msg ) ; cmsg != NULL ; cmsg = CMSG_NXTHDR ( & msg , cmsg ) ) { if ( cmsg -> cmsg_level == IPPROTO_IP && cmsg -> cmsg_type == IP_RECVDSTADDR ) memcpy ( laddr , CMSG_DATA ( cmsg ) , sizeof ( struct in_addr ) ) ; if ( cmsg -> cmsg_level == SOL_SOCKET && cmsg -> cmsg_type == SCM_CREDS ) cred = ( struct sockcred * ) CMSG_DATA ( cmsg ) ; } if ( pi -> cred ) check_priv_dgram ( pi , cred ) ; return ( 0 ) ; }
Input from a datagram socket.
Input from a datagram socket .
/* no buffer yet - allocate one */ /* ups - could not get buffer. Read away input
			 * and drop it */ /* return error */ /* try to get a message */ /* receive error */ /* truncated - drop */