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
Exemple #2
0
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);
}
Exemple #3
0
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