Created
April 13, 2013 08:30
-
-
Save KOBA789/5377599 to your computer and use it in GitHub Desktop.
ARP Capture
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/socket.h> | |
#include <sys/ioctl.h> | |
#include <net/ethernet.h> | |
#include <netpacket/packet.h> | |
#include <netinet/if_ether.h> | |
#include <linux/if.h> | |
int init_socket (char *device) { | |
int sock, err; | |
struct ifreq ifreq; | |
struct sockaddr_ll sa; | |
sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); | |
if (sock < 0) { | |
return -1; | |
} | |
memset(&ifreq, 0, sizeof(struct ifreq)); | |
strncpy(ifreq.ifr_name, device, sizeof(ifreq.ifr_name)-1); | |
if (ioctl(sock, SIOCGIFINDEX, &ifreq) < 0) { | |
close(sock); | |
return -1; | |
} | |
sa.sll_family = PF_PACKET; | |
sa.sll_protocol = htons(ETH_P_ALL); | |
sa.sll_ifindex = ifreq.ifr_ifindex; | |
if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) { | |
close(sock); | |
return -1; | |
} | |
if (err = ioctl(sock, SIOCGIFFLAGS, &ifreq) < 0) { | |
close(sock); | |
return err; | |
} | |
ifreq.ifr_flags=ifreq.ifr_flags | IFF_PROMISC; | |
if (err = ioctl(sock, SIOCSIFFLAGS, &ifreq) < 0) { | |
close(sock); | |
return err; | |
} | |
return sock; | |
} | |
const EH_SIZE = sizeof(struct ether_header); | |
char *mac_ntoa (u_char *mac, char *buf, int size) { | |
snprintf(buf, size, "%02x:%02x:%02x:%02x:%02x:%02x", | |
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | |
return buf; | |
} | |
char *ip8_ntoa (u_int8_t *ip, char *buf, int size) { | |
snprintf(buf, size, "%u.%u.%u.%u", | |
ip[0], ip[1], ip[2], ip[3]); | |
return buf; | |
} | |
int show_header (struct ether_header *header) { | |
char buf[80]; | |
printf("|+-ether header-----------------------------------\n"); | |
printf("|| destination: %s\n", mac_ntoa(header->ether_dhost, buf, sizeof(buf))); | |
printf("|| source: %s\n", mac_ntoa(header->ether_shost, buf, sizeof(buf))); | |
printf("|+------------------------------------------------\n"); | |
} | |
int show_arp (struct ether_arp *arp) { | |
char buf[80]; | |
int op; | |
op = ntohs(arp->arp_op); | |
printf("|+-ARP--------------------------------------------\n"); | |
printf("|| operation: %s\n", (op == 1) ? "ARP request" : ((op == 2) ? "ARP reply" : "unknown")); | |
printf("|| source ip: %s\n", ip8_ntoa(arp->arp_spa, buf, sizeof(buf))); | |
printf("|| source mac: %s\n", mac_ntoa(arp->arp_sha, buf, sizeof(buf))); | |
printf("|| target ip: %s\n", ip8_ntoa(arp->arp_tpa, buf, sizeof(buf))); | |
printf("|| target mac: %s\n", mac_ntoa(arp->arp_tha, buf, sizeof(buf))); | |
printf("|+------------------------------------------------\n"); | |
} | |
int analize (int *i, u_char *chunk, int size) { | |
u_char *ptr; | |
int lest; | |
struct ether_header *header; | |
struct ether_arp *arp; | |
ptr = chunk; | |
lest = size; | |
if (lest < EH_SIZE) { | |
return 0; | |
} | |
header = (struct ether_header *)ptr; | |
ptr += EH_SIZE; | |
lest -= EH_SIZE; | |
if (ntohs(header->ether_type) == ETHERTYPE_ARP) { | |
printf("+[%04d]-------------------------------------------\n", *i); | |
show_header(header); | |
arp = (struct ether_arp *)ptr; | |
show_arp(arp); | |
printf("+-------------------------------------------------\n\n"); | |
*i = *i + 1; | |
} | |
} | |
int main (int argc, char *argv[]) { | |
int sock, size, i; | |
u_char buf[65535]; | |
i = 0; | |
sock = init_socket(argv[1]); | |
if (sock < 0) { | |
return -1; | |
} | |
while (size = read(sock, buf, sizeof(buf))) { | |
if (analize(&i, buf, size) < 0) { | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment