Re: Перечисление сетевых интерфейсов.
>>>>> On Fri, 22 Feb 2002 19:11:47 +0300
>>>>> "Mikhail" == Mikhail Nikitin <mouse@uslugionline.ru> wrote:
Mikhail>
>> > Есть такая проблема: необходимо получить список всех активных сетевых
>> > интерфейсов (eth0, lo, eth1.. etc), а также присвоенные им ip-адреса при
>> > условии, что программа запускается от обычного пользователя а также
>> > (возможно), что в /proc/ прочитать ничего нельзя (/proc/net/dev.. etc...)
>> >
>> > Чем бы это дело обстряпать? (Прога пишется на С++)
>>
>> Сделать сокет и подергать за его ioctl-и. Есть перловый модуль
>> IO::Interface на CPAN. Его стоит взять и прочитать.
>> Исходник там, кстати, C-шный. А в книжке Линкольна Штайна
>> "Сетевое программирование на Perl" есть перловый эквивалент.
>>
Mikhail> Хм... вот про ioctl было интересно (к перлу у меня органическое отвращение
Mikhail> ;-(, так что он не подходит...)
Mikhail> Как это за него дергать?
# include <stdio.h>
# include <stdlib.h>
# include <errno.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <net/if.h>
# include <sys/ioctl.h>
# include <netinet/in.h>
# include <arpa/inet.h>
int main(int argc, char* argv[]){
struct ifconf ifc;
struct ifreq *ifr, ifrcopy;
int flags;
char *buf, *ptr;
int len;
int sockfd;
struct sockaddr_in *sad;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if ( sockfd == -1 ) {
perror ("socket");
return 1;
}
len = 100 * sizeof(struct ifreq);
buf = malloc(len);
ifc.ifc_len = len;
ifc.ifc_buf = buf;
if ( ioctl(sockfd, SIOCGIFCONF, &ifc ) == -1) {
if ( errno != EINVAL ) {
perror("ioctl");
return 2;
}
else
printf("not all interfaces fit in buf\n");
}
for (ptr = buf; ptr < buf + ifc.ifc_len; ){
ifr = (struct ifreq *)ptr;
# if 1
ptr += sizeof (ifr->ifr_name) + sizeof(struct sockaddr);
# else
ptr += sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len;
# endif
ifrcopy = *ifr;
ioctl(sockfd,SIOCGIFFLAGS,&ifrcopy);
flags = ifrcopy.ifr_flags;
if ( (flags & IFF_UP) == 0 ) continue; /* interface is down */
sad = (struct sockaddr_in *)(&ifr->ifr_addr);
printf("%s %s\n", ifr->ifr_name,
inet_ntoa( sad->sin_addr) );
}
return 0;
}
Есть там некоторый тарабл с тем, что ioctl заполняет массив из
struct ifreq {
...
union {
struct sockaddr
...
}
...
}
так у struct sockaddr может быть (более или менее свежий BSD), а может
и не быть (linux, например) sin_len, соответствеено в коде есть # if 1
под linux, дабы под BSD работало надо 1 заменить на 0.
Mikhail> Сокет-то мы создадим, а вот дальше? У меня тут злой MFC-программер под
Mikhail> боком сидит и жужжит что под виндами это enum-одной функцией а дальше в
Mikhail> цикле перечисление интерфесов... нужели в Linux такого нет?
Да ну... что-то не верится
--
Alexander Kotelnikov
Saint-Petersburg, Russia
Reply to: