LINUX.ORG.RU

Протоколы ICMP и ARP не имеют никакого отношения к gcc. По этому вопрос "как сделать сабж в gcc" - на мой взгляд, некорректен. Другими словами, в gcc сабж сделать точно также как же, как и в других цешных компайлерах;)

Теперь, собственно, по вопросу.

Суть работы с пакетами ICMP и ARP заключается в том, что открывается RAW сокет и в него пишутся "вручную" сформированные пакеты. Другими словами пакеты необходимо формировать "самому" структурами типа

#define ETH_HW_ADDR_LEN 6
#define IP_ADDR_LEN 4

struct arp_packet {
u_char targ_hw_addr[ETH_HW_ADDR_LEN];
u_char src_hw_addr[ETH_HW_ADDR_LEN];
u_short frame_type;
u_short hw_type;
u_short prot_type;
u_char hw_addr_size;
u_char prot_addr_size;
u_short op;
u_char sndr_hw_addr[ETH_HW_ADDR_LEN];
u_char sndr_ip_addr[IP_ADDR_LEN];
u_char rcpt_hw_addr[ETH_HW_ADDR_LEN];
u_char rcpt_ip_addr[IP_ADDR_LEN];
u_char padding[18];
};

и

struct raw_packet {
struct iphdr ip;
struct icmphdr icmp;
struct iphdr encl_iphdr;
char encl_ip_data[8];
};

после чего необходимо соответствующим образом заполнять эти структуры данными и отправлять адресату.

Чтобы не повторяться (ибо на эту тему уже есть инфо), основную идею описываю схематично.
Если понадобится более подробное описание, его можно найти на void.ru в статье "Исследование возможностей перенаправления пакетов в протоколах ARP and ICMP" by Yuri Volobuyev.

Итак, сокет открывается таким образом:

в случае ICMP: sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

в случае ARP: sock = socket(AF_INET, SOCK_PACKET, htons(ETH_P_RARP));

Даные отправляются адресату таким образом:

в случае ICMP:

char on = 1;
struct raw_packet packet;
struct sockaddr_in sa;

/* заполняем соотв. образом packet и sa */

sa.sin_addr.s_addr = get_ip_addr("target_host_address");
sa.sin_family = AF_INET;
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&on, sizeof(on));
sendto(sock, packet, sizeof(struct raw_packet), 0, (struct sockaddr*)&sa, sizeof(struct sockaddr_in));

в случае ARP:

#define DEFAULT_DEVICE "eth0"
struct arp_packet packet;
struct sockaddr sa;

/* заполняем соотв. образом packet и sa */

strcpy(sa.sa_data, DEFAULT_DEVICE);
sendto(sock, &pkt, sizeof(pkt), 0, &sa, sizeof(sa));

--

С ICMP и ARP работаем по такой же схеме, как и с UDP, только разница в том, что необходимо самому выполнять рутинную работу по формированию пакетов.

Code and enjoy ;-)

proff
()

Ба-а-а-альшое спасибо :) Редко в форумах видишь такие полные ответы. Щас будем пробовать... Тока еще вот > > в случае ICMP: sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); почему нельзя sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); Вроде работает...

dist
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.