Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Raw сокеты, ручное формирование Ethernet-II фреймов

16K
25 апреля 2011 года
asmforce
186 / / 05.01.2010
Доброго дня.

Есть ли возможность самостоятельного формирования ethernet-II фрейма ручками, без создания собственного драйвера (более-менее `штатными` средствами)?
Пока получается формировать стек, начиная с `ip`.

Как видно из кода и того, что мне даёт wireshark, фрейм формируется в процедуре sendto и ниже:
> `Destination-MAC` получается из ARP-таблицы по IP-адресу (в данном случае `IPv4`) указанному в структуре sockaddr (sockaddr_in);
> `Source-MAC` подставляется свой (с учетом маршрута, а следовательно и интерфейса);
> Поле `type` eth-фрейма вычисляется в соответствии с семейством (поле sin_family структуры sockaddr_in);

Хочется реализовать mac-спуффинг, не изменяя мак-адрес сетевой карточки. Т.е. слать с одной карточки фреймы с различными значениями `Source-MAC` (ну и при желании стальные два поля);

Отсюда вытекает еще вопрос: если необходимо вручную формировать все эти параметры, следовательно нужно явно указать интерфейс, через который произойдет отправка. Как?

Вот то, что я налабал:
Код:
#include <iostream>
#include <cstdlib> // rand

// #include <winsock.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#include <elib/aliases.hpp>
using namespace elib::aliases;





#pragma pack( push, 1 )

namespace eth {
  struct ipv4 {
    // base
    u8  ihl:4;      // 32-bit blocks count of ip-head
    u8  version:4;  // must be 4
    u8  tos;        // type of service
    u16 packsize;   // total size of packet

    // fragmentation
    u16 fuid;       // fragstream uid
    u8  fzero:1;    // must be zero
    u8  fdisable:1; // disable fragmentation
    u8  fmore:1;    // current fragment is not last
    u16 foffset:13; // fragment ordinal number

    // advanced
    u8  ttl;         // time to live
    u8  protocol;    // next level of tcp/ip stack
    u16 checksum;    // head checksum

    u32 source;      // sender's ipv4-address
    u32 destination; // receiver's ipv4-address
  };

  struct udp {
    u16 sport;
    u16 dport;
    u16 length;
    u16 checksum;
  };
}; // namespace eth


template< u32 datasize >
struct udppacket {
  eth::ipv4 iphead;
  eth::udp  udphead;
  char data[datasize];
};






int main( int argc, char **argv )
{
  WSADATA wsadata;
  WSAStartup( 0x0202, &wsadata );

  SOCKET s = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
  if( s == INVALID_SOCKET )  {
    std::cout << "error: invalid socket\n";
    return -1;
  };

  BOOL optval = TRUE;
  if( setsockopt(s,IPPROTO_IP,IP_HDRINCL,(char*)&optval,sizeof(optval))==SOCKET_ERROR )  {
    std::cout << "error: failed to set socket in raw mode\n";
    return -1;
  };


  udppacket<1024> packet;

  // ip
  packet.iphead.version = 4;
  packet.iphead.ihl = 5;
  packet.iphead.tos = 0;
  packet.iphead.packsize = htons( sizeof(packet) );

  packet.iphead.fuid = rand();
  packet.iphead.fzero = 0;
  packet.iphead.fdisable = 0;
  packet.iphead.fmore = 0;
  packet.iphead.foffset = 0;

  packet.iphead.ttl = 32;
  packet.iphead.protocol = 17; // udp
  packet.iphead.checksum = 0;

  packet.iphead.source = inet_addr("192.168.100.118");
  packet.iphead.destination = inet_addr("192.168.100.254");

  // udp
  packet.udphead.sport = htons(65000);
  packet.udphead.dport = htons(65000);
  packet.udphead.length = htons( sizeof(packet.udphead) + sizeof(packet.data) );
  packet.udphead.checksum  = 0;

  // data
  memset( packet.data, 0, sizeof(packet.data) );

  sockaddr_in address;
  address.sin_family = AF_INET;
  address.sin_port = 0;
  address.sin_addr.s_addr = inet_addr("192.168.100.254");
  memset( address.sin_zero, 0, sizeof(address.sin_zero) );

  std::cout << "sendto: " <<
      sendto( s, (char*)&packet, sizeof(packet), 0, (SOCKADDR*)&address, sizeof(address) )
      << '\n';

  WSACleanup();
  std::cin.get();
  return 0;
};
16K
25 апреля 2011 года
asmforce
186 / / 05.01.2010
Пока просмотрел некоторые части исходников WinPCap, там используется NDis (по-моему это драйвер-прослойка), что не радует. Хотелось бы переносимые сопровождаемые штатные интерфейсы юзать.
Буду копать в сторону <неведомая сторона>. )
63K
03 мая 2011 года
SimSonic
16 / / 14.03.2011
Честна, вроде как MS "обещались", что c RAW сокетами будет всё тяжелее и тяжелее, начиная с Vista (7), еще до её выхода, если исходить из этого, штатные средства если и есть, скоро их не будет...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог