Ejemplo n.º 1
0
/**
 *  Given an IP address, add a client corresponding to that IP to client list.
 *  Return a pointer to the new client list entry, or to an existing entry
 *  if one with the given IP already exists.
 *  Return NULL if no new client entry can be created.
 */
t_client *
client_list_add_client(const char *ip)
{
    t_client *client;
    char *mac, *token;
    s_config *config;

    if(!check_ip_format(ip)) {
        /* Inappropriate format in IP address */
        debug(LOG_NOTICE, "Illegal IP format [%s]", ip);
        return NULL;
    }

    if (!(mac = arp_get(ip))) {
        /* We could not get their MAC address */
        debug(LOG_NOTICE, "Could not arp MAC address for %s", ip);
        return NULL;
    }

    if ((client = client_list_find(ip, mac)) == NULL) {
        token = _client_list_make_auth_token(ip,mac);  /* get a new token */
        client = _client_list_append(ip, mac, token);
        free(token);
    } else {
        debug(LOG_INFO, "Client %s %s token %s already on client list",
              ip, mac, client->token);
    }
    free(mac);
    return client;
}
Ejemplo n.º 2
0
void 
http_callback_auth(httpd *webserver, request *r)
{
	t_client	*client;
	httpVar * token;
	char	*mac;
	if ((token = httpdGetVariableByName(r, "token"))) {
		/* They supplied variable "token" */
		if (!(mac = arp_get(r->clientAddr))) {
			/* We could not get their MAC address */
			debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
			send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address");
		} else {
			/* We have their MAC address */

			LOCK_CLIENT_LIST();
			
			if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
				debug(LOG_DEBUG, "New client for %s", r->clientAddr);
				client_list_append(r->clientAddr, mac, token->value);
			} else {
				debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip);
			}
			UNLOCK_CLIENT_LIST();
			authenticate_client(r);
			free(mac);
		}
	} else {
		/* They did not supply variable "token" */
		send_http_page(r, "WiFiDog error", "Invalid token");
	}
}
Ejemplo n.º 3
0
void
http_callback_auth(httpd * webserver, request * r)
{
    t_client *client;
    httpVar *token;
    char *mac;
    httpVar *logout = httpdGetVariableByName(r, "logout");
    const s_config *config = config_get_config();

    if ((token = httpdGetVariableByName(r, "token"))) {
        /* They supplied variable "token" */
        if (!(mac = arp_get(r->clientAddr))) {
            /* We could not get their MAC address */
            debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
            send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address");
        } else {
	    t_redir_node *node;
	    int index = 0;
	    LOCK_REDIR();
	    node = redir_list_find(mac);
	    if (node) {
		index = node->wlindex;
	    }
	    UNLOCK_REDIR();
            /* We have their MAC address */
            LOCK_CLIENT_LIST();

            if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
                debug(LOG_DEBUG, "New client for %s", r->clientAddr);
                client = client_list_add(r->clientAddr, mac, token->value);
		client->fw_connection_state = FW_MARK_REDIR;
		client->counters.active_duration = config->sessiontimeout[index-1];
            } else if (logout) {
                logout_client(client);
            } else {
                debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip);
            }

            UNLOCK_CLIENT_LIST();
            if (!logout) { /* applies for case 1 and 3 from above if */
                authenticate_client(r);
            }
            free(mac);
        }
    } else {
        /* They did not supply variable "token" */
        send_http_page(r, "WiFiDog error", "Invalid token");
    }
}
Ejemplo n.º 4
0
/**
 * @brief libmicrohttpd_cb called when the client do a request to this server
 * @param cls unused
 * @param connection - client connection
 * @param url - which url was called
 * @param method - POST / GET / ...
 * @param version http 1.0 or 1.1
 * @param upload_data - unused
 * @param upload_data_size - unused
 * @param ptr - unused
 * @return
 */
int
libmicrohttpd_cb(void *cls,
				 struct MHD_Connection *connection,
				 const char *url,
				 const char *method,
				 const char *version,
				 const char *upload_data, size_t *upload_data_size, void **ptr)
{

	t_client *client;
	char *ip_addr;
	char *mac;
	int ret;

	debug(LOG_DEBUG, "access: %s %s", method, url);

	/* only allow get */
	if(0 != strcmp(method, "GET")) {
		debug(LOG_DEBUG, "Unsupported http method %s", method);
		return send_error(connection, 503);
	}

	/* switch between preauth, authenticated */
	/* - always - set caching headers
	 * a) possible implementation - redirect first and serve them using a tempo redirect
	 * b) serve direct
	 * should all requests redirected? even those to .css, .js, ... or respond with 404/503/...
	 */

	ip_addr = get_ip(connection);
	mac = arp_get(ip_addr);

	client = client_list_find(ip_addr, mac);
	if(client) {
		if(client->fw_connection_state == FW_MARK_AUTHENTICATED ||
				client->fw_connection_state == FW_MARK_TRUSTED) {
			/* client already authed - dangerous!!! This should never happen */
			ret = authenticated(connection, ip_addr, mac, url, client);
			free(mac);
			free(ip_addr);
			return ret;
		}
	}
	ret = preauthenticated(connection, ip_addr, mac, url, client);
	free(mac);
	free(ip_addr);
	return ret;
}
Ejemplo n.º 5
0
static int
arpd_lookup(struct addr *addr)
{
	struct arp_entry arpent;
	int error;

	if (addr_cmp(addr, &arpd_ifent.intf_addr) == 0) {
		syslog(LOG_DEBUG, "%s: %s at %s", __func__,
		    addr_ntoa(addr), addr_ntoa(&arpd_ifent.intf_link_addr));
		return (0);
	}
	memcpy(&arpent.arp_pa, addr, sizeof(*addr));
	
	error = arp_get(arpd_arp, &arpent);
	
	if (error == -1) {
		syslog(LOG_DEBUG, "%s: no entry for %s", __func__,
		    addr_ntoa(addr));
	} else {
		syslog(LOG_DEBUG, "%s: %s at %s", __func__,
		    addr_ntoa(addr), addr_ntoa(&arpent.arp_ha));
	}
	return (error);
}
Ejemplo n.º 6
0
/** The 404 handler is also responsible for redirecting to the auth server */
void
http_callback_404(httpd * webserver, request * r, int error_code)
{
    char tmp_url[MAX_BUF], *url, *mac;
    s_config *config = config_get_config();
    t_auth_serv *auth_server = get_auth_server();

    memset(tmp_url, 0, sizeof(tmp_url));
    /* 
     * XXX Note the code below assumes that the client's request is a plain
     * http request to a standard port. At any rate, this handler is called only
     * if the internet/auth server is down so it's not a huge loss, but still.
     */
    snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s",
             r->request.host, r->request.path, r->request.query[0] ? "?" : "", r->request.query);
    url = httpdUrlEncode(tmp_url);

    if (!is_online()) {
        /* The internet connection is down at the moment  - apologize and do not redirect anywhere */
        char *buf;
        safe_asprintf(&buf,
                      "<p>We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.</p>"
                      "<p>If at all possible, please notify the owners of this hotspot that the internet connection is out of service.</p>"
                      "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
                      "<p>In a while please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);

        send_http_page(r, "Uh oh! Internet access unavailable!", buf);
        free(buf);
        debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server",
              r->clientAddr);
    } else if (!is_auth_online()) {
        /* The auth server is down at the moment - apologize and do not redirect anywhere */
        char *buf;
        safe_asprintf(&buf,
                      "<p>We apologize, but it seems that we are currently unable to re-direct you to the login screen.</p>"
                      "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
                      "<p>In a couple of minutes please <a href='%s'>click here</a> to try your request again.</p>",
                      tmp_url);

        send_http_page(r, "Uh oh! Login screen unavailable!", buf);
        free(buf);
        debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server",
              r->clientAddr);
    } else {
        /* Re-direct them to auth server */
        char *urlFragment;

        if (!(mac = arp_get(r->clientAddr))) {
            /* We could not get their MAC address */
            debug(LOG_INFO, "Failed to retrieve MAC address for ip %s, so not putting in the login request",
                  r->clientAddr);
            safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&ip=%s&url=%s",
                          auth_server->authserv_login_script_path_fragment, config->gw_address, config->gw_port,
                          config->gw_id, r->clientAddr, url);
        } else {
            debug(LOG_INFO, "Got client MAC address for ip %s: %s", r->clientAddr, mac);
            safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&ip=%s&mac=%s&url=%s",
                          auth_server->authserv_login_script_path_fragment,
                          config->gw_address, config->gw_port, config->gw_id, r->clientAddr, mac, url);
            free(mac);
        }

        // if host is not in whitelist, maybe not in conf or domain'IP changed, it will go to here.
        debug(LOG_INFO, "Check host %s is in whitelist or not", r->request.host);       // e.g. www.example.com
        t_firewall_rule *rule;
        //e.g. example.com is in whitelist
        // if request http://www.example.com/, it's not equal example.com.
        for (rule = get_ruleset("global"); rule != NULL; rule = rule->next) {
            debug(LOG_INFO, "rule mask %s", rule->mask);
            if (strstr(r->request.host, rule->mask) == NULL) {
                debug(LOG_INFO, "host %s is not in %s, continue", r->request.host, rule->mask);
                continue;
            }
            int host_length = strlen(r->request.host);
            int mask_length = strlen(rule->mask);
            if (host_length != mask_length) {
                char prefix[1024] = { 0 };
                // must be *.example.com, if not have ".", maybe Phishing. e.g. phishingexample.com
                strncpy(prefix, r->request.host, host_length - mask_length - 1);        // e.g. www
                strcat(prefix, ".");    // www.
                strcat(prefix, rule->mask);     // www.example.com
                if (strcasecmp(r->request.host, prefix) == 0) {
                    debug(LOG_INFO, "allow subdomain");
                    fw_allow_host(r->request.host);
                    http_send_redirect(r, tmp_url, "allow subdomain");
                    free(url);
                    free(urlFragment);
                    return;
                }
            } else {
                // e.g. "example.com" is in conf, so it had been parse to IP and added into "iptables allow" when wifidog start. but then its' A record(IP) changed, it will go to here.
                debug(LOG_INFO, "allow domain again, because IP changed");
                fw_allow_host(r->request.host);
                http_send_redirect(r, tmp_url, "allow domain");
                free(url);
                free(urlFragment);
                return;
            }
        }

        debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url);
        http_send_redirect_to_auth(r, urlFragment, "Redirect to login page");
        free(urlFragment);
    }
    free(url);
}
Ejemplo n.º 7
0
/** The 404 handler is also responsible for redirecting to the auth server */
    void
http_callback_404(httpd *webserver, request *r)
{
    char tmp_url[MAX_BUF],
         *url,
         *mac;
    s_config	*config = config_get_config();
    t_auth_serv	*auth_server = get_auth_server();

    memset(tmp_url, 0, sizeof(tmp_url));
    /*
     * XXX Note the code below assumes that the client's request is a plain
     * http request to a standard port. At any rate, this handler is called only
     * if the internet/auth server is down so it's not a huge loss, but still.
     */
    snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s",
            r->request.host,
            r->request.path,
            r->request.query[0] ? "?" : "",
            r->request.query);
    url = httpdUrlEncode(tmp_url);

    if (!is_online()) {
        /* The internet connection is down at the moment  - apologize and do not redirect anywhere */
        char * buf;
        safe_asprintf(&buf,
                "<p>We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.</p>"
                "<p>If at all possible, please notify the owners of this hotspot that the internet connection is out of service.</p>"
                "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
                "<p>In a while please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);

        send_http_page(r, "Uh oh! Internet access unavailable!", buf);
        free(buf);
        debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server", r->clientAddr);
    }
    else if (!is_auth_online()) {
        /* The auth server is down at the moment - apologize and do not redirect anywhere */
        char * buf;
        safe_asprintf(&buf,
                "<p>We apologize, but it seems that we are currently unable to re-direct you to the login screen.</p>"
                "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
                "<p>In a couple of minutes please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);

        send_http_page(r, "Uh oh! Login screen unavailable!", buf);
        free(buf);
        debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server", r->clientAddr);
    }
    else {
        //hector add 2014/3/18
        get_oauth_iplist();
        fw_set_oauthservers();
        //hector end
        /* Re-direct them to auth server */
        char *urlFragment;

        if (!(mac = arp_get(r->clientAddr))) {
            /* We could not get their MAC address */
            debug(LOG_INFO, "Failed to retrieve MAC address for ip %s, so not putting in the login request", r->clientAddr);
            safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s",
                    auth_server->authserv_login_script_path_fragment,
                    config->gw_address,
                    config->gw_port,
                    config->gw_id,
                    url);
        } else {
            debug(LOG_INFO, "Got client MAC address for ip %s: %s", r->clientAddr, mac);
            safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s",
                    auth_server->authserv_login_script_path_fragment,
                    config->gw_address,
                    config->gw_port,
                    config->gw_id,
                    mac,
                    url);
        }

        debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url);
        http_send_redirect_to_auth(r, urlFragment, "Redirect to login page");
        free(urlFragment);

    }
    free(url);
}
Ejemplo n.º 8
0
    void
http_callback_auth(httpd *webserver, request *r)
{
    t_client	*client;
    httpVar * token;
    char	*mac;
    httpVar *logout = httpdGetVariableByName(r, "logout");
    if ((token = httpdGetVariableByName(r, "token"))) {
        /* They supplied variable "token" */
        if (!(mac = arp_get(r->clientAddr))) {
            /* We could not get their MAC address */
            debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
            send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address");
        } else {
            /* We have their MAC address */

            LOCK_CLIENT_LIST();

            if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
                debug(LOG_DEBUG, "New client for %s", r->clientAddr);
                client_list_append(r->clientAddr, mac, token->value);
            } else if (logout) {
                t_authresponse  authresponse;
                s_config *config = config_get_config();
                unsigned long long incoming = client->counters.incoming;
                unsigned long long outgoing = client->counters.outgoing;
                char *ip = safe_strdup(client->ip);
                char *urlFragment = NULL;
                t_auth_serv	*auth_server = get_auth_server();

                fw_deny(client->ip, client->mac, client->fw_connection_state);
                client_list_delete(client);
                debug(LOG_DEBUG, "Got logout from %s", client->ip);

                /* Advertise the logout if we have an auth server */
                if (config->auth_servers != NULL) {
                    UNLOCK_CLIENT_LIST();
                    auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token->value,
                            incoming, outgoing);
                    LOCK_CLIENT_LIST();

                    /* Re-direct them to auth server */
                    debug(LOG_INFO, "Got manual logout from client ip %s, mac %s, token %s"
                            "- redirecting them to logout message", client->ip, client->mac, client->token);
                    safe_asprintf(&urlFragment, "%smessage=%s",
                            auth_server->authserv_msg_script_path_fragment,
                            GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT
                            );
                    http_send_redirect_to_auth(r, urlFragment, "Redirect to logout message");
                    free(urlFragment);
                }
                free(ip);
            }
            else {
                debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip);
            }
            UNLOCK_CLIENT_LIST();
            if (!logout) {
                authenticate_client(r);
            }
            free(mac);
        }
    } else {
        /* They did not supply variable "token" */
        send_http_page(r, "WiFiDog error", "Invalid token");
    }
}
Ejemplo n.º 9
0
/** Perform username/password check if configured to use it.
 */
