int main(int argc, char* argv[]) { if(argc!=2) { fprintf(stderr, "Invalid arguments!\n"); exit(EXIT_FAILURE); } return get_hw_addr(argv[1]); }
int main ( int argc, char** argv ) { struct in_addr src_in_addr, targ_in_addr; struct arp_packet pkt; struct sockaddr sa; int sock; if ( argc != 5 ) die(usage) ; sock = socket( AF_INET, SOCK_PACKET, htons(ETH_P_RARP) ) ; if ( sock < 0 ){ perror("socket"); exit(1); } pkt.frame_type = htons(ARP_FRAME_TYPE); pkt.hw_type = htons(ETHER_HW_TYPE); pkt.prot_type = htons(IP_PROTO_TYPE); pkt.hw_addr_size = ETH_HW_ADDR_LEN; pkt.prot_addr_size = IP_ADDR_LEN; pkt.op = htons(OP_ARP_REQUEST); get_hw_addr( pkt.targ_hw_addr, argv[4] ); get_hw_addr( pkt.rcpt_hw_addr, argv[4] ); get_hw_addr( pkt.src_hw_addr, argv[2] ); get_hw_addr( pkt.sndr_hw_addr, argv[2] ); get_ip_addr( &src_in_addr, argv[1] ); get_ip_addr( &targ_in_addr, argv[3] ); memcpy( pkt.sndr_ip_addr, &src_in_addr, IP_ADDR_LEN ); memcpy( pkt.rcpt_ip_addr, &targ_in_addr, IP_ADDR_LEN ); bzero( pkt.padding, 18 ); strcpy( sa.sa_data, DEFAULT_DEVICE ) ; if ( sendto( sock, &pkt,sizeof(pkt), 0, &sa,sizeof(sa) ) < 0 ){ perror("sendto"); exit(1); } exit(0); } ; // main
libnet_t* mk_packet(libnet_t* lntag, u_int32_t ip, u_char *device, u_char macaddr[6], u_char *broadcast, u_char *netmask, u_short arptype) { u_char *target_mac; u_char device_mac[6]; u_char bcast_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u_char zero_mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (arptype == ARPOP_REQUEST) { target_mac = zero_mac; } else if (arptype == ARPOP_REPLY) { target_mac = macaddr; } else { cl_log(LOG_ERR, "unkonwn arptype:"); return NULL; } /* * ARP header */ if (libnet_build_arp(ARPHRD_ETHER, /* hardware address type */ ETHERTYPE_IP, /* protocol address type */ 6, /* Hardware address length */ 4, /* protocol address length */ arptype, /* ARP operation type */ macaddr, /* sender Hardware address */ (u_int8_t *)&ip, /* sender protocol address */ target_mac, /* target hardware address */ (u_int8_t *)&ip, /* target protocol address */ NULL, /* Payload */ 0, /* Length of payload */ lntag, /* libnet context pointer */ 0 /* packet id */ ) == -1 ) { cl_log(LOG_ERR, "libnet_build_arp failed:"); return NULL; } /* Ethernet header */ if (get_hw_addr((char *)device, device_mac) < 0) { cl_log(LOG_ERR, "Cannot find mac address for %s", device); return NULL; } if (libnet_build_ethernet(bcast_mac, device_mac, ETHERTYPE_ARP, NULL, 0 , lntag, 0) == -1 ) { cl_log(LOG_ERR, "libnet_build_ethernet failed:"); return NULL; } return lntag; }
int send_arp(struct libnet_link_int *l, u_int32_t ip, u_char *device, u_char *macaddr, u_char *broadcast, u_char *netmask, u_short arptype) { int n; u_char *buf; u_char *target_mac; u_char device_mac[6]; u_char bcast_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u_char zero_mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (libnet_init_packet(LIBNET_ARP_H + LIBNET_ETH_H, &buf) == -1) { cl_log(LOG_ERR, "libnet_init_packet memory:"); return -1; } /* Convert ASCII Mac Address to 6 Hex Digits. */ /* Ethernet header */ if (get_hw_addr((char*)device, device_mac) < 0) { cl_log(LOG_ERR, "Cannot find mac address for %s", device); return -1; } if (libnet_build_ethernet(bcast_mac, device_mac, ETHERTYPE_ARP, NULL, 0 , buf) == -1) { cl_log(LOG_ERR, "libnet_build_ethernet failed:"); libnet_destroy_packet(&buf); return -1; } if (arptype == ARPOP_REQUEST) { target_mac = zero_mac; } else if (arptype == ARPOP_REPLY) { target_mac = macaddr; } else { cl_log(LOG_ERR, "unkonwn arptype:"); return -1; } /* * ARP header */ if (libnet_build_arp(ARPHRD_ETHER, /* Hardware address type */ ETHERTYPE_IP, /* Protocol address type */ 6, /* Hardware address length */ 4, /* Protocol address length */ arptype, /* ARP operation */ macaddr, /* Source hardware addr */ (u_char *)&ip, /* Target hardware addr */ target_mac, /* Destination hw addr */ (u_char *)&ip, /* Target protocol address */ NULL, /* Payload */ 0, /* Payload length */ buf + LIBNET_ETH_H) == -1) { cl_log(LOG_ERR, "libnet_build_arp failed:"); libnet_destroy_packet(&buf); return -1; } n = libnet_write_link_layer(l, (char*)device, buf, LIBNET_ARP_H + LIBNET_ETH_H); if (n == -1) { cl_log(LOG_ERR, "libnet_build_ethernet failed:"); } libnet_destroy_packet(&buf); return (n); }
int main(int argc, char *argv[]) { int c = -1; char errbuf[LIBNET_ERRBUF_SIZE]; char* device; char* ipaddr; char* macaddr; char* broadcast; char* netmask; u_int32_t ip; u_char src_mac[6]; LTYPE* l; int repeatcount = 1; int j; long msinterval = 1000; int flag; char pidfilenamebuf[64]; char *pidfilename = NULL; CL_SIGNAL(SIGTERM, byebye); CL_SIGINTERRUPT(SIGTERM, 1); cl_log_set_entity(SENDARPNAME); cl_log_enable_stderr(TRUE); cl_log_set_facility(LOG_USER); cl_inherit_logging_environment(0); while ((flag = getopt(argc, argv, "i:r:p:")) != EOF) { switch(flag) { case 'i': msinterval= atol(optarg); break; case 'r': repeatcount= atoi(optarg); break; case 'p': pidfilename= optarg; break; default: fprintf(stderr, "%s\n\n", print_usage); return 1; break; } } if (argc-optind != 5) { fprintf(stderr, "%s\n\n", print_usage); return 1; } /* * argv[optind+1] DEVICE dc0,eth0:0,hme0:0, * argv[optind+2] IP 192.168.195.186 * argv[optind+3] MAC ADDR 00a0cc34a878 * argv[optind+4] BROADCAST 192.168.195.186 * argv[optind+5] NETMASK ffffffffffff */ device = argv[optind]; ipaddr = argv[optind+1]; macaddr = argv[optind+2]; broadcast = argv[optind+3]; netmask = argv[optind+4]; if (!pidfilename) { if (snprintf(pidfilenamebuf, sizeof(pidfilenamebuf), "%s%s", PIDFILE_BASE, ipaddr) >= (int)sizeof(pidfilenamebuf)) { cl_log(LOG_INFO, "Pid file truncated"); return EXIT_FAILURE; } pidfilename = pidfilenamebuf; } if(write_pid_file(pidfilename) < 0) { return EXIT_FAILURE; } #if defined(HAVE_LIBNET_1_0_API) #ifdef ON_DARWIN if ((ip = libnet_name_resolve((unsigned char*)ipaddr, 1)) == -1UL) { #else if ((ip = libnet_name_resolve(ipaddr, 1)) == -1UL) { #endif cl_log(LOG_ERR, "Cannot resolve IP address [%s]", ipaddr); unlink(pidfilename); return EXIT_FAILURE; } l = libnet_open_link_interface(device, errbuf); if (!l) { cl_log(LOG_ERR, "libnet_open_link_interface on %s: %s" , device, errbuf); unlink(pidfilename); return EXIT_FAILURE; } #elif defined(HAVE_LIBNET_1_1_API) if ((l=libnet_init(LIBNET_LINK, device, errbuf)) == NULL) { cl_log(LOG_ERR, "libnet_init failure on %s: %s", device, errbuf); unlink(pidfilename); return EXIT_FAILURE; } if ((signed)(ip = libnet_name2addr4(l, ipaddr, 1)) == -1) { cl_log(LOG_ERR, "Cannot resolve IP address [%s]", ipaddr); unlink(pidfilename); return EXIT_FAILURE; } #else # error "Must have LIBNET API version defined." #endif if (!strcasecmp(macaddr, AUTO_MAC_ADDR)) { if (get_hw_addr(device, src_mac) < 0) { cl_log(LOG_ERR, "Cannot find mac address for %s", device); unlink(pidfilename); return EXIT_FAILURE; } } else { convert_macaddr((unsigned char *)macaddr, src_mac); } /* * We need to send both a broadcast ARP request as well as the ARP response we * were already sending. All the interesting research work for this fix was * done by Masaki Hasegawa <*****@*****.**> and his colleagues. */ for (j=0; j < repeatcount; ++j) { c = send_arp(l, ip, (unsigned char*)device, src_mac , (unsigned char*)broadcast, (unsigned char*)netmask , ARPOP_REQUEST); if (c < 0) { break; } mssleep(msinterval / 2); c = send_arp(l, ip, (unsigned char*)device, src_mac , (unsigned char *)broadcast , (unsigned char *)netmask, ARPOP_REPLY); if (c < 0) { break; } if (j != repeatcount-1) { mssleep(msinterval / 2); } } unlink(pidfilename); return c < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } void convert_macaddr (u_char *macaddr, u_char enet_src[6]) { int i, pos; u_char bits[3]; pos = 0; for (i = 0; i < 6; i++) { /* Inserted to allow old-style MAC addresses */ if (*macaddr == ':') { pos++; } bits[0] = macaddr[pos++]; bits[1] = macaddr[pos++]; bits[2] = '\0'; enet_src[i] = strtol((const char *)bits, (char **)NULL, 16); } }
/** * Packet dispatcher function. * * This function takes the traffic received from the SIMICS networtk interfaces & * Esta funcion manda los paquetes recibidos y que han sido guardados en la lista de paquetes * por su correspondiente socket de destino, o sea, que despacha los paquetes recibidos a su destino. * @param list_sockets a list containing the connected sockets from SIMICS. * @param list_packets a list containing the data frames within FSIN. */ void packet_dispatcher(list * list_sockets, list * list_packets){ struct packet * pack; char * buf; int escritor; unsigned short count, aux_len; struct arp_record * aux; int i=0,j=0; struct in_addr targ_in_addr; u_char targ_hw_addr[ETH_ALEN]; char clear_stats = CLEAR_STATS, get_stats = GET_STATS; get_hw_addr(targ_hw_addr,TARG_HW_ADDR); get_ip_addr(&targ_in_addr,TARG_IP_ADDR); veces_que_entra_FSIN ++; while (TRUE){ pack = (struct packet *) StartLoop(list_packets); //if(pack == NULL) printf ("no hay paquetes en la lista de paquetes\n"); for (; pack; pack = (struct packet *) GetNext(list_packets)){ // Ver si la trama ethernet ha sido tratada anteriormente // para no volver a tratarla //printf("Dispatcher: trama %d, encoladas: %d\n", pack->id_ethernet_frame, ElementsInList(list_packets)); //if (pack->num_FSIN_packets != 0) continue; buf = pack->buffer; count = pack->length; escritor = pack->socket; if (!memcmp(buf + sizeof(when) + sizeof(count), broadcast, ETH_ALEN)){ // el paquete es un broadcast arp hay que mandarlo a todos // habria que insertar el mismo paquete en la lista de paquetes // pero destinado a cada uno de los nodos repetidas veces // todavia no lo implementamos y simplemente se manda directamente // como antes en la version standalone de SIMICS-TrGen aux = (struct arp_record *) StartLoop(list_sockets); for (; aux; aux = (struct arp_record *) GetNext(list_sockets)){ //printf("Sockets en lista: %d\n", ElementsInList(list_sockets)); if (aux->socket != sock && aux->socket != escritor){ write(aux->socket, buf, count + sizeof(when) + sizeof(count)); if (DEBUG >=5) printf("escribe un ARP broadcast en socket:%d, paquete:%d\n", aux->socket, ++aux->paquetes); } } // Destruir la trama ethernet RemoveFromList(list_packets, pack); free(pack->buffer); free(pack); } else if(!memcmp(buf + sizeof(when) + sizeof(count), targ_hw_addr, ETH_ALEN) && !memcmp(buf + sizeof(when) + sizeof(count) + ETH_ALEN*2 + 18, &targ_in_addr, IP_ADDR_LEN) && !memcmp(buf + sizeof(when) + sizeof(count) + ETH_ALEN*2 + 30, &clear_stats, sizeof(char))){ printf("Special ICMP packet received, cleaning FSIN statistics\n"); /* It is a special packet for us to clear FSIN statistics (clear_fsin_stats)*/ /* Devolver el mensaje que ha llegado al proceso que lo ha mandado ya que lo esta esperando */ aux = (struct arp_record *) StartLoop(list_sockets); for (; aux; aux = (struct arp_record *) GetNext(list_sockets)){ if(!memcmp(aux->StationAddress, buf + sizeof(when) + sizeof(count) + ETH_ALEN, ETH_ALEN)){ /* Encontrado el socket destino del mensaje */ /* Ahora hay que reformatear el mensaje para que le llegue al destino */ /* Primero intercambiar las MAC origen y destino */ SwapBytes(buf + sizeof(when) + sizeof(count), buf + sizeof(when) + sizeof(count) + ETH_ALEN, ETH_ALEN); /* Luego intercambiar las IP origen y destino */ SwapBytes(buf + sizeof(when) + sizeof(count) + 26, buf + sizeof(when) + sizeof(count) + 26 +IP_ADDR_LEN, IP_ADDR_LEN); /* Intercambiar los puertos origen y destino aunque sean el mismo en nuestro caso */ SwapBytes(buf + sizeof(when) + sizeof(count) + 34, buf + sizeof(when) + sizeof(count) + 36, 2); /* Calcular checksum de la cabecera udp y el payload */ memcpy(&aux_len, buf + sizeof(when) + sizeof(count) + 38, 2); *(unsigned short *)(buf + sizeof(when) + sizeof(count) + 40) = htons( csum ((unsigned short *) (buf + sizeof(when) + sizeof(count) + 34), ntohs(aux_len) >> 1)); /* calcular el checksum de la cabecera ip y de todo el contenido del paquete ip o sea la cabecera udp y el payload */ memcpy(&aux_len, buf + sizeof(when) + sizeof(count) + 16, 2); *(unsigned short *)(buf + sizeof(when) + sizeof(count) + 24) = htons( csum ((unsigned short *) buf + sizeof(when) + sizeof(count) + 14, ntohs(aux_len) >> 1)); write(aux->socket, buf, count + sizeof(when) + sizeof(count)); if (DEBUG >=5) printf("escribe respuesta a CLEAR_STATS en socket:%d\n", aux->socket); break; } } /* Inicializar las estadisticas */ clear_simics_fsin_stats(); // Destruir la trama ethernet RemoveFromList(list_packets, pack); free(pack->buffer); free(pack); } else if(!memcmp(buf + sizeof(when) + sizeof(count), targ_hw_addr, ETH_ALEN) &&
int str_to_macoct(const char *str, uint8_t oct[6]) { return get_hw_addr(oct,str); }
int str_to_mac(const char *str, struct MAC *m){ return get_hw_addr(m->mac,str); }
int main(int argc, char** argv) { unsigned long my_ip, my_netmask, my_prefix, network_len, cur_ip; int my_index; struct sockaddr sa; int sock; u_char hwaddr[MAC_ADDR_LEN]; char *ifname, *ifsend, *cindex; char ch; if (argc < 2) { print_usage(usage); } while ((ch = getopt(argc, argv, "d")) != -1) { switch(ch) { case 'd': opt_d = 1; break; case '?': default: goto args; } } args: argc -= optind; argv += optind; if (opt_d && !argc) { print_usage(usage); } // Sockets sock = NEWSOCKET(); ioctl_sock = NEWSOCKET(); // Recv timeout struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1; setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)); if ((sock < 0) || (ioctl_sock < 0)) { perror("Unable to create socket"); exit(1); } if (!(ifname = strdup(*argv)) || !(ifsend = strdup(*argv))) die("Cannot duplicate interface name\n"); /* * For an alias interface we use its data but we send * the actual packet on corresponding real interface */ if ((cindex = strchr(ifsend, ':'))) *cindex = '\0'; if (opt_d) { printf("Interface: %s\n", ifname); } sa.sa_family = AF_INET; strcpy(sa.sa_data, ifsend); get_hw_addr(hwaddr, ifname); my_ip = get_ip_addr(ifname); my_netmask = get_ip_mask(ifname); my_index = get_interface_index(ifname); my_prefix = my_ip & my_netmask; network_len = my_netmask ^ 0xffffffff; if (opt_d) { printf("Prefix: %lu\n", my_prefix); printf("Network length: %lu\n", network_len); } for (cur_ip = my_prefix + 1; cur_ip <= my_prefix + network_len; cur_ip++) { if (cur_ip == my_ip) continue; // Skip gratuitous ARP send_arp(sock, my_index, cur_ip, my_ip, hwaddr); detect_sonos(sock); } exit(0); }