Re: Netlink Implementation.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 20 Oct 2004 20:17:08 -0500
Eric Bambach <eric@cisu.net> wrote:

> Hello,
> 
> 	I am trying very hard to understand the userspace view of Netlink sockets. 
> However, my programming is not suffiecient enough to fully understand the man 
> pages or the source(iproute2/zebra) and work off of that. I have tried many 
> times but there seems no good documentation or implementation to help me. I 
> have found this implementation written by someone on LKML 2 years ago, 
> however the code produces no output. If I can get the code to produce some 
> and the expected output im sure I can work and understand the code from 
> there. However, because I did not write this code nor do I fully understand 
> netlink sockets I am at a loss of what to do. Can someone explain to me if 
> this code is correct for the 2.6.x series kernel? Furthermore, the author did 
> not define replybuf nor byes nor netlink_fd so I have guessed as to their 
> types. Ideally in the future Id like to use netlink to gather interface 
> information and modify routing tables, however without a solid base to learn 
> and adapt, I am at a loss. 

The file libnetlink.c in iproute2 sources is what you want to look at:

The problem with your code is it isn't look at the length of each sub-element
of the response message and stepping appropriately.  

The similar loop in libnetlink.c (notice more error checking)....

		status = recvmsg(rth->fd, &msg, 0);

		if (status < 0) {
			if (errno == EINTR)
				continue;
			perror("OVERRUN");
			continue;
		}
		if (status == 0) {
			fprintf(stderr, "EOF on netlink\n");
			return -1;
		}
		if (msg.msg_namelen != sizeof(nladdr)) {
			fprintf(stderr, "sender address length == %d\n", msg.msg_namelen);
			exit(1);
		}

		h = (struct nlmsghdr*)buf;
		while (NLMSG_OK(h, status)) {
			int err;

			if (nladdr.nl_pid != 0 ||
			    h->nlmsg_pid != rth->local.nl_pid ||
			    h->nlmsg_seq != rth->dump) {
				if (junk) {
					err = junk(&nladdr, h, arg2);
					if (err < 0)
						return err;
				}
				goto skip_it;
			}

			if (h->nlmsg_type == NLMSG_DONE)
				return 0;
			if (h->nlmsg_type == NLMSG_ERROR) {
				struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
				if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
					fprintf(stderr, "ERROR truncated\n");
				} else {
					errno = -err->error;
					perror("RTNETLINK answers");
				}
				return -1;
			}
			err = filter(&nladdr, h, arg1);
			if (err < 0)
				return err;

skip_it:
			h = NLMSG_NEXT(h, status);
		}
		if (msg.msg_flags & MSG_TRUNC) {
			fprintf(stderr, "Message truncated\n");
			continue;
		}
		if (status) {
			fprintf(stderr, "!!!Remnant of size %d\n", status);
			exit(1);
		}
	}
}
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux