LINUX.ORG.RU

послать ARP запрос и получить ответ.


0

0

Всем привет, есть вопрос.

пишу программу хост монитора для Linux на C++. Задача тривиальная — пинговать все хосты (1500+) и фиксировать время отклика в БД. Пинговать надо ARP запросами (ARP REQUEST).

Все бы хорошо, но не могу принять ответ на мой запрос.
Может кто подскажет, как это сотворить?


int send_packet(u_char *dev, u_char *packet, u_int packetsize)
{
struct sockaddr addr;
int sock, n;

if( (strlen(dev) == 0) ||
(packetsize == 0) )
return -1;

// Create socket descriptor
if((sock = socket(AF_INET,SOCK_TYPE,htons(ETH_P_ALL))) < 0) {
perror("socket");
exit(1);
}

// Set dev and send the packet
strncpy(addr.sa_data,dev,sizeof(addr.sa_data));
if((sendto(sock,packet,packetsize,0,&addr,sizeof(struct sockaddr))) < 0) {
perror("send");
exit(1);
}

close(sock);
return 0;
}

int send_arp(dev, sip, dip, smac, dmac) {
int uid;
unsigned int packetsize = sizeof(struct arphdr) + sizeof(struct ether_header);
unsigned char packet[packetsize];
struct ether_header *ethhdr = (struct ether_header *)packet;
struct arphdr *arp = (struct arphdr *)(packet + sizeof(struct ether_header));
u_short op;

// Are you root?
uid = getuid();
if(uid != 0)
{
printf("You must be a root. Your UID = %d.\n",uid);
exit(1);
}

memset(packet,0,packetsize);
op = ARPOP_REQUEST;

memcpy(ethhdr->ether_dhost,(u_char *)ether_aton(dmac),ETHER_ADDR_LEN);
memcpy(ethhdr->ether_shost,(u_char *)ether_aton(smac),ETHER_ADDR_LEN);
ethhdr->ether_type = htons(ETHERTYPE_ARP);

arp->hw_type = htons(ARPHDR_ETHER);
arp->proto_type = htons(ETH_P_IP);
arp->ha_len = ETH_ALEN;
arp->pa_len = IP_ALEN;
arp->opcode = htons(op);
memcpy(arp->source_add,(u_char *)ether_aton(smac),ETH_ALEN);
*(u_long *)arp->source_ip = inet_addr((char *)sip);
if(strcmp((char *)dmac,"ff:ff:ff:ff:ff:ff"))
memcpy(arp->dest_add,(u_char *)ether_aton((char *)dmac),ETH_ALEN);

*(u_long *)arp->dest_ip = inet_addr((char *)dip);

send_packet((char *)dev,packet,packetsize);
}

int main(int argc, char *argv[]){
// sip - source IP
// dip = Dest IP
// mac - source MAC
// dev - dev

send_arp(dev, sip, dip, mac, "ff:ff:ff:ff:ff:ff");
}

Тут две функции с помощью которых можно послать ARP REQUEST, а как принять ARP REPLY не заню. tcpdump показывает 2 пакета (REQUEST and REPLY) т.е. запрос правильный и пингуемый хост отвечает. Пытаюсь что-то принять, но приходит какае-то чушь. Ни разу не поймал то что нужно. (использовал recv)

Очень не хочется использовать pcap или libnet.


Есть такая программа -- `arping`. Делает то, что тебе нужно. Если хочешь сам писать что-то подобное, можешь в исходники этой проги глянуть.

anonymous
()
Ответ на: комментарий от anonymous

Знаю я такую программу как arping, но там есть одно НО, она пингует хост 1 раз в секунду, без учета задержки на пакете. А что касается исходников, то все что я пока находил использует libnet или pcap. Поэтому не подходит.

nevsky
() автор топика

Писал пару лет назад прогу, которая тупо слушала интерфейс на предмет ARP-Request / ARP-Response и таким образом определяла, какие компы в сети включены. Принимал ARP recv'ом - все было нормально... Да и не может recv не принять пакет. Скорее всего ты неправильно расшифровываеш его содержимое. Проверь наличие ntohs/ntohl в нужных местах. Проверь правильность размеров элементов структуры запроса (может тупо смещаются поля). Проверь код на предмет выравнивания на границу байта/слова.

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