История изменений
Исправление
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));
Вариантов на выбор несколько. Зависит от того, что Вы собираетесь делать дальше. Если будет дополнительная информация и если будет нужна дополнительная помощь, то возможно я и смогу помочь.