示例#1
0
// Returns AF_MAX (with errno set) if error, AF_UNSPEC if no more addrs (socket closed)
struct IPAddr nextAddr(struct AddrFilter const filter, struct MonitorState * const state){
	// NLMSG_OK checks length first, so safe to call with state->nlh == NULL iff
	// state->nlmsg_len < (int) sizeof(struct nlmsghdr)
	if (NLMSG_OK(state->nlh, state->nlmsg_len) && (state->nlh->nlmsg_type != NLMSG_DONE)){
		struct nlmsghdr * nlh = state->nlh;
		state->nlh = NLMSG_NEXT(state->nlh, state->nlmsg_len);
		switch(nlh->nlmsg_type){
		case NLMSG_ERROR:
			errno = -((struct nlmsgerr *) NLMSG_DATA(nlh))->error;
			struct IPAddr addr = {.af = AF_MAX};
			return addr;
		case RTM_NEWADDR: {
			struct ifaddrmsg * ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);
			if (!filterIfAddrMsg(*ifa, filter))
				return nextAddr(filter, state);
			{
			struct rtattr * rth;
			size_t rtmsg_len;
			for (rth = IFA_RTA(ifa), rtmsg_len = IFA_PAYLOAD(nlh);
			     RTA_OK(rth, rtmsg_len); RTA_NEXT(rth, rtmsg_len)){
				if (rth->rta_type != IFA_ADDRESS)
					continue;
				// family checked in filterIfAddrMsg, so always valid.
				struct IPAddr addr = {.af = ifa->ifa_family};
				switch (ifa->ifa_family) {
				case AF_INET:
					addr.ipv4 = *((struct in_addr *) RTA_DATA(rth));
					break;
				case AF_INET6:
					addr.ipv6 = *((struct in6_addr *) RTA_DATA(rth));
					break;
				}
				if (addrIsPrivate(addr) && !filter.allow_private)
					return nextAddr(filter, state);
				else
					return addr;
			}
			}
			// Recieved RTM_NEWADDR without any address.
			errno = EBADMSG;
			struct IPAddr addr = {.af = AF_MAX};
			return addr;
		}
		default:
			return nextAddr(filter, state);
		}
	} else {
		state->nlmsg_len = nextMessage(filter, state->socket, &state->buf, &state->buf_len);
		if (state->nlmsg_len == 0) {
			// Socket closed by kernel
			struct IPAddr addr = {.af = AF_UNSPEC};
			return addr;
		} else if (state->nlmsg_len < 0) {
			// Socket error
			struct IPAddr addr = {.af = AF_MAX};
			return addr;
		} else  {
示例#2
0
文件: netlink.c 项目: anastiel/avahi
int avahi_netlink_work(AvahiNetlink *nl, int block) {
    ssize_t bytes;
    struct msghdr smsg;
    struct cmsghdr *cmsg;
    struct ucred *cred;
    struct iovec iov;
    struct nlmsghdr *p;
    char cred_msg[CMSG_SPACE(sizeof(struct ucred))];

    assert(nl);

    iov.iov_base = nl->buffer;
    iov.iov_len = nl->buffer_length;

    smsg.msg_name = NULL;
    smsg.msg_namelen = 0;
    smsg.msg_iov = &iov;
    smsg.msg_iovlen = 1;
    smsg.msg_control = cred_msg;
    smsg.msg_controllen = sizeof(cred_msg);
    smsg.msg_flags = (block ? 0 : MSG_DONTWAIT);

    if ((bytes = recvmsg(nl->fd, &smsg, 0)) < 0) {
        if (errno == EAGAIN || errno == EINTR)
            return 0;

        avahi_log_error(__FILE__": recvmsg() failed: %s", strerror(errno));
        return -1;
    }

    cmsg = CMSG_FIRSTHDR(&smsg);

    if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) {
        avahi_log_warn("No sender credentials received, ignoring data.");
        return -1;
    }

    cred = (struct ucred*) CMSG_DATA(cmsg);

    if (cred->pid != 0)
        return -1;

    p = (struct nlmsghdr *) nl->buffer;

    assert(nl->callback);

    for (; bytes > 0; p = NLMSG_NEXT(p, bytes)) {
        if (!NLMSG_OK(p, (size_t) bytes)) {
            avahi_log_warn(__FILE__": packet truncated");
            return -1;
        }

        nl->callback(nl, p, nl->userdata);
    }

    return 0;
}
示例#3
0
int netlink_mon_handler(orc_options_t * options,
                orc_driver_t * drv,
                int netlink_sock)
{
    char buf[BUFLEN];
    int msg_len;
    struct nlmsghdr * nl_msg;

    msg_len = recv(netlink_sock, buf, BUFLEN, 0);
    nl_msg = (struct nlmsghdr *) buf;
    for (; NLMSG_OK(nl_msg, msg_len); nl_msg=NLMSG_NEXT(nl_msg, msg_len))
    {
        switch(nl_msg->nlmsg_type)
        {
            case RTM_NEWLINK:
               orc_debug("RTNETLINK: add interface\n");
               /** TODO **/
               break;
            case RTM_DELLINK:
               orc_debug("RTNETLINK: del interface\n");
               /** TODO **/
               break;
            case RTM_NEWADDR:
               orc_trace("RTNETLINK: add IPv4 address\n");
               handle_v4_addr(OP_ADD, options, nl_msg);
               break;
            case RTM_DELADDR:
               orc_trace("RTNETLINK: del IPv4 address\n");
               handle_v4_addr(OP_DEL, options, nl_msg);
               break;
            case RTM_NEWROUTE:
               orc_trace("RTNETLINK: add IPv4 route\n");
               handle_v4_route(OP_ADD, options, nl_msg);
               break;
            case RTM_DELROUTE:
               orc_trace("RTNETLINK: del IPv4 route\n");
               handle_v4_route(OP_DEL, options, nl_msg);
               break;
            case RTM_NEWNEIGH:
               orc_trace("RTNETLINK: add IPv4 neighbor\n");
               handle_v4_neighbor(OP_ADD, options, nl_msg);
               break;
            case RTM_DELNEIGH:
               orc_trace("RTNETLINK: del IPv4 neighbor\n");
               handle_v4_neighbor(OP_DEL, options, nl_msg);
               break;
            case NLMSG_DONE:
               orc_log("RTNETLINK: ignoring an NLM_DONE msg\n");
               break;
            default:
               orc_log("RTNETLINK: unknown msg of type %d -- ignoring\n",
                       nl_msg->nlmsg_type);
        };

    }
    return 0;
}
示例#4
0
// gw and iface[IF_NAMESIZE] MUST be allocated
int get_default_gw(struct in_addr *gw, char *iface)
{
	struct rtmsg req;
	unsigned int nl_len;
	char buf[8192];
	struct nlmsghdr *nlhdr;

	if (!gw || !iface) {
		return -1;
	}

	// Send RTM_GETROUTE request
	memset(&req, 0, sizeof(req));
	int sock = send_nl_req(RTM_GETROUTE, 0, &req, sizeof(req));

	// Read responses
	nl_len = read_nl_sock(sock, buf, sizeof(buf));
	if (nl_len <= 0) {
		return -1;
	}

	// Parse responses
	nlhdr = (struct nlmsghdr *)buf;
	while (NLMSG_OK(nlhdr, nl_len)) {
		struct rtattr *rt_attr;
		struct rtmsg *rt_msg;
		int rt_len;
		int has_gw = 0;

		rt_msg = (struct rtmsg *) NLMSG_DATA(nlhdr);
		
		if ((rt_msg->rtm_family != AF_INET) || (rt_msg->rtm_table != RT_TABLE_MAIN)) {
			return -1;
		}
	
		rt_attr = (struct rtattr *) RTM_RTA(rt_msg);
		rt_len = RTM_PAYLOAD(nlhdr);
		while (RTA_OK(rt_attr, rt_len)) {
			switch (rt_attr->rta_type) {
			case RTA_OIF:
				if_indextoname(*(int *) RTA_DATA(rt_attr), iface); 
				break;
			case RTA_GATEWAY:
				gw->s_addr = *(unsigned int *) RTA_DATA(rt_attr); 
				has_gw = 1;
				break;
			}
			rt_attr = RTA_NEXT(rt_attr, rt_len);
		}
	
		if (has_gw) {
			return 0;
		}
		nlhdr = NLMSG_NEXT(nlhdr, nl_len);	
	}
	return -1;
}
示例#5
0
static int read_iface_prefix(const char *ip_str, int is_ipv6)
{
	uint8_t family = is_ipv6 ? AF_INET6 : AF_INET;

	char buf[16384];
	unsigned int len;

	struct {
		struct nlmsghdr nlhdr;
		struct ifaddrmsg addrmsg;
	} msg;

	struct nlmsghdr *retmsg;

	int sock = SAFE_SOCKET(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

	memset(&msg, 0, sizeof(msg));
	msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
	msg.nlhdr.nlmsg_type = RTM_GETADDR;
	msg.addrmsg.ifa_family = family;

	SAFE_SEND(1, sock, &msg, msg.nlhdr.nlmsg_len, 0);
	len = recv(sock, buf, sizeof(buf), 0);
	retmsg = (struct nlmsghdr *)buf;

	while NLMSG_OK(retmsg, len) {
		char ifname[IFNAMSIZ];
		struct ifaddrmsg *retaddr;
		struct rtattr *retrta;
		char pradd[128];
		int attlen;

		retaddr = (struct ifaddrmsg *)NLMSG_DATA(retmsg);
		retrta = (struct rtattr *)IFA_RTA(retaddr);
		attlen = IFA_PAYLOAD(retmsg);

		while RTA_OK(retrta, attlen) {
			if (retrta->rta_type == IFA_ADDRESS) {
				inet_ntop(family, RTA_DATA(retrta), pradd,
					  sizeof(pradd));

				if_indextoname(retaddr->ifa_index, ifname);

				if (!strcmp(pradd, ip_str)) {
					prefix = retaddr->ifa_prefixlen;
					iface = strdup(ifname);
					return 0;
				}
			}
			retrta = RTA_NEXT(retrta, attlen);
		}
		retmsg = NLMSG_NEXT(retmsg, len);
	}

	return -1;
}
示例#6
0
int
get_gateway (char *gateway)
{
	struct nlmsghdr *nlMsg;
	//struct rtmsg *rtMsg;
	struct route_info *rtInfo;
	char msgBuf[BUFSIZE];

	int sock, len, msgSeq = 0;
	//?? Socket
	if ((sock = socket (PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
		cfg_error("Socket Creation: \n");
		return -1;
	}

	/* Initialize the buffer */
	memset (msgBuf, 0, BUFSIZE);

	/* point the header and the msg structure pointers into the buffer */
	nlMsg = (struct nlmsghdr *)msgBuf;
	//rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);

	/* Fill in the nlmsg header */
	nlMsg->nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg)); // Length of message.
	nlMsg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table .

	nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump.
	nlMsg->nlmsg_seq = msgSeq++;/*lint !e632*/
	// Sequence of the message packet.

	nlMsg->nlmsg_pid = getpid ();/*lint !e632*/
// PID of process sending the request.

	/* Send the request */
	if (send (sock, nlMsg, (size_t)(nlMsg->nlmsg_len), 0) < 0) {
		cfg_error("Write To Socket Failed...\n");
		return -1;
	}

	/* Read the response */
	if ((len = readNlSock (sock, msgBuf, msgSeq, getpid ())) < 0) {
		cfg_error("Read From Socket Failed...\n");
		return -1;
	}
	/* Parse and print the response */
	rtInfo = (struct route_info *)malloc (sizeof (struct route_info));
	if (NULL != rtInfo) {
		for (; NLMSG_OK (nlMsg, len); nlMsg = NLMSG_NEXT (nlMsg, len)) { /*lint !e574 */
			/*lint !e574 */
			memset (rtInfo, 0, sizeof (struct route_info));
			parseRoutes (nlMsg, rtInfo, gateway);
		}
		free (rtInfo);
	}
	close (sock);
	return 0;
}
示例#7
0
int process_and_print()
{
    std::vector<Entry> ev;

    unsigned int nlmsg_len_c = nlmsg_len;

    count = count_messages();
    int i = 0;
    rtentry_array = (rttable_entry *)malloc(count * sizeof(rttable_entry));

    // preparujemy wiadomości
    nlmsg_ptr = (struct nlmsghdr *) read_buffer;
    for(; NLMSG_OK(nlmsg_ptr, nlmsg_len_c); nlmsg_ptr = NLMSG_NEXT(nlmsg_ptr, nlmsg_len_c)) {
        Entry e;
        rtmsg_ptr = (struct rtmsg *) NLMSG_DATA(nlmsg_ptr);
        prepare_rttable_entry( rtmsg_ptr, &(rtentry_array[i]) );

        e.inner = rtentry_array[i];
        if (e.inner.dest)
          {
            char buf[128];
            inet_ntop(e.inner.family, e.inner.dest, buf, 128);
            e.addr = boost::asio::ip::address::from_string(buf);
          }
        ev.push_back(e);

        i++;
    }

    // sortujemy
    sort(ev.begin(), ev.end(), Entry_oper);

    // dodajemy wcięcia
    for(unsigned int i=0; i<ev.size(); i++)
      {
        int max_indent = 0;

        for(unsigned int j=0; j<i; j++)
          {
            if ((ev[j].subsumes(ev[i]))) // && (ev[j] != ev[i]))
              {
#define max(a,b) a > b ? a : b
                max_indent = max(max_indent, ev[j].indent+1);
#undef max
              }
          }
        ev[i].indent = max_indent;
      }

    // wypisujemy
    for(unsigned int i=0; i<ev.size(); i++)
      {
        ev[i].print();
      }

    return 0;
}
示例#8
0
static int 
nl_getmsg(int sd, int request, int seq, 
	  struct nlmsghdr **nlhp,
	  int *done)
{
  struct nlmsghdr *nh;
  size_t bufsize = 65536, lastbufsize = 0;
  void *buff = NULL;
  int result = 0, read_size;
  int msg_flags;
  pid_t pid = getpid();
  for (;;){
    void *newbuff = realloc(buff, bufsize);
    if (newbuff == NULL || bufsize < lastbufsize) {
      result = -1;
      break;
    }
    buff = newbuff;
    result = read_size = nl_recvmsg(sd, request, seq, buff, bufsize, &msg_flags);
    if (read_size < 0 || (msg_flags & MSG_TRUNC)){
      lastbufsize = bufsize;
      bufsize *= 2;
      continue;
    }
    if (read_size == 0) break;
    nh = (struct nlmsghdr *)buff;
    for (nh = (struct nlmsghdr *)buff;
	 NLMSG_OK(nh, read_size);
	 nh = (struct nlmsghdr *)NLMSG_NEXT(nh, read_size)){
      if (nh->nlmsg_pid != pid ||
	  nh->nlmsg_seq != seq)
	continue;
      if (nh->nlmsg_type == NLMSG_DONE){
	(*done)++;
	break; /* ok */
      }
      if (nh->nlmsg_type == NLMSG_ERROR){
	struct nlmsgerr *nlerr = (struct nlmsgerr *)NLMSG_DATA(nh);
	result = -1;
	if (nh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
	  __set_errno(EIO);
	else
	  __set_errno(-nlerr->error);
	break;
      }
    }
    break;
  }
  if (result < 0)
    if (buff){
      int saved_errno = errno;
      free(buff);
      __set_errno(saved_errno);
    }
  *nlhp = (struct nlmsghdr *)buff;
  return result;
}
示例#9
0
/**
 * nfnl_iterator_next - get the next message hold by the iterator
 * @h: nfnetlink handler
 * @it: nfnetlink iterator that contains the current message processed
 *
 * This function update the current message to be processed pointer.
 * It returns NFNL_CB_CONTINUE if there is still more messages to be 
 * processed, otherwise NFNL_CB_STOP is returned.
 */
int nfnl_iterator_next(const struct nfnl_handle *h, struct nfnl_iterator *it)
{
	assert(h);
	assert(it);

	it->nlh = NLMSG_NEXT(it->nlh, it->len);
	if (!it->nlh)
		return 0;
	return 1;
}
示例#10
0
int read_reply()
{
	//string to hold content of the route
	// table (i.e. one entry)
	char dsts[24], gws[24], ifs[16], ms[24];
	// outer loop: loops thru all the NETLINK
	// headers that also include the route entry
	// header
	nlp = (struct nlmsghdr *) buf;
	for(; NLMSG_OK(nlp, nll); nlp = NLMSG_NEXT(nlp, nll))
	{
		// get route entry header
		rtp = (struct rtmsg *) NLMSG_DATA(nlp);
		// we are only concerned about the
		// main route table
		if(rtp->rtm_table != RT_TABLE_MAIN)
			continue;
		// init all the strings
		bzero(dsts, sizeof(dsts));
		bzero(gws, sizeof(gws));
		bzero(ifs, sizeof(ifs));
		bzero(ms, sizeof(ms));
		// inner loop: loop thru all the attributes of
		// one route entry
		rtap = (struct rtattr *) RTM_RTA(rtp);
		rtl = RTM_PAYLOAD(nlp);
		for( ; RTA_OK(rtap, rtl); rtap = RTA_NEXT(rtap,rtl))
		{
			switch(rtap->rta_type)
			{
				// destination IPv4 address
				case RTA_DST:
					inet_ntop(AF_INET, RTA_DATA(rtap),
							dsts, 24);
					break;
					// next hop IPv4 address
				case RTA_GATEWAY:
					inet_ntop(AF_INET, RTA_DATA(rtap),
							gws, 24);
					break;
					// unique ID associated with the network
					// interface
				case RTA_OIF:
					sprintf(ifs, "%d",
							*((int *) RTA_DATA(rtap)));
				default:
					break;
			}
		}
		sprintf(ms, "%d", rtp->rtm_dst_len);
		test_msg("dst %s/%s gw %s if %s\n",
				dsts, ms, gws, ifs);
	}
	return 0;
}
示例#11
0
int main(int argc, const char *argv[])
{
	struct nlmsghdr *nl_msg;
	struct route_info *rt_info;
	char msg[BUFSIZE];
	
	int sd, len, msg_seq = 0;
	
	/* Create Socket */
	if ((sd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
		perror("Socket Creation: ");
	}
	
	memset(msg, 0, BUFSIZE);
	
	/* point the header and the msg structure pointers into the buffer */
	nl_msg = (struct nlmsghdr *) msg;
	
	/* Fill in the nlmsg header*/
	nl_msg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));  // Length of message
	nl_msg->nlmsg_type = RTM_GETROUTE; // Get the routes from kernel routing table
	
	nl_msg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; // The message is a request for dump
	nl_msg->nlmsg_seq = msg_seq++; // Sequence of the message packet.
	nl_msg->nlmsg_pid = getpid(); // PID of process sending the request.
	
	/* Send the request */
	if (send(sd, nl_msg, nl_msg->nlmsg_len, 0) < 0) {
		printf("Write To Socket Failed...\n");
		return -1;
	}
	
	/* Read the response */
	if ((len = socket_netlink_read(sd, msg, msg_seq, getpid())) < 0) {
		printf("Read From Socket Failed...\n");
		return -1;
	}
	
	/* Parse and print the response */
	rt_info = (struct route_info *) malloc(sizeof(struct route_info));
	
	fprintf(stdout, "Destination\tGateway\tInterface\tSource\n");
	
	for ( ; NLMSG_OK(nl_msg, len); nl_msg = NLMSG_NEXT(nl_msg, len)) {
		memset(rt_info, 0, sizeof(struct route_info));
		route_parse(nl_msg, rt_info);
	}
	
	free(rt_info);
	close(sd);
	
	print_gateway();
	
	return 0;
}
示例#12
0
static void CAHandleNetlink()
{
#ifdef __linux__
    char buf[4096];
    struct nlmsghdr *nh;
    struct sockaddr_nl sa;
    struct iovec iov = { buf, sizeof (buf) };
    struct msghdr msg = { (void *)&sa, sizeof (sa), &iov, 1, NULL, 0, 0 };

    size_t len = recvmsg(caglobals.ip.netlinkFd, &msg, 0);

    for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len))
    {
        if (nh->nlmsg_type != RTM_NEWLINK)
        {
            continue;
        }

        struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
        if (!ifi || (ifi->ifi_flags & IFF_LOOPBACK) || !(ifi->ifi_flags & IFF_RUNNING))
        {
            continue;
        }

        int newIndex = ifi->ifi_index;

        u_arraylist_t *iflist = CAIPGetInterfaceInformation(newIndex);
        if (!iflist)
        {
            OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
            return;
        }

        uint32_t listLength = u_arraylist_length(iflist);
        for (uint32_t i = 0; i < listLength; i++)
        {
            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
            if (!ifitem)
            {
                continue;
            }

            if ((int)ifitem->index != newIndex)
            {
                continue;
            }

            CAProcessNewInterface(ifitem);
            break; // we found the one we were looking for
        }
        u_arraylist_destroy(iflist);
    }
#endif // __linux__
}
示例#13
0
static void ril_mtu_watch_handle_nlmsg(struct ril_mtu_watch *self,
					const struct nlmsghdr *hdr, int len)
{
	while (len > 0 && NLMSG_OK(hdr, len)) {
		if (hdr->nlmsg_type == RTM_NEWLINK) {
			ril_mtu_watch_handle_ifinfomsg(self, NLMSG_DATA(hdr),
						IFLA_PAYLOAD(hdr));
		}
		hdr = NLMSG_NEXT(hdr, len);
        }
}
示例#14
0
static void netlink_receive(int sock, void *eloop_ctx, void *sock_ctx)
{
	struct netlink_data *netlink = eloop_ctx;
	char buf[8192];
	int left;
	struct sockaddr_nl from;
	socklen_t fromlen;
	struct nlmsghdr *h;
	int max_events = 10;

try_again:
	fromlen = sizeof(from);
	left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
			(struct sockaddr *) &from, &fromlen);
	if (left < 0) {
		if (errno != EINTR && errno != EAGAIN)
			wpa_printf(MSG_INFO, "netlink: recvfrom failed: %s",
				   strerror(errno));
		return;
	}

	h = (struct nlmsghdr *) buf;
	while (NLMSG_OK(h, left)) {
		switch (h->nlmsg_type) {
		case RTM_NEWLINK:
			netlink_receive_link(netlink, netlink->cfg->newlink_cb,
					     h);
			break;
		case RTM_DELLINK:
			netlink_receive_link(netlink, netlink->cfg->dellink_cb,
					     h);
			break;
		}

		h = NLMSG_NEXT(h, left);
	}

	if (left > 0) {
		wpa_printf(MSG_DEBUG, "netlink: %d extra bytes in the end of "
			   "netlink message", left);
	}

	if (--max_events > 0) {
		/*
		 * Try to receive all events in one eloop call in order to
		 * limit race condition on cases where AssocInfo event, Assoc
		 * event, and EAPOL frames are received more or less at the
		 * same time. We want to process the event messages first
		 * before starting EAPOL processing.
		 */
		goto try_again;
	}
}
示例#15
0
void process_netlink_msg(int netlink_fd){
    int                 len             = 0;
    char                buffer[4096];
    struct iovec        iov;
    struct sockaddr_nl  dst_addr;
    struct msghdr       msgh;
    struct nlmsghdr     *nlh    = NULL;

    nlh = (struct nlmsghdr *)buffer;

    memset(&iov, 0, sizeof(iov));
    iov.iov_base = (void *)nlh;
    iov.iov_len = sizeof(nlh);

    memset(&msgh, 0, sizeof(msgh));
    msgh.msg_name = (void *)&(dst_addr);
    msgh.msg_namelen = sizeof(dst_addr);
    msgh.msg_iov = &iov;
    msgh.msg_iovlen = 1;

    while ((len = recv (netlink_fd,nlh,4096,MSG_DONTWAIT)) > 0){
        for (;(NLMSG_OK (nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE); nlh = NLMSG_NEXT(nlh, len)){
            switch(nlh->nlmsg_type){
            case RTM_NEWADDR:
                lispd_log_msg(LISP_LOG_DEBUG_2, "=>process_netlink_msg: Received  new address message");
                process_nl_add_address (nlh);
                break;
            case RTM_DELADDR:
                lispd_log_msg(LISP_LOG_DEBUG_2, "=>process_netlink_msg: Received  del address message");
                process_nl_del_address (nlh);
                break;
            case RTM_NEWLINK:
                lispd_log_msg(LISP_LOG_DEBUG_2, "=>process_netlink_msg: Received  link message");
                process_nl_new_link (nlh);
                break;
            case RTM_NEWROUTE:
                lispd_log_msg(LISP_LOG_DEBUG_2, "=>process_netlink_msg: Received  new route message");
                process_nl_new_route (nlh);
                break;
            case RTM_DELROUTE:
                //lispd_log_msg(LISP_LOG_DEBUG_2, "=>process_netlink_msg: Received  remove route message");
                //process_nl_del_route (nlh);
                break;
            default:
                break;
            }
        }
        nlh = (struct nlmsghdr *)buffer;
        memset(nlh,0,4096);
    }
    lispd_log_msg(LISP_LOG_DEBUG_2, "Finish pocessing netlink message");
    return;
}
示例#16
0
void getPortInode(QueryData &results, int type) {
  int nl_sock = 0;
  int numbytes = 0;
  int rtalen = 0;
  struct nlmsghdr *nlh;
  uint8_t recv_buf[SOCKET_BUFFER_SIZE];
  struct inet_diag_msg *diag_msg;

  // set up the socket
  if ((nl_sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_INET_DIAG)) == -1) {
    close(nl_sock);
    return;
  }

  // send the inet_diag message
  if (send_diag_msg(nl_sock, type) < 0) {
    close(nl_sock);
    return;
  }

  // recieve netlink messages
  numbytes = recv(nl_sock, recv_buf, sizeof(recv_buf), 0);
  nlh = (struct nlmsghdr *)recv_buf;
  while (NLMSG_OK(nlh, numbytes)) {

    // close the socket once NLMSG_DONE header recieved
    if (nlh->nlmsg_type == NLMSG_DONE) {
      close(nl_sock);
      return;
    }

    if (nlh->nlmsg_type == NLMSG_ERROR) {
      close(nl_sock);
      return;
    }

    // parse and process netlink message
    diag_msg = (struct inet_diag_msg *)NLMSG_DATA(nlh);
    rtalen = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*diag_msg));
    try {
      results.push_back(parse_diag_msg(diag_msg, rtalen));
    }
    catch (std::exception &e) {
      LOG(ERROR) << e.what();
    }

    nlh = NLMSG_NEXT(nlh, numbytes);
  }

  close(nl_sock);
  return;
}
示例#17
0
QueryData genRoutes(QueryContext& context) {
  QueryData results;

  int socket_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
  if (socket_fd < 0) {
    VLOG(1) << "Cannot open NETLINK socket";
    return {};
  }

  // Create netlink message header
  auto netlink_buffer = (void*)malloc(MAX_NETLINK_SIZE);
  if (netlink_buffer == nullptr) {
    close(socket_fd);
    return {};
  }

  memset(netlink_buffer, 0, MAX_NETLINK_SIZE);
  auto netlink_msg = (struct nlmsghdr*)netlink_buffer;
  netlink_msg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
  netlink_msg->nlmsg_type = RTM_GETROUTE; // routes from kernel routing table
  netlink_msg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST | NLM_F_ATOMIC;
  netlink_msg->nlmsg_seq = 0;
  netlink_msg->nlmsg_pid = getpid();

  // Send the netlink request to the kernel
  if (send(socket_fd, netlink_msg, netlink_msg->nlmsg_len, 0) < 0) {
    TLOG << "Cannot write NETLINK request header to socket";
    close(socket_fd);
    free(netlink_buffer);
    return {};
  }

  // Wrap the read socket to support multi-netlink messages
  size_t size = 0;
  if (!readNetlink(socket_fd, 1, (char*)netlink_msg, &size).ok()) {
    TLOG << "Cannot read NETLINK response from socket";
    close(socket_fd);
    free(netlink_buffer);
    return {};
  }

  // Treat the netlink response as route information
  while (NLMSG_OK(netlink_msg, size)) {
    genNetlinkRoutes(netlink_msg, results);
    netlink_msg = NLMSG_NEXT(netlink_msg, size);
  }

  close(socket_fd);
  free(netlink_buffer);
  return results;
}
示例#18
0
文件: netlink.c 项目: gygias/yammer
int
main()
{
  struct sockaddr_nl addr;
  int sock, len;
  char buffer[4096];
  struct nlmsghdr *nlh;

  if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
    perror("couldn't open NETLINK_ROUTE socket");
    return 1;
  }

  fprintf(stderr,"socket: f%d\n",sock);
  memset(&addr, 0, sizeof(addr));
  addr.nl_family = AF_NETLINK;
  addr.nl_groups = RTMGRP_IPV4_IFADDR;

  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
    perror("couldn't bind");
    return 1;
  }

  fprintf(stderr,"bound\n");
  nlh = (struct nlmsghdr *)buffer;
  while ((len = recv(sock, nlh, 4096, 0)) > 0) {
    fprintf(stderr,"recv returned %db (%d %s)\n",len,errno,strerror(errno));
    while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {
      if (nlh->nlmsg_type == RTM_NEWADDR) {
	struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);
	struct rtattr *rth = IFA_RTA(ifa);
	int rtl = IFA_PAYLOAD(nlh);

	while (rtl && RTA_OK(rth, rtl)) {
	  if (rth->rta_type == IFA_LOCAL) {
	    uint32_t ipaddr = htonl(*((uint32_t *)RTA_DATA(rth)));
	    char name[IFNAMSIZ];
	    if_indextoname(ifa->ifa_index, name);
	    printf("%s is now %d.%d.%d.%d\n",
		   name,
		   (ipaddr >> 24) & 0xff,
		   (ipaddr >> 16) & 0xff,
		   (ipaddr >> 8) & 0xff,
		   ipaddr & 0xff);
	  }
	  rth = RTA_NEXT(rth, rtl);
	}
      }
      nlh = NLMSG_NEXT(nlh, len);
    }
  }
