From: Mark Huang Date: Mon, 27 Nov 2006 22:39:09 +0000 (+0000) Subject: - extension to gather information about local network interfaces X-Git-Tag: planetlab-4_0-rc1~35 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=eee86eeae2b45b588eb32dd0b43da135437066ec;hp=ac16fee02ad417b3541743675a8a91b858a5f287;p=nodemanager.git - extension to gather information about local network interfaces --- diff --git a/sioc.c b/sioc.c new file mode 100644 index 0000000..0ddeb31 --- /dev/null +++ b/sioc.c @@ -0,0 +1,160 @@ +/* + * Extension to gather information about network interfaces + * + * Mark Huang + * Copyright (C) 2006 The Trustees of Princeton University + * + * $Id$ + */ + +#include + +/* struct ifreq */ +#include + +/* socket() */ +#include +#include + +/* ioctl() */ +#include + +/* inet_ntoa() */ +#include +#include + +/* ARPHRD_ETHER */ +#include + +/* ETH_ALEN */ +#include + +static PyObject * +gifconf(PyObject *self, PyObject *args) +{ + struct ifconf ifc; + int len; + int s; + PyObject *addrs; + void *buf; + struct ifreq *ifr; + struct sockaddr_in *sin; + + if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return PyErr_SetFromErrno(PyExc_OSError); + + len = sizeof(struct ifreq); + ifc.ifc_len = 0; + ifc.ifc_req = NULL; + + do { + len *= 2; + buf = realloc(ifc.ifc_req, len); + if (!buf) + break; + ifc.ifc_len = len; + ifc.ifc_req = buf; + if (ioctl(s, SIOCGIFCONF, &ifc) < 0) + break; + } while (ifc.ifc_len >= len); + + close(s); + + addrs = Py_BuildValue("{}"); + + for (ifr = ifc.ifc_req, len = ifc.ifc_len; len > 0; ifr++, len -= sizeof(struct ifreq)) { + sin = (struct sockaddr_in *) &ifr->ifr_addr; + PyDict_SetItem(addrs, + Py_BuildValue("s", ifr->ifr_name), + Py_BuildValue("s", inet_ntoa(sin->sin_addr))); + } + + if (ifc.ifc_req) + free(ifc.ifc_req); + + return addrs; +} + +static PyObject * +gifaddr(PyObject *self, PyObject *args) +{ + const char *name; + struct ifreq ifr; + int s; + struct sockaddr_in *sin; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, name, IFNAMSIZ); + + if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return PyErr_SetFromErrno(PyExc_OSError); + + if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { + close(s); + return PyErr_SetFromErrno(PyExc_OSError); + } + + close(s); + + sin = (struct sockaddr_in *) &ifr.ifr_addr; + return Py_BuildValue("s", inet_ntoa(sin->sin_addr)); +} + +static PyObject * +gifhwaddr(PyObject *self, PyObject *args) +{ + const char *name; + struct ifreq ifr; + int s; + char mac[sizeof(ifr.ifr_hwaddr.sa_data) * 3], *c; + int len, i; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, name, IFNAMSIZ); + + if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + return PyErr_SetFromErrno(PyExc_OSError); + + if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { + close(s); + return PyErr_SetFromErrno(PyExc_OSError); + } + + close(s); + + switch (ifr.ifr_hwaddr.sa_family) { + case ARPHRD_ETHER: + len = ETH_ALEN; + break; + default: + len = sizeof(ifr.ifr_hwaddr.sa_data); + break; + } + + for (i = 0, c = mac; i < len; i++) { + if (i) + c += sprintf(c, ":"); + c += sprintf(c, "%02X", (unsigned char)(ifr.ifr_hwaddr.sa_data[i] & 0xFF)); + } + + return Py_BuildValue("s", mac); +} + +static PyMethodDef methods[] = { + { "gifconf", gifconf, METH_VARARGS, "Get all interface addresses" }, + { "gifaddr", gifaddr, METH_VARARGS, "Get interface address" }, + { "gifhwaddr", gifhwaddr, METH_VARARGS, "Get interface hardware address" }, + { NULL, NULL, 0, NULL } +}; + +PyMODINIT_FUNC +initsioc(void) +{ + Py_InitModule("sioc", methods); +}