- 论坛徽章:
- 36
|
iptables的libipq.c中的代码:
- static ssize_t ipq_netlink_recvfrom(const struct ipq_handle *h,
- unsigned char *buf, size_t len,
- int timeout)
- {
- int addrlen, status;
- struct nlmsghdr *nlh;
- if (len < sizeof(struct nlmsgerr)) {
- ipq_errno = IPQ_ERR_RECVBUF;
- return -1;
- }
- addrlen = sizeof(h->peer);
- if (timeout != 0) {
- int ret;
- struct timeval tv;
- fd_set read_fds;
-
- if (timeout < 0) {
- /* non-block non-timeout */
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- } else {
- tv.tv_sec = timeout / 1000000;
- tv.tv_usec = timeout % 1000000;
- }
- FD_ZERO(&read_fds);
- FD_SET(h->fd, &read_fds);
- ret = select(h->fd+1, &read_fds, NULL, NULL, &tv);
- if (ret < 0) {
- if (errno == EINTR) {
- return 0;
- } else {
- ipq_errno = IPQ_ERR_RECV;
- return -1;
- }
- }
- if (!FD_ISSET(h->fd, &read_fds)) {
- ipq_errno = IPQ_ERR_TIMEOUT;
- return 0;
- }
- }
- status = recvfrom(h->fd, buf, len, 0,
- (struct sockaddr *)&h->peer, &addrlen);
- if (status < 0) {
- ipq_errno = IPQ_ERR_RECV;
- return status;
- }
- if (addrlen != sizeof(h->peer)) {
- ipq_errno = IPQ_ERR_RECV;
- return -1;
- }
- if (h->peer.nl_pid != 0) {
- ipq_errno = IPQ_ERR_RECV;
- return -1;
- }
- if (status == 0) {
- ipq_errno = IPQ_ERR_NLEOF;
- return -1;
- }
- nlh = (struct nlmsghdr *)buf;
- if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > status) {
- ipq_errno = IPQ_ERR_RTRUNC;
- return -1;
- }
- return status;
- }
复制代码 |
|