示例#19
0
static bool __read_netlink_responses(int fd, ifaddrs** out, char* buf, size_t buf_len) {
  ssize_t bytes_read;
  // Read through all the responses, handing interesting ones to __handle_netlink_response.
  while ((bytes_read = TEMP_FAILURE_RETRY(recv(fd, buf, buf_len, 0))) > 0) {
    nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(buf);
    for (; NLMSG_OK(hdr, static_cast<size_t>(bytes_read)); hdr = NLMSG_NEXT(hdr, bytes_read)) {
      if (hdr->nlmsg_type == NLMSG_DONE) return true;
      if (hdr->nlmsg_type == NLMSG_ERROR) return false;
      __handle_netlink_response(out, hdr);
    }
  }
  // We only get here if recv fails before we see a NLMSG_DONE.
  return false;
}
示例#20
0
文件: kni.c 项目: daniel666/dpvs
static int kni_rtnl_check(void *arg)
{
    struct netif_port *dev = arg;
    int fd = dev->kni.kni_rtnl_fd;
    int n, i;
    char buf[4096];
    struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
    bool update = false;
    int max_trials = 1000;

    /* try to handle more events once, because we're not really
     * event-driven, the polling speed may not fast enough.
     * there may not so may events in real world ? but when 
     * performan strength test, it's really found kni_rtnl_timer
     * is too slow, so that more and more events queued. */

    for (i = 0; i < max_trials; i++) {
        n = recv(fd, nlh, sizeof(buf), 0);
        if (n < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN)
                break; /* no more events */
            RTE_LOG(WARNING, Kni, "fail to check kni event!\n");
            return DTIMER_OK;
        } else if (n == 0)
            break; /* closed */

        while (NLMSG_OK(nlh, n) && (nlh->nlmsg_type != NLMSG_DONE)) {
            if (nlh->nlmsg_type == RTM_NEWADDR) {
                update = true;
                break; /* not need handle all messages, recv again. */
            }

            nlh = NLMSG_NEXT(nlh, n);
        }
    }

    if (!kni_dev_exist(dev))
        return DTIMER_OK;

    /* note we should not update kni mac list for every event ! */
    if (update) {
        RTE_LOG(DEBUG, Kni, "%d events received!\n", i);
        if (kni_update_maddr(dev) == EDPVS_OK)
            RTE_LOG(DEBUG, Kni, "update maddr of %s OK!\n", dev->name);
        else
            RTE_LOG(ERR, Kni, "update maddr of %s Failed!\n", dev->name);
    }

    return DTIMER_OK;
}
示例#21
0
/*
 * our custom recvmsg, checks for the port number and hides it from ss
 */
