← Back to team overview

yellow team mailing list archive

Re: lxc-ip script

 

Hi,

I had some points in response, but that gave me an idea.  Attached is a
program which, given the pid of a task in a container, prints the ip
address of eth0 in that container.  It's not pretty nor safe if there
are any errors, but a POC :)

Note setns is a privileged operation (as is opening /proc/pid/ns/net
itself, apparently), so you must run this as root.

Does this suffice?

-serge
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <arpa/inet.h>
#include <sched.h>
#include <linux/sched.h>

int main(int argc, char *argv[])
{
	int ret;
	int pid = atoi(argv[1]);
	char name[300];
	int fd;
	int s;
	struct ifreq ifr;

	if (argc < 2) {
		printf("Usage: %s [pid]", argv[0]);
		exit(1);
	}
	pid = atoi(argv[1]);
	snprintf(name, 300, "/proc/%d/ns/net", pid);
	fd = open(name, "r");
	if (fd < 0) {
		printf("open ns/net\n");
		perror("open ns/net\n");
		exit(1);
	}
	ret = setns(fd, CLONE_NEWNET);
	close(fd);
	printf("setns returned %d\n", ret);

	s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
	if (s < 0) {
		perror("socket");
		exit(2);
	}
	ifr.ifr_addr.sa_family = AF_INET;
	strcpy(ifr.ifr_ifrn.ifrn_name, "eth0");
	ioctl(s, SIOCGIFADDR, &ifr);


	struct sockaddr *sa;
	sa=(struct sockaddr *)&(ifr.ifr_addr);
	printf("address is %s\n", inet_ntoa(((struct sockaddr_in *)sa)->sin_addr));

	exit(0);
}

References