Если Вы используете exec
в функции, переменные правила поиска изменяются решительно. Закрытия больше не возможны, но Python позволяет произвольные идентификаторы в функции. Это дает Вам "модифицируемых местных жителей ()" и может привыкнуть к идентификаторам звездообразного импорта. На оборотной стороне это делает каждый поиск медленнее, потому что переменные заканчиваются в dict, а не слотах в кадре:
>>> def f():
... exec "a = 42"
... return a
...
>>> def g():
... a = 42
... return a
...
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 1 ('a = 42')
3 LOAD_CONST 0 (None)
6 DUP_TOP
7 EXEC_STMT
3 8 LOAD_NAME 0 (a)
11 RETURN_VALUE
>>> dis.dis(g)
2 0 LOAD_CONST 1 (42)
3 STORE_FAST 0 (a)
3 6 LOAD_FAST 0 (a)
9 RETURN_VALUE
Это можно сделать только в зависимости от операционной системы. Вы можете попробовать разобрать вывод iptables, но правильный ответ для Linux - использовать ioctl.
SIOCGIFCONF принимает struct ifconf *. Поле ifc_buf указывает на буфер длиной ifc_len bytes, в который ядро записывает список введите struct ifreq [].
Структура struct ifreq задокументирована в linux / if.h:
struct ifreq
{
#define IFHWADDRLEN 6
union
{
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
} ifr_ifrn;
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
struct sockaddr ifru_hwaddr;
short ifru_flags;
int ifru_ivalue;
int ifru_mtu;
struct ifmap ifru_map;
char ifru_slave[IFNAMSIZ]; /* Just fits the size */
char ifru_newname[IFNAMSIZ];
void * ifru_data;
struct if_settings ifru_settings;
} ifr_ifru;
};
Как видите, она содержит необходимую вам адресную информацию.
Вот мое доказательство концептуального кода с использованием принятого ответа Каски для потомков:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
static const char * flags(int sd, const char * name)
{
static char buf[1024];
static struct ifreq ifreq;
strcpy(ifreq.ifr_name, name);
int r = ioctl(sd, SIOCGIFFLAGS, (char *)&ifreq);
assert(r == 0);
int l = 0;
#define FLAG(b) if(ifreq.ifr_flags & b) l += snprintf(buf + l, sizeof(buf) - l, #b " ")
FLAG(IFF_UP);
FLAG(IFF_BROADCAST);
FLAG(IFF_DEBUG);
FLAG(IFF_LOOPBACK);
FLAG(IFF_POINTOPOINT);
FLAG(IFF_RUNNING);
FLAG(IFF_NOARP);
FLAG(IFF_PROMISC);
FLAG(IFF_NOTRAILERS);
FLAG(IFF_ALLMULTI);
FLAG(IFF_MASTER);
FLAG(IFF_SLAVE);
FLAG(IFF_MULTICAST);
FLAG(IFF_PORTSEL);
FLAG(IFF_AUTOMEDIA);
FLAG(IFF_DYNAMIC);
#undef FLAG
return buf;
}
int main(void)
{
static struct ifreq ifreqs[32];
struct ifconf ifconf;
memset(&ifconf, 0, sizeof(ifconf));
ifconf.ifc_req = ifreqs;
ifconf.ifc_len = sizeof(ifreqs);
int sd = socket(PF_INET, SOCK_STREAM, 0);
assert(sd >= 0);
int r = ioctl(sd, SIOCGIFCONF, (char *)&ifconf);
assert(r == 0);
for(int i = 0; i < ifconf.ifc_len/sizeof(struct ifreq); ++i)
{
printf("%s: %s\n", ifreqs[i].ifr_name, inet_ntoa(((struct sockaddr_in *)&ifreqs[i].ifr_addr)->sin_addr));
printf(" flags: %s\n", flags(sd, ifreqs[i].ifr_name));
}
close(sd);
return 0;
}
Работает как шарм!
вы уверены, что правильно используете gethostname () / gethostbyname ()? проверьте здесь , единственная проблема, которую я вижу при этом, заключается в том, что возможно, что имя домена имеет несколько сопоставленных IP-адресов. В таком случае невозможно узнать, какой IP-адрес принадлежит локальной машине
.Некоторые ответы на дополнительные вопросы:
Добавление нескольких IP-адресов к устройству может выполняться с использованием псевдонимов. Когда вы это делаете, Linux создает устройства с именами типа eth0: 0.
ifconfig eth0: 0 10.0.0.1
Наличие одного и того же IP-адреса на нескольких устройствах может быть выполнено с помощью связывания каналов / агрегации каналов.
Вы можете получить необходимую информацию об интерфейсе двумя способами, включая вызов ioctl () с параметром SIOCGIFCONF и цикл по возвращенным структурам для получения информации об адресе интерфейса.
Учитывая список из все IP-адреса, как мне отфильтровать адреса обратной связи?
См. структуру ifreq в ответе caskey. Вы можете определить петлю (правильно) с помощью:
if (ifru_flags & IFF_LOOPBACK)
Константы находятся в if.h
Как мне получить список всех IP-адресов, по которым машина может устанавливать исходящие (т. Е. К любому другому компьютеру) соединения? Имея список всех IP-адресов, как мне отфильтровать адреса обратной связи?
Посмотрите исходный код lsof и netstat . Вы увидите, что это включает в себя обход структур памяти ядра, а не только выполнение системных вызовов.