asmlinkage ssize_t
manipulated_recvmsg(int fd, struct user_msghdr __user * msg, unsigned int flags)
{
	/* lock and increase the call counter */
	INCREASE_CALL_COUNTER(recvmsg_call_counter, &recvmsg_lock,
			      recvmsg_lock_flags);

	ssize_t retv;
	char *stream;
	struct nlmsghdr *nlh;
	struct inet_diag_msg *idm;
	unsigned int port;
	int i;
	int count;
	int offset;
	int found = 1;

	/* compute the length of original call */
	retv = original_recvmsg(fd, msg, flags);

	nlh = (struct nlmsghdr *)(msg->msg_iov->iov_base);

	/* to hold the bytes remaining */
	count = retv;

	while (NLMSG_OK(nlh, count)) {
		if (found == 0)
			nlh = NLMSG_NEXT(nlh, count);

		stream = (char *)nlh;
		idm = NLMSG_DATA(nlh);
		port = ntohs(idm->id.idiag_sport);

		/* check if we need to hide this socket */
		if (is_tcp_socket_hidden(port)) {
			found = 1;
			offset = NLMSG_ALIGN(nlh->nlmsg_len);
			for (i = 0; i < count; ++i)
				stream[i] = stream[i + offset];

			retv -= offset;
		} else
			found = 0;
	}

	/* lock and increase the call counter */
	DECREASE_CALL_COUNTER(recvmsg_call_counter, &recvmsg_lock,
			      recvmsg_lock_flags);
	return retv;
}
示例#22
0
/*
 * Handle a single netlink message. Block until we get a route status
 * change message. Returns 0 if there was a route status change, 1 if there was
 * a timeout, and -1 if there was a read error.
 */
