[ПРОграммист
ВЗАИМОДЕЙСТВИЕ С СЕТЕВЫМИ ИНТЕРФЕЙСАМИ В LINUX
май 2010
int sock = socket(AF_INET, SOCK_DGRAM, 0); Результат sock и есть дескриптор сокета, перед использованием,
его,
как
и
все
прочие
дескрипторы, следует проверять на отрицательные
значения, на случай возможных ошибок. Также, для
ioctl
вызовов
на
дескрипторе
сокета
применяется особая структура параметра (serail, в
интерфейс активен или неактивен и др.) ifr_metric
- метрика интерфейса
ifr_mtu
- mtu интерфейса
ifr_map
- структура, содержащая в себе техническую информацию (номер прерывания, память устройства)
ifr_slave
- подчиненное устройство
ifr_newname - новое имя интерфейса (для переименования)
примере выше) - struct ifreq. Это очень важная
Перед любым использованием структуры следует
сетевыми устройствами. Разберем ее подробнее
затем задавать имя интересуемого интерфейса
структура, используемая во всех случаях работы с (см. листинг 2): struct ifreq {
ЛИСТИНГ 2
char ifr_name[IFNAMSIZ]; struct sockaddr ifr_addr;
IP
Соответствующий
#include <sys/socket.h>
struct sockaddr ifr_netmask;
#include <sys/types.h>
short
ifr_flags;
int
ifr_metric;
int
struct ifmap char
состоит
(см.
ЛИСТИНГ 3
#include <errno.h> #include <stdio.h>
ifr_mtu;
ifr_slave[IFNAMSIZ];
int main()
ifr_data;
int sock;
{
// дескриптор сокета
struct sockaddr_in*in_addr;
из
двух
полей:
имени
// структура интернет-адреса (поля) struct ifreq ifdata;
интерфейса и объединения, каждое возможное
// структура - параметр
сетевого интерфейса. Данная структура позволяет,
sock = socket(AF_INET, SOCK_DGRAM, 0);
его. Так как используется объединение – можно
if (sock < 0) {
один параметр за раз.
return 1;
поле, которого выражает конкретный параметр как получать параметр интерфейса, так и задавать получать и задавать только
Интересуемые и используемые поля: ifr_addr
- IP адрес интерфейса
ifr_dstaddr
- адрес сервера (для Point-to-Point)
ifr_broadaddr - широковещательный адрес интерфейса ifr_netmask
- маска подсети
ifr_hwaddr
- mac адрес
ifr_ifinder
- индекс интерфейса (внутри ядра сетевые интерфейсы
char
сетевой подсистемы) - различные флаги (интерфейс поднят или опущен,
*ifname = "eth0"; // имя интерфейса
// открываем дескриптор сокета
printf("Не удалось открыть сокет, ошибка: %s\n", strerror(errno));
}
memset(&ifdata,
0,
sizeof(ifdata)); // очищаем структуру
// задаем имя интерфейса
strncpy(ifdata.ifr_name, ifname, sizeof(ifname)); // получаем айпи адрес с помощью SIOCGIFADDR, // одновременно проверяя результат
if (ioctl(sock, SIOCGIFADDR, &ifdata) < 0) {
printf("Не получить IP адрес для %s, ошибка: %s\n", ifname, strerror(errno));
имеют уникальные индексы, для упрощения работы
ifr_flags
ниже
#include <net/if.h>
ifr_newname[IFNAMSIZ];
char *
приведен
eth0!
#include <string.h>
ifr_map;
char
пример
интерфейса
#include <sys/ioctl.h>
ifr_ifindex;
int
адрес
#include <arpa/inet.h>
struct sockaddr ifr_hwaddr;
Структура
получим
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
};
ifr_name. Теперь перейдем от теории к действию –
листинг 3):
union {
};
ее обязательно обнулять с помощью memset, а
close(sock);
return 1; }
LINUX ПРОГРАММИРОВАНИЕ. НАЧИНАЮЩИМ
СОДЕРЖАНИЕ
12