LINUX.ORG.RU

История изменений

Исправление Moisha_Liberman, (текущая версия) :

Я бы сказал что вариантов несколько.

Исправление Moisha_Liberman, :

0 Общие моменты, что-то типа предупреждения. Мы понимаем, что работаем от root. Мы понимаем что в данном случае скорее всего пакеты RAW (сырые, самодельные), что так же тербует прав root. В случае raw-пакетов мы помним что практически вся инфраструктура ядра Linux для TCP/IP идёт лесом. Т.е. файерволл здесь работать не будет, т.к. raw означает для системы что пакет полностью обрабатывается приложением самостоятельно.

Вариант 1. Если нам просто надо отправить самосторятельно скрафченный пакет, то я бы предложил использовать libnet. Библиотека в принципе старенькая, но с другой стороны в ethernet тоже ничего новенького.

Как-то вот так:

libnet_t *l; /* Контекст либы. */

/* device это как раз char *device, т.е., имя интерфейса. 
 * Так же здесь я использовал LIBNET_LINK_ADV, что означает 
 * перевод интерфейса в adv. mode. 
 * Возможно что лучше будет использовать либо LIBNET_RAW4 или
 * LIBNET_RAW6 для отдельных случаев. */
l = libnet_init(LIBNET_LINK_ADV, device, error_information); 

Неплохая стартовая точка для разборок с данной либой. Пакеты там при её помощи крафтить тоже можно. В общем, рекомендую. И вот тоже неплохая дока по теме.

Вариант 2. Если у нас есть уже перехваченное TCP соединение, то скорее всего бы использовали libpcap. В этом случае как-то так:

int rc = pcap_findalldevs(&alldevs,errbuf);
if(-1 == rc)
{
    fprintf(stderr,"Error in pcap_findalldevs(): %s\n", errbuf);
    exit(1);
}
char *device = NULL;
device = alldevs->name; /* Здесь я беру имя первой карты в системе, но смысл, IMHO, понятен. */

Т.е., тоже в принципе можно, но случай это явно отдельный, т.к. это перехват линка и только потом инжектинг в поток своих пакетов.

Вариант 3. Как-то вот так примерно (проверку возвращаемого значения верните в код – setsockopt() не должен быть < 0). Не всегда срабатывает, если не сработает, то см. вариант 4:

char* device = "eth2"; /* Так, кажется у Вас? */
setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device));

Вариант 4. Как-то так (почти тоже что и вриант 3, но «страшнее») И здесь проверки возвращаемых значений верните в код (setsockopt() не должен быть < 0):

struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth2");
ioctl(fd, SIOCGIFINDEX, &ifr);

printf("[[%d]]\n", ifr.ifr_ifindex );
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,  (void*)&ifr, sizeof(struct ifreq));

Вариантов на выбор несколько. Зависит от того, что Вы собираетесь делать дальше. Если будет дополнительная информация и если будет нужна дополнительная помощь, то возможно я и смогу помочь.

Исходная версия Moisha_Liberman, :

Я бы сказал чо вариантов несколько.

0 Общие моменты, что-то типа предупреждения. Мы понимаем, что работаем от root. Мы понимаем что в данном случае скорее всего пакеты RAW (сырые, самодельные), что так же тербует прав root. В случае raw-пакетов мы помним что практически вся инфраструктура ядра Linux для TCP/IP идёт лесом. Т.е. файерволл здесь работать не будет, т.к. raw означает для системы что пакет полностью обрабатывается приложением самостоятельно.

Вариант 1. Если нам просто надо отправить самосторятельно скрафченный пакет, то я бы предложил использовать libnet. Библиотека в принципе старенькая, но с другой стороны в ethernet тоже ничего новенького.

Как-то вот так:

libnet_t *l; /* Контекст либы. */

/* device это как раз char *device, т.е., имя интерфейса. 
 * Так же здесь я использовал LIBNET_LINK_ADV, что означает 
 * перевод интерфейса в adv. mode. 
 * Возможно что лучше будет использовать либо LIBNET_RAW4 или
 * LIBNET_RAW6 для отдельных случаев. */
l = libnet_init(LIBNET_LINK_ADV, device, error_information); 

Неплохая стартовая точка для разборок с данной либой. Пакеты там при её помощи крафтить тоже можно. В общем, рекомендую. И вот тоже неплохая дока по теме.

Вариант 2. Если у нас есть уже перехваченное TCP соединение, то скорее всего бы использовали libpcap. В этом случае как-то так:

int rc = pcap_findalldevs(&alldevs,errbuf);
if(-1 == rc)
{
    fprintf(stderr,"Error in pcap_findalldevs(): %s\n", errbuf);
    exit(1);
}
char *device = NULL;
device = alldevs->name; /* Здесь я беру имя первой карты в системе, но смысл, IMHO, понятен. */

Т.е., тоже в принципе можно, но случай это явно отдельный, т.к. это перехват линка и только потом инжектинг в поток своих пакетов.

Вариант 3. Как-то вот так примерно (проверку возвращаемого значения верните в код – setsockopt() не должен быть < 0). Не всегда срабатывает, если не сработает, то см. вариант 4:

char* device = "eth2"; /* Так, кажется у Вас? */
setsockopt(sfd, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(device));

Вариант 4. Как-то так (почти тоже что и вриант 3, но «страшнее») И здесь проверки возвращаемых значений верните в код (setsockopt() не должен быть < 0):

struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth2");
ioctl(fd, SIOCGIFINDEX, &ifr);

printf("[[%d]]\n", ifr.ifr_ifindex );
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,  (void*)&ifr, sizeof(struct ifreq));

Вариантов на выбор несколько. Зависит от того, что Вы собираетесь делать дальше. Если будет дополнительная информация и если будет нужна дополнительная помощь, то возможно я и смогу помочь.