int API
routeup_once (struct routeup *rtc, unsigned int timeout)
{
  char buf[4096];
  ssize_t sz;
  struct timeval remaining;
  struct timeval *rp = timeout ? &remaining : NULL;
  fd_set fds;

  remaining.tv_sec = timeout;
  remaining.tv_usec = 0;

  FD_ZERO (&fds);
  FD_SET (rtc->netlinkfd, &fds);

  while (select (rtc->netlinkfd + 1, &fds, NULL, NULL, rp) >= 0)
    {
      FD_ZERO (&fds);
      FD_SET (rtc->netlinkfd, &fds);
      if (timeout && !remaining.tv_sec && !remaining.tv_usec)
  return 1;
      if ((sz = read (rtc->netlinkfd, buf, sizeof (buf))) < 0)
  return -1;
      struct nlmsghdr *nh;
      for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, sz);
     nh = NLMSG_NEXT (nh, sz))
  {
    /*
     * Unpack the netlink message into a bunch of... well...
     * netlink messages. The terminology is overloaded. Walk
     * through the message until we find a header of type
     * NLMSG_DONE.
     */
    if (nh->nlmsg_type == NLMSG_DONE)
      break;
    if (nh->nlmsg_type != RTM_NEWROUTE)
      continue;
    /*
     * Clear out the socket so we don't keep old messages
     * queued up and eventually overflow the receive buffer.
     */
    while (read (rtc->netlinkfd, buf, sizeof(buf)) > 0)
      /* loop through receive queue */;
    if (errno != EAGAIN) return -1;
    return 0;
  }
    }

  return -1;
}
示例#23
0
void netlink_multicast(struct daemon *daemon)
{
  ssize_t len;
  struct nlmsghdr *h;
  
  if ((len = netlink_recv(daemon)) != -1)
    {
      for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
	if (h->nlmsg_type == NLMSG_ERROR)
	  nl_err(h);
	else
	  nl_routechange(daemon, h);
    }
}
示例#24
0
文件: netlink.cpp 项目: vyvy/vasum
std::unique_ptr<std::vector<char>> Netlink::rcv(unsigned int nlmsgSeq)
{
    std::unique_ptr<std::vector<char>> buf(new std::vector<char>());

    msghdr msg = utils::make_clean<msghdr>();
    sockaddr_nl nladdr = utils::make_clean<sockaddr_nl>();
    iovec iov = utils::make_clean<iovec>();

    msg.msg_name = &nladdr;
    msg.msg_namelen = sizeof(nladdr);
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    nladdr.nl_family = AF_NETLINK;

    nlmsghdr* answer;
    nlmsghdr* lastOk = NULL;
    size_t offset = 0;
    do {
        buf->resize(offset + NLMSG_RCV_GOOD_SIZE);
        answer = reinterpret_cast<nlmsghdr*>(buf->data() + offset);
        iov.iov_base = answer;
        iov.iov_len = buf->size() - offset;
        unsigned int ret = vsm_recvmsg(mFd, &msg, 0);
        for (unsigned int len = ret; NLMSG_OK(answer, len); answer = NLMSG_NEXT(answer, len)) {
            lastOk = answer;
            if (answer->nlmsg_type == NLMSG_ERROR) {
                // It is NACK/ACK message
                nlmsgerr *err = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(answer));
                if (answer->nlmsg_seq != nlmsgSeq) {
                    throw VasumException("Receive failed: answer message was mismatched");
                }
                if (err->error) {
                    throw VasumException("Receive failed: " + getSystemErrorMessage(-err->error));
                }
            } else if (answer->nlmsg_type == NLMSG_OVERRUN) {
                throw VasumException("Receive failed: data lost");
            }
        }
        if (lastOk == NULL) {
            const std::string msg = "Can't receive data from the system";
            LOGE(msg);
            throw VasumException(msg);
        }
        offset +=  NLMSG_ALIGN(ret);
    } while (lastOk->nlmsg_type != NLMSG_DONE && lastOk->nlmsg_flags & NLM_F_MULTI);

    buf->resize(offset);
    return buf;
}
示例#25
0
/*** read_event ***/
int read_event (int sockint) {
	int status, rc = EXIT_FAILURE;
	char buf[4096];
	struct iovec iov = { buf, sizeof buf };
	struct sockaddr_nl snl;
	struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
	struct nlmsghdr *h;

	if ((status = recvmsg (sockint, &msg, 0)) < 0) {
		/* Socket non-blocking so bail out once we have read everything */
		if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR) {
			rc = EXIT_SUCCESS;
			goto out;
		}

		/* Anything else is an error */
		fprintf (stderr, "read_netlink: Error recvmsg: %d\n", status);
		goto out;
	}

	if (status == 0)
		fprintf (stderr, "read_netlink: EOF\n");

	/* We need to handle more than one message per 'recvmsg' */
	for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status); h = NLMSG_NEXT (h, status)) {
		/* Finish reading */
		if (h->nlmsg_type == NLMSG_DONE) {
			rc = EXIT_SUCCESS;
			goto out;
		}

		/* Message is some kind of error */
		if (h->nlmsg_type == NLMSG_ERROR) {
			fprintf (stderr, "read_netlink: Message is an error - decode TBD\n");
			goto out;
		}

		/* Call message handler */
		if (msg_handler(&snl, h) != EXIT_SUCCESS) {
			fprintf (stderr, "read_event: Message hander returned error.\n");
			goto out;
		}
	}

	rc = EXIT_SUCCESS;

