Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unable to list/enumarate network interfaces through any means #136

Closed
codenotes opened this issue Apr 11, 2016 · 4 comments
Closed

unable to list/enumarate network interfaces through any means #136

codenotes opened this issue Apr 11, 2016 · 4 comments

Comments

@codenotes
Copy link

There seems to be no way to enumerate networking interfaces. While I understand we can not and shouldn't be accessing raw sockets, it is nonetheless a common task to explore, via bash, what interfaces you have. So, in addition to standard command line utils not working (ifconfig , "netstat" , "ip link") the real concern is that most python scripts that relay on this ability will fail. This python code for example:

import netifaces
netifaces.interfaces()

Fails. This is going to nullify a lot of scripts out there who need to iterate through available interfaces. Again, this is not to do anything low level, but it is a common procedure that a ton of legacy relies on. Hopefully this will be added?

@tkelman
Copy link

tkelman commented Apr 11, 2016

what's the error? probably a duplicate of #118

@sunilmut
Copy link
Member

Yes, this looks like #118, #69 and few other network related posts. We are aware of the lack of support for NETLINK sockets and are looking into it, based on the feedback provided through the wpdev portal. Please provide your feedback\up vote feature requests @ https://wpdev.uservoice.com/forums/266908-command-prompt-console-bash-on-ubuntu-on-windo

@codenotes
Copy link
Author

I think it likely resolve to the same thing. "Error 22, invalid argument." As it is with issue 118, the python is really just calling into a shared library that is querying the network layer...so our failures are probably from the same source, which is also why netstat and "ifconfig" fail as well.

The error number probably comes from the failure of the underlying .so to return a python list but am not certain. at the CC level I sure we just have a failure on the function that queries the network layer. For completeness, here is the .C code for hat netifaces in python is calling into:

static PyObject *
interfaces (PyObject *self)
{
PyObject *result;

#if defined(WIN32)
PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL, pInfo = NULL;
ULONG ulBufferLength = 0;
DWORD dwRet;

/* First, retrieve the adapter information */
do {
dwRet = GetAdaptersAddresses(AF_UNSPEC, 0, NULL,
pAdapterAddresses, &ulBufferLength);

if (dwRet == ERROR_BUFFER_OVERFLOW) {
  if (pAdapterAddresses)
    free (pAdapterAddresses);
  pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc (ulBufferLength);

  if (!pAdapterAddresses) {
    PyErr_SetString (PyExc_MemoryError, "Not enough memory");
    return NULL;
  }
}

} while (dwRet == ERROR_BUFFER_OVERFLOW);

/* If we failed, then fail in Python too */
if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) {
if (pAdapterAddresses)
free (pAdapterAddresses);

PyErr_SetString (PyExc_OSError,
                 "Unable to obtain adapter information.");
return NULL;

}

result = PyList_New(0);

if (dwRet == ERROR_NO_DATA) {
free (pAdapterAddresses);
return result;
}

for (pInfo = pAdapterAddresses; pInfo; pInfo = pInfo->Next) {
PyObject *ifname = (PyObject *)PyString_FromString (pInfo->AdapterName);

PyList_Append (result, ifname);
Py_DECREF (ifname);

}

free (pAdapterAddresses);
#elif HAVE_GETIFADDRS
const char *prev_name = NULL;
struct ifaddrs *addrs = NULL;
struct ifaddrs *addr = NULL;

result = PyList_New (0);

if (getifaddrs (&addrs) < 0) {
Py_DECREF (result);
PyErr_SetFromErrno (PyExc_OSError);
return NULL;
}

for (addr = addrs; addr; addr = addr->ifa_next) {
if (!prev_name || strncmp (addr->ifa_name, prev_name, IFNAMSIZ) != 0) {
PyObject *ifname = PyString_FromString (addr->ifa_name);

  if (!PySequence_Contains (result, ifname))
    PyList_Append (result, ifname);
  Py_DECREF (ifname);
  prev_name = addr->ifa_name;
}

}

freeifaddrs (addrs);
#elif HAVE_SIOCGIFCONF
const char *prev_name = NULL;
int fd = socket (AF_INET, SOCK_DGRAM, 0);
struct CNAME(ifconf) ifc;
int len = -1;

if (fd < 0) {
PyErr_SetFromErrno (PyExc_OSError);
return NULL;
}

// Try to find out how much space we need
#if HAVE_SIOCGSIZIFCONF
if (ioctl (fd, SIOCGSIZIFCONF, &len) < 0)
len = -1;
#elif HAVE_SIOCGLIFNUM
{ struct lifnum lifn;
lifn.lifn_family = AF_UNSPEC;
lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
ifc.lifc_family = AF_UNSPEC;
ifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
if (ioctl (fd, SIOCGLIFNUM, (char *)&lifn) < 0)
len = -1;
else
len = lifn.lifn_count;
}
#endif

// As a last resort, guess
if (len < 0)
len = 64;

ifc.CNAME(ifc_len) = (int)(len * sizeof (struct CNAME(ifreq)));
ifc.CNAME(ifc_buf) = malloc (ifc.CNAME(ifc_len));

if (!ifc.CNAME(ifc_buf)) {
PyErr_SetString (PyExc_MemoryError, "Not enough memory");
close (fd);
return NULL;
}

#if HAVE_SIOCGLIFNUM
if (ioctl (fd, SIOCGLIFCONF, &ifc) < 0) {
#else
if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) {
#endif
free (ifc.CNAME(ifc_req));
PyErr_SetFromErrno (PyExc_OSError);
close (fd);
return NULL;
}

result = PyList_New (0);
struct CNAME(ifreq) *pfreq = ifc.CNAME(ifc_req);
struct CNAME(ifreq) *pfreqend = (struct CNAME(ifreq) *)((char *)pfreq
+ ifc.CNAME(ifc_len));
while (pfreq < pfreqend) {
if (!prev_name || strncmp (prev_name, pfreq->CNAME(ifr_name), IFNAMSIZ) != 0) {
PyObject *name = PyString_FromString (pfreq->CNAME(ifr_name));

  if (!PySequence_Contains (result, name))
    PyList_Append (result, name);
  Py_XDECREF (name);

  prev_name = pfreq->CNAME(ifr_name);
}

#if !HAVE_SOCKADDR_SA_LEN
++pfreq;
#else
/* On some platforms, the ifreq struct can grow(!) if the socket address
is very long. Mac OS X is such a platform. */
{
size_t len = sizeof (struct CNAME(ifreq));
if (pfreq->ifr_addr.sa_len > sizeof (struct sockaddr))
len = len - sizeof (struct sockaddr) + pfreq->ifr_addr.sa_len;
pfreq = (struct CNAME(ifreq) *)((char *)pfreq + len);
}
#endif
}

free (ifc.CNAME(ifc_buf));
close (fd);
#endif /* HAVE_SIOCGIFCONF */

return result;
}

@sunilmut
Copy link
Member

Looks like there is already a post in wpdev tracking this. Feel free to add your vote there:

https://wpdev.uservoice.com/forums/266908-command-prompt-console-bash-on-ubuntu-on-windo/suggestions/13383789-enable-network-interface-enumeraration

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants