in_addr_t anubis_lookup_ip_address(const char *expression) { //get param char *buffer = anubis_parse_param("lookup_ip_address", expression); if(!buffer) return 0; if(!strcasecmp(buffer, "ff:ff:ff:ff:ff:ff") || !strcasecmp(buffer, "Broadcast")) { return INADDR_BROADCAST; }//end if else { arp_t *handle = arp_open(); struct arp_entry arp_entry = {0}; if(!handle) { anubis_perror("arp_open()"); return 0; }//end if addr_pton(buffer, &arp_entry.arp_ha); int ret = arp_loop(handle, arp_lookup_ip_address_callback, (void *)&arp_entry); if(ret == 1) { char *ip_address = addr_ntoa(&arp_entry.arp_pa); arp_close(handle); return anubis_ip_aton(ip_address); }//end if else { anubis_err("lookup_ip_address(): \"%s\" is not found\n", buffer); arp_close(handle); return 0; }//end else }//end else }//end anubis_lookup_ip_address
static void arpd_init(char *dev, int naddresses, char **addresses) { struct bpf_program fcode; char filter[1024], ebuf[PCAP_ERRBUF_SIZE], *dst; intf_t *intf; dst = arpd_expandips(naddresses, addresses); if ((arpd_arp = arp_open()) == NULL) err(1, "arp_open"); if ((intf = intf_open()) == NULL) err(1, "intf_open"); if (dev == NULL) { if ((dev = pcap_lookupdev(ebuf)) == NULL) errx(1, "pcap_lookupdev: %s", ebuf); } arpd_ifent.intf_len = sizeof(arpd_ifent); strncpy(arpd_ifent.intf_name, dev, sizeof(arpd_ifent.intf_name) - 1); arpd_ifent.intf_name[sizeof(arpd_ifent.intf_name) - 1] = '\0'; if (intf_get(intf, &arpd_ifent) < 0) err(1, "intf_get"); if (arpd_ifent.intf_addr.addr_type != ADDR_TYPE_IP || arpd_ifent.intf_link_addr.addr_type != ADDR_TYPE_ETH) errx(1, "bad interface configuration: not IP or Ethernet"); arpd_ifent.intf_addr.addr_bits = IP_ADDR_BITS; snprintf(filter, sizeof(filter), "arp %s%s%s and not ether src %s", dst ? "and (" : "", dst ? dst : "", dst ? ")" : "", addr_ntoa(&arpd_ifent.intf_link_addr)); if ((arpd_pcap = pcap_open_live(dev, 128, 0, 500, ebuf)) == NULL) errx(1, "pcap_open_live: %s", ebuf); if (pcap_compile(arpd_pcap, &fcode, filter, 1, 0) < 0 || pcap_setfilter(arpd_pcap, &fcode) < 0) errx(1, "bad pcap filter: %s", pcap_geterr(arpd_pcap)); #if defined(BSD) && defined(BIOCIMMEDIATE) { int on = 1; if (ioctl(pcap_fileno(arpd_pcap), BIOCIMMEDIATE, &on) < 0) err(1, "BIOCIMMEDIATE"); } #endif if ((arpd_eth = eth_open(dev)) == NULL) errx(1, "eth_open"); #ifndef LOG_PERROR #define LOG_PERROR 0 #endif openlog("arpd", LOG_PERROR|LOG_PID|LOG_CONS, LOG_DAEMON); syslog(LOG_INFO, "listening on %s: %s", dev, filter); }
static void fragroute_init(const char *dst, const char *outfile) { struct arp_entry arpent; struct intf_entry ifent; struct route_entry rtent; #ifdef WIN32 WSADATA wsdata; if (WSAStartup(MAKEWORD(2, 2), &wsdata) != 0) err(1, "couldn't initialize Winsock"); SetConsoleCtrlHandler(fragroute_signal, TRUE); #else signal(SIGINT, fragroute_signal); signal(SIGTERM, fragroute_signal); #endif if (addr_aton(dst, &ctx.dst) < 0) err(1, "destination address invalid"); if (ctx.dst.addr_bits != IP_ADDR_BITS) errx(1, "only /32 destinations supported at this time"); pkt_init(128); event_init(); // event_sigcb = fragroute_close; if ((ctx.arp = arp_open()) == NULL || (ctx.intf = intf_open()) == NULL || (ctx.route = route_open()) == NULL) err(1, "couldn't open kernel networking interfaces"); /* Find outgoing interface, addresses, and MTU. */ ifent.intf_len = sizeof(ifent); if (intf_get_dst(ctx.intf, &ifent, &ctx.dst) < 0) err(1, "couldn't determine outgoing interface"); memcpy(&ctx.src, &ifent.intf_addr, sizeof(ctx.src)); ctx.src.addr_bits = IP_ADDR_BITS; memcpy(&ctx.smac, &ifent.intf_link_addr, sizeof(ctx.smac)); ctx.mtu = ifent.intf_mtu; /* Open outgoing interface for sending. */ if ((ctx.eth = eth_open(ifent.intf_name)) == NULL) err(1, "couldn't open %s for sending", ifent.intf_name); /* Find destination MAC address. */ memcpy(&arpent.arp_pa, &ctx.dst, sizeof(arpent.arp_pa)); if (arp_get(ctx.arp, &arpent) < 0) { memcpy(&rtent.route_dst, &ctx.dst, sizeof(rtent.route_dst)); if (route_get(ctx.route, &rtent) < 0) err(1, "no route to %s", addr_ntoa(&rtent.route_dst)); memcpy(&arpent.arp_pa, &rtent.route_gw, sizeof(arpent.arp_pa)); if (arp_get(ctx.arp, &arpent) < 0) err(1, "no ARP entry for %s", addr_ntoa(&arpent.arp_pa)); } memcpy(&ctx.dmac, &arpent.arp_ha, sizeof(ctx.dmac)); /* Setup our tunnel. */ if ((ctx.tun = tun_open(&ctx.src, &ctx.dst, ctx.mtu)) == NULL) err(1, "couldn't initialize tunnel interface"); ctx.dfile = NULL; if (outfile && ((ctx.dfile = pcap_dump_open(ctx.tun->pcap, outfile)) == NULL)) err(1, "couldn't open pcap dump file"); tun_register(ctx.tun, fragroute_process, &ctx); }
u_int8_t *anubis_lookup_mac_address(const char *expression, const char *device) { //get param char *buffer = anubis_parse_param("lookup_mac_address", expression); if(!buffer) return NULL; if(!strcasecmp(buffer, "255.255.255.255") || !strcasecmp(buffer, "Broadcast")) { return (u_int8_t *)"\xff\xff\xff\xff\xff\xff"; }//end if else if(!strncasecmp(buffer, "224.", 4) || !strncasecmp(buffer, "239.", 4)) { char mac_address[MAC_ADDRSTRLEN] = {0}; int byte1 = 1, byte2 = 0, byte3 = 0, byte4 = 0; if(sscanf(buffer, "%d.%d.%d.%d", &byte1, &byte2, &byte3, &byte4) != 4) { anubis_err("lookup_mac_address(): \"%s\" is not found\n", buffer); return NULL; }//end if snprintf(mac_address, sizeof(mac_address), "01:00:5e:%02x:%02x:%02x", byte2, byte3, byte4); return anubis_mac_aton(mac_address); }//end if multicast else { arp_t *handle = arp_open(); struct arp_entry arp_entry = {0}; int arping = 0; if(!handle) { anubis_perror("arp_open()"); return NULL; }//end if addr_pton(buffer, &arp_entry.arp_pa); AGAIN: if(arp_get(handle, &arp_entry) == 0) { char *mac_address = addr_ntoa(&arp_entry.arp_ha); arp_close(handle); if(arping) { anubis_verbose("Found \"%s\" at \"%s\"\n", buffer, mac_address); }//end if found return anubis_mac_aton(mac_address); }//end if else { if(arping) { anubis_err("lookup_mac_address(): \"%s\" is not found\n", buffer); arp_close(handle); return NULL; }//end if else { //try to arping anubis_verbose("MAC address of \"%s\" is not found in the ARP cache, trying to arping \"%s\"\n", buffer, buffer); pid_t pid = fork(); if(pid == 0) { FILE *temp_out_stream = out_stream; FILE *temp_err_stream = err_stream; int out_fail = 0; int err_fail = 0; out_stream = anubis_null_stream(); err_stream = anubis_null_stream(); if(!out_stream) { out_stream = temp_out_stream; out_fail = 1; }//end if if(!err_stream) { err_stream = temp_err_stream; err_fail = 1; }//end if //arping 3 three times for(int i = 0 ; i < 3 ; i++) anubis_arping(device, buffer); anubis_wait_microsecond(800000); //wait 800 ms //restore if(!out_fail) { fclose(out_stream); out_stream = temp_out_stream; }//end if if(!err_fail) { fclose(err_stream); err_stream = temp_err_stream; }//end if exit(0); }//end if else if(pid < 0) { anubis_perror("fork()"); }//end if #ifdef __CYGWIN__ wait(0); #else wait(NULL); #endif //wait fork finish arping = 1; goto AGAIN; } }//end else }//end else }//end anubis_lookup_mac_address