out:
	return rc;
}
示例#26
0
/*
 * Function     : icm_parse_netlink_msg
 * Description  : parse the received netlink msg to know
 *				  the interface state changes.
 * Input params : pointer pointing to the ICM_DEV_INFO_T structure
 * Return       : SUCCESS or FAILURE
 *
 */
int icm_parse_rtnetlink_msg(ICM_DEV_INFO_T* pdev) {
    int len;
    char buf[RTNETLINKBUFSIZ] = {0};
    struct iovec iov = {buf, sizeof(buf)};
    struct sockaddr_nl sa;
    struct nlmsghdr *nh;
    struct msghdr msg = {(void *)&sa, sizeof(sa), &iov, 1, NULL, 0, 0};
    struct ifinfomsg *ifinfo;
    char ifname[IFNAMSIZ] = {0};
    ICM_NLSOCK_T *prtnlinfo = ICM_GET_ADDR_OF_RTNLSOCK_INFO(pdev);
    int sd = prtnlinfo->sock_fd;

    len = recvmsg(sd, &msg, 0);

    /* Parsing the Netlink message */
    for(nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {

        if(nh->nlmsg_type == NLMSG_DONE) {
            break;
        }

        if(nh->nlmsg_type == NLMSG_ERROR) {
            return -1;
        }

        ifinfo = NLMSG_DATA(nh);
        if_indextoname(ifinfo->ifi_index, ifname);

        if((ifinfo->ifi_flags & IFF_RUNNING) && (ifinfo->ifi_flags & IFF_UP)) {
            ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_MAJOR, ICM_MODULE_ID_SOCKET,
                        "VAP %s ifindex %d is Created. Status: UP Running\n",
                        ifname, ifinfo->ifi_index);
            ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_MAJOR, ICM_MODULE_ID_SOCKET,"Updating Device information\n");
        } else if((ifinfo->ifi_flags & IFF_UP) || (ifinfo->ifi_flags & IFF_RUNNING)) {
            ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_MAJOR, ICM_MODULE_ID_SOCKET,
                        "VAP %s ifindex %d is Created. Status: Down Not Running\n",
                        ifname, ifinfo->ifi_index);
            ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_MAJOR, ICM_MODULE_ID_SOCKET,"Updating Device information\n");
        } else {
            ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_MAJOR, ICM_MODULE_ID_SOCKET,
                        "VAP %s ifindex %d is Destroyed.\n",
                        ifname, ifinfo->ifi_index);
            ICM_DPRINTF(pdev, ICM_PRCTRL_FLAG_NONE, ICM_DEBUG_LEVEL_MAJOR, ICM_MODULE_ID_SOCKET,"Updating Device information\n");
        }
        icm_configure_radio_iface(pdev);
    }

    return SUCCESS;
}
示例#27
0
static void netsnmp_access_arp_read_netlink(int fd, void *data)
{
    netsnmp_arp_access *access = (netsnmp_arp_access *) data;
    netsnmp_arp_entry *entry;
    char buf[16384];
    struct nlmsghdr *h;
    int r, len;

    do {
        r = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
        if (r < 0) {
            if (errno == EINTR)
                continue;
            if (errno == EAGAIN)
                return;
            snmp_log(LOG_WARNING, "netlink buffer overrun\n");
            access->synchronized = 0;
            if (access->cache_expired != NULL)
                *access->cache_expired = 1;
            return;
        }
    } while (0);
    len = r;

    for (h = (struct nlmsghdr *) buf; NLMSG_OK(h, len); h = NLMSG_NEXT(h, len)) {
        if (h->nlmsg_type == NLMSG_DONE) {
            access->synchronized = 1;
            continue;
        }

        entry = netsnmp_access_arp_entry_create();
        if (NULL == entry)
            break;

        DEBUGMSGTL(("access:netlink:arp", "arp netlink notification\n"));

        entry->generation = access->generation;
        r = fillup_entry_info (entry, h);
        if (r > 0) {
            access->update_hook(access, entry);
        } else {
            if (r < 0) {
                NETSNMP_LOGONCE((LOG_ERR, "filling entry info failed\n"));
                DEBUGMSGTL(("access:netlink:arp", "filling entry info failed\n"));
            }
            netsnmp_access_arp_entry_free(entry);
        }
    }
}
示例#28
0
文件: init.c 项目: bigclouds/opendove
/*
 ******************************************************************************
 * dcs_local_ip_monitor_process                                           *//**
 *
 * \brief - Called by the polling thread that gets an indication that the local
 *          IP address has changed. The function sets the Local IP Address in 
 *          the dcs_local_ip variable
 *
 * \param[in] socket - The socket on which the information arrived
 * \param[in] context - NULL
 *
 * \retval DOVE_STATUS_OK
 *
 ******************************************************************************
 */
