/* Programme de démonstration de création d'un raw socket 17/11/2011 */ #include #include #include /* Network includes */ #include // socket(), PF_PACKET, SOCK_RAW, ... #include // struct sockaddr_ll, ... #include // ETH_P_ALL, struct ethhdr, ... #include // ioctl(), ... #include // struct ifreq, IFNAMSIZ, ... #include #include #define SIZMAXPACKET 1500 + 16 int raw_socket_connexion(char* device) { /* Création du socket */ int packet_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(packet_socket == -1) { perror("socket"); exit(EXIT_FAILURE); } /* Récupération de l'index d'une interface réseau */ struct ifreq interface; memset(&interface, 0, sizeof(struct ifreq)); strncpy(interface.ifr_name, device, IFNAMSIZ); if( ioctl(packet_socket, SIOCGIFINDEX, &interface) == -1) { perror("ioctl"); exit(EXIT_FAILURE); } /* Binding */ struct sockaddr_ll connexion; memset(&connexion, 0, sizeof(struct sockaddr_ll)); connexion.sll_family = AF_PACKET; connexion.sll_protocol = ETH_P_ALL; connexion.sll_ifindex = interface.ifr_ifindex; if(bind(packet_socket, (struct sockaddr *) &connexion, sizeof(struct sockaddr_ll)) == -1) { perror("bind"); exit(EXIT_FAILURE); } return packet_socket; } void capturerPaquet(int socket, char* packet) { struct sockaddr_ll packet_info; socklen_t packet_len; printf("waiting packet...\n"); if(recvfrom(socket, (void*)packet, SIZMAXPACKET, 0, (struct sockaddr*) &packet_info, &packet_len) == -1) { perror("recvfrom"); exit(EXIT_FAILURE); } char* addr = malloc(packet_info.sll_halen + 1); strncpy(addr, packet_info.sll_addr, packet_info.sll_halen); printf("A packet has been captured\n\tPhysical layer address : %s\n",addr); free(addr); } void parse_arp_header(char* packet) { /* Parsing ethernet header */ struct ethhdr ethernet_header; memcpy(ðernet_header, packet, sizeof(ethernet_header)); /* Analyse ethernet header*/ printf("Sender packet : %s\n", ethernet_header.h_dest); printf("Receiver packet : %s\n", ethernet_header.h_source); if(ethernet_header.h_proto == ETH_P_ARP) { printf("You catch an ARP packet\n"); struct arphdr arp_header; memcpy(&arp_header, packet+sizeof(ethernet_header), sizeof(struct arphdr)); printf("Format of hardware address : %d\n", arp_header.ar_hrd); printf("Format of protocol address : %d\n", arp_header.ar_pro); printf("Length of hardware address : %d\n", arp_header.ar_hln); printf("Length of protocol address : %d\n", arp_header.ar_pln); printf("Operation code : %d\n", arp_header.ar_op); char* sender_hardware_address = malloc(arp_header.ar_hln * sizeof(char) + 1); char* sender_protocol_address = malloc(arp_header.ar_pro * sizeof(char) + 1); char* receiv_hardware_address = malloc(arp_header.ar_hln * sizeof(char) + 1); char* receiv_protocol_address = malloc(arp_header.ar_pro * sizeof(char) + 1); strncpy(sender_hardware_address, packet+sizeof(struct ethhdr)+sizeof(struct arphdr), arp_header.ar_hln * sizeof(char)); strncpy(sender_protocol_address, packet+sizeof(struct ethhdr)+sizeof(struct arphdr)+arp_header.ar_hln*sizeof(char), arp_header.ar_pro * sizeof(char)); strncpy(receiv_hardware_address, packet+sizeof(struct ethhdr)+sizeof(struct arphdr)+arp_header.ar_hln*sizeof(char)+arp_header.ar_pro * sizeof(char), arp_header.ar_hln * sizeof(char)); strncpy(sender_protocol_address, packet+sizeof(struct ethhdr)+sizeof(struct arphdr)+arp_header.ar_hln*sizeof(char)*2+arp_header.ar_pro * sizeof(char), arp_header.ar_pro * sizeof(char)); printf("Sender hardware address : %s\n", sender_hardware_address); printf("Sender protocol address : %s\n", sender_protocol_address); printf("Receiver hardware address : %s\n", receiv_hardware_address); printf("Receiver protocol address : %s\n", receiv_protocol_address); free(sender_hardware_address); free(sender_protocol_address); free(receiv_hardware_address); free(receiv_protocol_address); } else printf("This packet is not an ARP packet. The protocole is : %d\n", ethernet_header.h_proto); } int main(int argc, char* argv []) { if(argc < 2) { fprintf(stderr, "%s interface\n",argv[0]); exit(EXIT_FAILURE); } int socket_handle = raw_socket_connexion(argv[1]); char paquet[SIZMAXPACKET]; capturerPaquet(socket_handle, paquet); parse_arp_header(paquet); close(socket_handle); return(EXIT_SUCCESS); }