int
http_nodogsplash_check_userpass(request *r, t_auth_target *authtarget)
{
	s_config *config;
	t_client  *client;
	config = config_get_config();
	int attempts = 0;
	char *ip;
	char *mac;

	if(!config->passwordauth && !config->usernameauth) {
		/* Not configured to use username/password check; can't fail. */
		return 1;
	}

	ip = r->clientAddr;

	if (!(mac = arp_get(ip))) {
		/* we could not get their MAC address; fail */
		debug(LOG_NOTICE, "Could not arp MAC address for %s to check user/password", ip);
		return 0;
	}

	/* We have their MAC address, find them on the client list
	   and increment their password attempt counter */
	LOCK_CLIENT_LIST();
	client = client_list_find(ip,mac);
	if(client) attempts = ++(client->attempts);
	UNLOCK_CLIENT_LIST();

	if(!client) {
		/* not on client list; fail */
		debug(LOG_NOTICE, "Client %s %s not on client list to check user/password",
			  ip, mac);
		free(mac);
		return 0;
	}

	if(attempts > config->passwordattempts) {
		/* too many attempts; fail */
		debug(LOG_NOTICE, "Client %s %s exceeded %d password attempts",
			  ip, mac, config->passwordattempts);
		free(mac);
		return 0;
	}

	if ((!config->usernameauth || (authtarget->username && !strcmp(config->username,authtarget->username)))
			&& (!config->passwordauth || (authtarget->password && !strcmp(config->password,authtarget->password)))) {
		/* password and username match; success */
		debug(LOG_NOTICE, "Client %s %s username/password '%s'/'%s'",
			  ip, mac,
			  authtarget->username,
			  authtarget->password);
		free(mac);
		return 1;
	}

	/* fail */
	debug(LOG_NOTICE, "Client %s %s bad username/password '%s'/'%s'",
		  ip, mac,
		  authtarget->username,
		  authtarget->password);
	free(mac);
	return 0;
}
Ejemplo n.º 10
0
/** The multipurpose authentication action handler
 */
void
http_nodogsplash_callback_action(request *r,
								 t_auth_target *authtarget,
								 t_authaction action)
{
	t_client	*client;
	char *mac;
	const char *ip;
	char *clienttoken = NULL;
	const char *requesttoken = authtarget->token;
	const char *redir = authtarget->redir;

	ip = r->clientAddr;

	if(!requesttoken) {
		debug(LOG_NOTICE, "No token in request from ip %s", ip);
		return;
	}
	if(!redir) {
		debug(LOG_NOTICE, "No redirect in request from ip %s", ip);
		return;
	}

	if (!(mac = arp_get(ip))) {
		/* We could not get their MAC address */
		debug(LOG_NOTICE, "Could not arp MAC address for %s action %d", ip, action);
		return;
	}

	/* We have their MAC address, find them on the client list */
	LOCK_CLIENT_LIST();
	client = client_list_find(ip,mac);
	if(client && client->token) {
		clienttoken = safe_strdup(client->token);
	}
	UNLOCK_CLIENT_LIST();

	if(!client) {
		debug(LOG_NOTICE, "Client %s %s action %d is not on client list",
			  ip, mac, action);
		http_nodogsplash_serve_info(r,
									"Nodogsplash Error",
									"You are not on the client list.");
		free(mac);
		return;
	}

	/* We have a client */

	/* Do we have a client token? */
	if(!clienttoken) {
		debug(LOG_NOTICE, "Client %s %s action %d does not have a token",
			  ip, mac, action);
		free(mac);
		return;
	}

	debug(LOG_DEBUG, "Action %d: %s %s tokens %s, %s",
		  action, ip, mac, clienttoken, requesttoken);
	debug(LOG_DEBUG, "Redirect:  %s", redir);

	/* Check token match */
	if (strcmp(clienttoken,requesttoken)) {
		/* tokens don't match, reject */
		debug(LOG_NOTICE, "Client %s %s tokens %s, %s do not match",
			  r->clientAddr, mac, clienttoken, requesttoken);
		http_nodogsplash_serve_info(r, "Nodogsplash Error",
									"Tokens do not match.");
		free(mac);
		free(clienttoken);
		return;
	}

	/* Log value of info string, if any */
	if(authtarget->info) {
		debug(LOG_NOTICE, "Client %s %s info: %s",
			  ip, mac, authtarget->info);
	}

	/* take action */
	switch(action) {
	case AUTH_MAKE_AUTHENTICATED:
		auth_client_action(ip,mac,action);
		http_nodogsplash_redirect(r, redir);
		break;
	case AUTH_MAKE_DEAUTHENTICATED:
		auth_client_action(ip,mac,action);
		http_nodogsplash_serve_info(r, "Nodogsplash Deny",
									"Authentication revoked.");
		break;
	default:
		debug(LOG_ERR, "Unknown auth action: %d", action);
	}

	free(mac);
	free(clienttoken);
	return;
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
/* arp */
void
rib_arp_get(struct in_addr *addr, char *mac, int *ifindex) {
  arp_get(addr, mac, ifindex);
}