static int dcs_local_ip_monitor_process(int socket, void *context)
{
	struct nlmsghdr *nlh;
	char buf[4096];
	int len;
	dove_status status = DOVE_STATUS_OK;

	while ((len = recv(dps_monitor_socket, buf, sizeof(buf), 0)) > 0)
	{

		nlh = (struct nlmsghdr *)buf;
		while ((NLMSG_OK(nlh, (uint32_t)len)) && (nlh->nlmsg_type != NLMSG_DONE))
		{
			if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR)
			{
				struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA(nlh);
				struct rtattr *rth = IFA_RTA(ifa);
				int rtl = IFA_PAYLOAD(nlh);

				while (rtl && RTA_OK(rth, rtl))
				{
					if (rth->rta_type == IFA_LOCAL)
					{
						char ifname[IFNAMSIZ];

						if_indextoname(ifa->ifa_index, ifname);

						if (!strcmp(ifname, SVA_INTERFACE_NAME) && (nlh->nlmsg_type == RTM_NEWADDR))
						{
							status = set_local_ip();
							if (status != DOVE_STATUS_OK)
							{
								log_warn(PythonDataHandlerLogLevel,
								         "Cannot get IP Address of SVA");
								break;
							}
							// Register the Local DPS Node with the Cluster
							dcs_set_service_role(dcs_role_assigned);
						}
					}
					rth = RTA_NEXT(rth, rtl);
				}
			}
			nlh = NLMSG_NEXT(nlh, len);
		}
	}

	return DOVE_STATUS_OK;
}
示例#29
0
static void vlan_event_receive(int sock, void *eloop_ctx, void *sock_ctx)
{
	char buf[8192];
	int left;
	struct sockaddr_nl from;
	socklen_t fromlen;
	struct nlmsghdr *h;
	struct hostapd_data *hapd = eloop_ctx;

	fromlen = sizeof(from);
	left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
			(struct sockaddr *) &from, &fromlen);
	if (left < 0) {
		if (errno != EINTR && errno != EAGAIN)
			wpa_printf(MSG_ERROR, "VLAN: %s: recvfrom failed: %s",
				   __func__, strerror(errno));
		return;
	}

	h = (struct nlmsghdr *) buf;
	while (NLMSG_OK(h, left)) {
		int len, plen;

		len = h->nlmsg_len;
		plen = len - sizeof(*h);
		if (len > left || plen < 0) {
			wpa_printf(MSG_DEBUG, "VLAN: Malformed netlink "
				   "message: len=%d left=%d plen=%d",
				   len, left, plen);
			break;
		}

		switch (h->nlmsg_type) {
		case RTM_NEWLINK:
			vlan_read_ifnames(h, plen, 0, hapd);
			break;
		case RTM_DELLINK:
			vlan_read_ifnames(h, plen, 1, hapd);
			break;
		}

		h = NLMSG_NEXT(h, left);
	}

	if (left > 0) {
		wpa_printf(MSG_DEBUG, "VLAN: %s: %d extra bytes in the end of "
			   "netlink message", __func__, left);
	}
}
static void factory_receive_skb(struct sk_buff *skb)
{
	struct nlmsghdr *nlh;
	int len;
	int err;
	nlh = (struct nlmsghdr*)skb->data;
	len = skb->len;
	while (NLMSG_OK(nlh, len)) {
		err = process_received_msg(skb, nlh);
		/* if err or if this message says it wants a response */
		if (err || (nlh->nlmsg_flags & NLM_F_ACK))
			netlink_ack(skb, nlh, err);
		nlh = NLMSG_NEXT(nlh, len);
	}
}