11-09-05 07:49 AM
Hello, All!
I'm trying to use raw sockets to capture ARP packets under Linux (kernel
2.4.20). What I've done is this short test code:
<skip headers>
#define BUFSIZE 2048
void
dumpPacket2(unsigned char *packet, const char *proto)
{
struct ethhdr *ether = (struct ethhdr *)packet;
struct arphdr *arp;
printf("%-6s : ", proto);
printf("%02X:%02X:%02X:%02X:%02X:%02X ",
ether->h_dest[0], ether->h_dest[1], ether->h_dest[2],
ether->h_dest[3], ether->h_dest[4], ether->h_dest[5]);
printf("%02X:%02X:%02X:%02X:%02X:%02X\n",
ether->h_source[0], ether->h_source[1], ether->h_source[2],
ether->h_source[3], ether->h_source[4], ether->h_source[5]);
arp = (struct arphdr *)(packet + sizeof(struct ethhdr));
printf("Hardware type: %d\n", ntohs(arp->ar_hrd));
printf("Protocol type: %d\n", ntohs(arp->ar_pro));
printf("HW address length: %d\n", arp->ar_hln);
printf("Proto address length: %d\n", arp->ar_pln);
printf("ARP code: %d\n", ntohs(arp->ar_op));
printf("\n");
}
int main(void)
{
int sock;
ssize_t n;
unsigned char buffer[BUFSIZE];
struct ifreq req;
if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 0) {
perror("socket() error");
return -1;
}
/* bind device to the socket */
strncpy(req.ifr_name, "eth0", sizeof(req.ifr_name));
if (ioctl(sock, SIOCGIFFLAGS, &req) < 0) {
perror("ioctl-get");
return -1;
}
/* set the interface promiscous mode */
req.ifr_flags |= IFF_PROMISC;
if (ioctl(sock, SIOCSIFFLAGS, &req) < 0) {
perror("ioctl-set");
return -1;
}
printf("Initialized !\n");
if ( (n = read(sock, buffer, BUFSIZE)) <= 0 ) {
printf("read() <= 0\n");
return -1;
}
fprintf(stdout, "got %d bytes packet\n", n); fflush(stdout);
dumpPacket2(buffer, "ARP");
req.ifr_flags &= ~(IFF_PROMISC);
return 0;
}
Compile it with "gcc -W -Wall -ansi -pedantic -g -o raw raw.c" succesfully,
run it and run into problem: result I get is wrong.
ARP : FF:FF:FF:FF:FF:FF 00:50:18:21:B1:F4
Hardware type: 1
Protocol type: 2048
HW address length: 6
Proto address length: 4
ARP code: 1
Why is 'proto type' broken here? (In debbuger I see memory area pointed by
'*arp' and see correct and nice values). This field in 'arphdr' is declared
with 'unsigned char' type, so as I understand - no need to make network-host
byte order convertation. Where's my mistake?
TIA.
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
[ Post a follow-up to this message ]
|