Esempio n. 1
0
unsigned
sqdb_get_bssid_packet(struct SQDB *sqdb, const unsigned char *bssid, unsigned type, struct SquirrelPacket *pkt)
{
	struct SQDB_AccessPoint *ap;
	unsigned i;

	pkt->px = (const unsigned char*)"";
	pkt->length = 1;
	pkt->secs = time(0);
	pkt->usecs = 0;
    pkt->linktype = 0;

	pixie_enter_critical_section(sqdb->cs);

    /* Grab the AP record */
	ap = sqdb_find_bssid(sqdb, bssid);
    if (ap == NULL)
        goto _end;

    /* Figure out which type of packet we need */
    if (type == SQPKT_BEACON)
        i = 0;
    else if (type == SQPKT_PROBERESPONSE)
        i = 1;
    else
        goto _end;

    /* Copy the packet over */
	memcpy(pkt, &ap->packets[i], sizeof(*pkt));

_end:
	pixie_leave_critical_section(sqdb->cs);
	return 1;
}
Esempio n. 2
0
void regmac_base_crypto(struct SQDB *sqdb, const unsigned char *bssid, unsigned crypto)
{
	struct SQDB_AccessPoint *entry;

	pixie_enter_critical_section(sqdb->cs);

	entry = sqdb_create_bssid(sqdb, bssid);

	switch (crypto) {
	case ENC_TYPE_WEP	:
	case ENC_TYPE_WEP40	:
	case ENC_TYPE_WEP128	:
	case ENC_TYPE_WPA	:
	case ENC_TYPE_WPA2	:
		if (entry->encryption_type < crypto)
			entry->encryption_type = crypto;
		break;
	case CIPHER_TYPE_WEP	:
	case CIPHER_TYPE_TKIP:
	case CIPHER_TYPE_AES:
		if (entry->cipher_type < crypto)
			entry->cipher_type = crypto;
		break;
	case AUTH_TYPE_OPEN	:
	case AUTH_TYPE_SKA	:
	case AUTH_TYPE_EAP	:
	case AUTH_TYPE_PSK	:
	case AUTH_TYPE_MGMT:
		entry->auth_type = crypto;
		break;
	default:
		;
	}
	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 3
0
const unsigned char *
sqdb_lookup_bssid_by_access_point(struct SQDB *sqdb, const unsigned char *mac_address)
{
	unsigned i;
	const unsigned char *result = NULL;

	pixie_enter_critical_section(sqdb->cs);

	for (i=0; i<sizeof(sqdb->access_points)/sizeof(sqdb->access_points[0]); i++) {
		struct SQDB_AccessPoint *x;


		for (x = sqdb->access_points[i]; x; x = x->next) {
			struct EntryMacAddr *y;
			
			if (memcmp(mac_address, x->bssid, 6) == 0) {
				result = x->bssid;
				goto _return;
			}

			for (y = &x->mac_address; y; y = y->next) {
				if (memcmp(mac_address, y->addr, 6) == 0) {
					result = x->bssid;
					goto _return;
				}
			}
		}
	}
_return:
	pixie_leave_critical_section(sqdb->cs);
	return result;
}
Esempio n. 4
0
unsigned regmac_base_resolve_direction(struct SQDB *sqdb, const unsigned char *bssid, const unsigned char *src, const unsigned char *dst)
{
	struct SQDB_AccessPoint *entry;
	struct EntryMacAddr *mac;
	unsigned dir = DIR_UNKNOWN;

	pixie_enter_critical_section(sqdb->cs);

	if (memcmp(bssid, src, 6) == 0) {
		regmac_base(sqdb, bssid, bssid);
		regmac_station(sqdb, bssid, dst, -1);
		dir = DIR_BASE_TO_STA;
	} else if (memcmp(bssid, dst, 6) == 0) {
		regmac_base(sqdb, bssid, bssid);
		regmac_station(sqdb, bssid, src, -1);
		dir = DIR_STA_TO_BASE;
	} else {
		/* Neither matches, so let's see if this is a different
		 * access-point in the BSS */
		entry = sqdb_create_bssid(sqdb, bssid);
		for (mac = &entry->mac_address; mac; mac = mac->next) {
			if (memcmp(mac->addr, src, 6) == 0) {
				regmac_station(sqdb, bssid, dst, -1);
				dir = DIR_BASE_TO_STA;
				break;
			} else if (memcmp(mac->addr, dst, 6) == 0) {
				regmac_station(sqdb, bssid, src, -1);
				dir = DIR_STA_TO_BASE;
			}
		}
	}

	pixie_leave_critical_section(sqdb->cs);
	return dir;
}
Esempio n. 5
0
void
regmac_base_ssid(struct SQDB *sqdb, const unsigned char *bssid, struct SQDB_String *ssid)
{
	struct SQDB_AccessPoint *entry;

    /* Ignore empty SSIDs */
    if (ssid->length == 0)
        return;
    if (ssid->length == 1 && ssid->value[0] == '\0')
        return;

	pixie_enter_critical_section(sqdb->cs);

	entry = sqdb_create_bssid(sqdb, bssid);

	if (!sqdb_string_is_equal(&entry->ssid, ssid)) {
		if (entry->ssid.length > 0) {
			SQUIRREL_EVENT("[%02X:%02X:%02X:%02X:%02X:%02X]  SSID=\"%.*s\" (was \"%.*s\")\n", 
				PRINTMAC(bssid),
				PRINTSTR(ssid),
				PRINTSTR(&entry->ssid));
		}
		sqdb_string_copy(&entry->ssid, ssid);
		/*FIXME: we should support seeing multiple SSIDs on a BSSID */
	}
	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 6
0
/**
 * Lookup access point by BSSID
 */
static struct SQDB_AccessPoint *
sqdb_create_bssid(struct SQDB *sqdb, const unsigned char *bssid)
{
	struct SQDB_AccessPoint **r_entry;
	unsigned index = bssid_hash(bssid);

	pixie_enter_critical_section(sqdb->cs);

	r_entry = &sqdb->access_points[index];
	while ((*r_entry) && memcmp((*r_entry)->bssid, bssid, 6) != 0)
		r_entry = &((*r_entry)->next);
	if (*r_entry == NULL) {
		struct XMAC *xmac;

		*r_entry = (struct SQDB_AccessPoint*)malloc(sizeof(**r_entry));
		memset(*r_entry, 0, sizeof(**r_entry));
		memcpy((*r_entry)->bssid, bssid, 6);
        if (sqdb->kludge.channel) {
            (*r_entry)->channels[0] = sqdb->kludge.channel;
            (*r_entry)->channel_count = 1;
        }

		/* Create a link to this from the master MAC address registery */
		xmac = xmac_create(&sqdb->macs, bssid);
		xmac->type = STATION_TYPE_BASE;
		xmac->base = *r_entry;
        (*r_entry)->first = sqdb->kludge.time_stamp;
	}

    (*r_entry)->last = sqdb->kludge.time_stamp;
	pixie_leave_critical_section(sqdb->cs);
	return *r_entry;
}
Esempio n. 7
0
struct TMP_STATIONS *
sqdb_find_station(struct SQDB *sqdb, const unsigned char *mac, unsigned *count)
{
    struct TMP_STATIONS *result = 0;
    unsigned i;
    unsigned maxcount = 0;
    *count = 0;

   	pixie_enter_critical_section(sqdb->cs);

    memset(&result, 0, sizeof(result));

    /*
     * Look for a "prober" record
     */
    {
    	struct SQDB_Station *entry;
		unsigned index = bssid_hash(mac);

		entry = sqdb->stations[index];
		while (entry && memcmp(entry->mac_address, mac, 6) != 0)
			entry = entry->next;
        if (entry != NULL) {
            result = alloc_tmp_stations(result, count, &maxcount);
            result[*count].type = 1;
            result[*count].sta.unassociated = entry;
            result[*count].last_update = entry->dbm_last_update;
            (*count)++;
        }
    }

    /* Look for Associated station */
    for (i=0; i<sizeof(sqdb->access_points)/sizeof(sqdb->access_points[0]); i++) {
        struct SQDB_AccessPoint *ap;
        
        ap = sqdb->access_points[i];
        while (ap) {
            struct SQDB_SubStation *sta;

            sta = ap->substations;
            while (sta) {
                if (memcmp(sta->mac_address, mac, 6) == 0) {
                    result = alloc_tmp_stations(result, count, &maxcount);
                    result[*count].type = 2;
                    result[*count].sta.associated = sta;
                    result[*count].last_update = sta->dbm_last_update;
                    result[*count].sta.accesspoint = ap;
                    (*count)++;
                    break;
                }
                sta = sta->next;
            }
            ap = ap->next;
        }
    }

	pixie_leave_critical_section(sqdb->cs);

    return result;
}
Esempio n. 8
0
void regmac_station_wired(struct SQDB *sqdb, const unsigned char *bssid, const unsigned char *mac_address, unsigned dir)
{
	struct SQDB_SubStation *sta;
	struct SQDB_AccessPoint *base;
	struct SQDB_SubStation multicast;


	pixie_enter_critical_section(sqdb->cs);

	/* First, register the fact we have an access-point*/
	base = sqdb_create_bssid(sqdb, bssid);

	/* Second, regisger the fact we have an access-point attached
	 * to that access-point */
    if (mac_address[0]&1)
        sta = &multicast;
    else
    	sta = sqdb_lookup_substation(sqdb, mac_address, bssid);

	/* Finally, update the packet counts */
	switch (dir) {
	case DIR_RECEIVED:
	case DIR_BASE_TO_STA:
		//base->data_sent++;
		sta->data_received++;
		break;
	case DIR_SENT:
	case DIR_STA_TO_BASE:
		//base->data_received++;
		sta->data_sent++;
		break;
	}
	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 9
0
void regmac_event(struct SQDB *sqdb, 
                         unsigned event_type,
                         const unsigned char *bssid, const unsigned char *mac_address, 
                         unsigned frame_type,
                         struct NetFrame *frame)
{
	struct SQDB_SubStation *sta;
	struct SQDB_AccessPoint *ap;
    struct SQDB_Event *event;
    time_t timestamp = sqdb->kludge.time_stamp;

	pixie_enter_critical_section(sqdb->cs);

	ap = sqdb_create_bssid(sqdb, bssid);
	sta = sqdb_lookup_substation(sqdb, mac_address, bssid);

    /* If the existing event doesn't match this, then we need to close it */
    if (sta->current_event && sta->current_event->type != event_type) {
        event_close(sqdb, sta->current_event);
    }

    /* If there is no current event, create one */
    if (sta->current_event == NULL)
        event_new(sqdb, sta, ap, sqdb->kludge.time_stamp, event_type);
    event = sta->current_event;

    /* update latest time */
    if (event->time_last < timestamp)
        event->time_last = timestamp;

    /* Do different logic, depending on the event type */
    event_update_packet(event, frame_type, frame);

	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 10
0
/**
 * Create a list pointing to discovered stations
 */
struct TMP_STATIONS *
sqdb_enum_probers(struct SQDB *sqdb, size_t *count)
{  
    unsigned i;
    unsigned total_stations = 0;
    unsigned n;
    struct TMP_STATIONS *result;
    bool still_swapping;

	pixie_enter_critical_section(sqdb->cs);

    /* First, count all the station records */
    for (i=0; i<sizeof(sqdb->stations)/sizeof(sqdb->stations[0]); i++) {
        struct SQDB_Station *entry = sqdb->stations[i];
        while (entry) {
            total_stations++;
            entry = entry->next;
        }
    }

    /* Allocate a list of the stations */
    result = (struct TMP_STATIONS*)malloc(sizeof(result[0]) * (total_stations + 1));
    n = 0;
    for (i=0; i<sizeof(sqdb->stations)/sizeof(sqdb->stations[0]); i++) {
        struct SQDB_Station *entry = sqdb->stations[i];
        while (entry) {
            result[n].sta.unassociated = entry;
            result[n].last_update = entry->dbm_last_update;
            result[n].type = 1;
            n++;
            entry = entry->next;
        }
    }
    result[n].type = 0;
    *count = total_stations;

    /* Sort the list so that most recent are on top */
    still_swapping = true;
    if (total_stations)
    while (still_swapping) {
        still_swapping = false;
        for (i=0; i<total_stations-1; i++) {
            if (result[i].last_update < result[i+1].last_update) {
                struct TMP_STATIONS x;
                memcpy(&x, &result[i], sizeof(x));
                memcpy(&result[i], &result[i+1], sizeof(x));
                memcpy(&result[i+1], &x, sizeof(x));
                still_swapping = true;
            }
        }
    }
	pixie_leave_critical_section(sqdb->cs);
	return result;
}
Esempio n. 11
0
/*===========================================================================
 *===========================================================================*/
void
xml_station_item(struct mg_connection *c, const struct mg_request_info *ri, void *user_data)
{
	struct SQDB *sqdb = (struct SQDB*)user_data;
	unsigned char mac_address[6];
    char mac_address_str[16] = "";
    struct TMP_STATIONS *stations=NULL;
    unsigned station_count = 0;

	pixie_enter_critical_section(sqdb->cs);

	if (memcmp(ri->uri, "/station/", 9) != 0) {
		mg_printf(c, "404 Not Found\r\nConnection: closed\r\n\r\n");
		goto _return;
	}

	/*
	 * Lookup this BSSID entry
	 */
	parse_mac_address(mac_address, sizeof(mac_address), ri->uri+strlen("/station/"));
	stations = sqdb_find_station(sqdb, mac_address, &station_count);
	if (stations == NULL || station_count == 0) {
		mg_printf(c, "404 Not Found\r\nConnection: closed\r\n\r\n");
		goto _return;
	}

	sprintf_s(mac_address_str, sizeof(mac_address_str), "%02x%02x%02x%02x%02x%02x", 
					mac_address[0],mac_address[1],mac_address[2],
					mac_address[3],mac_address[4],mac_address[5]
					);

	mg_headers_ok(c, "text/xml");
	X(c, "Connection: close\r\n");
	X(c, "\r\n");

	X(c, "<?xml version=\"1.0\" ?>\n");
	X(c, "<update timestamp=\"%u\">\n", time(0));
	X(c, " <station id=\"%02x%02x%02x%02x%02x%02x\">\n",
					mac_address[0],mac_address[1],mac_address[2],
					mac_address[3],mac_address[4],mac_address[5]
					);
	X(c, "  <mac>[%02x:%02x:%02x:%02x:%02x:%02x]</mac>\n",
					mac_address[0],mac_address[1],mac_address[2],
					mac_address[3],mac_address[4],mac_address[5]
					);
	X(c, " </station>\n");

	X(c, "</update>\n");
_return:
	pixie_leave_critical_section(sqdb->cs);
    if (stations)
        free(stations);
}
Esempio n. 12
0
/**
 * Lookup a MAC address in the system and see whether it refers
 * to an access-point or a normal station
 */
unsigned sqdb_station_type(struct SQDB *sqdb, const unsigned char *mac_address)
{
	unsigned result = STATION_TYPE_UNKNOWN;
	pixie_enter_critical_section(sqdb->cs);
	if ((mac_address[0]&1) == 1)
		result = STATION_TYPE_MULTICAST;
	else {
		struct XMAC *xmac;
		xmac = xmac_create(&sqdb->macs, mac_address);
		result = xmac->type;
	}
	pixie_leave_critical_section(sqdb->cs);
	return result;
}
Esempio n. 13
0
/**
 * Add access-point information for a beacon or probe-response packet
 * Returns '1' if a new entry was created, or '0' otherwise
 */
unsigned sqdb_add_beacon(
	struct SQDB *sqdb, 
	const unsigned char *src_mac,
	const unsigned char *bssid,
	struct SQDB_String ssid,
	unsigned channel,
	struct SQDB_RateList rates1,
	struct SQDB_RateList rates2,
    unsigned is_adhoc,
    struct SQDB_String cisco_name
)
{
	struct SQDB_AccessPoint *entry;
	/*unsigned is_new = false;*/

	pixie_enter_critical_section(sqdb->cs);

	/*  
	 * Look up the entry in the hash table 
	 */
	entry = sqdb_create_bssid(sqdb, bssid);
    entry->flag_is_ibss = is_adhoc;
    if (memcmp(entry->mac_address.addr, "\0\0\0\0\0\0", 6) == 0)
        memcpy(entry->mac_address.addr, src_mac, 6);
	regmac_base(sqdb, bssid, src_mac);
	regmac_base_ssid(sqdb, bssid, &ssid);
	sqdb_base_channel(entry, channel);
	sqdb_string_copy(&entry->cisco_name, &cisco_name);

	entry->beacon_count++;


	/*
	 * See if the Rates fields are the same
	 */
	if (!sqdb_ratesfield_equal(&entry->rates1, &rates1)) {
		sqdb_ratesfield_copy(&entry->rates1, &rates1);
	}
	if (!sqdb_ratesfield_equal(&entry->rates2, &rates2)) {
		sqdb_ratesfield_copy(&entry->rates2, &rates2);
	}

	pixie_leave_critical_section(sqdb->cs);
	return 0;
}
Esempio n. 14
0
void
sqdb_add_info(struct SQDB *sqdb, const unsigned char *mac_address, const unsigned char *bssid,
			  const char *name, const char *value)
{
	struct SQDB_SubStation *sta;
	struct NVPair **r_data;
	struct NVPair *d;
	unsigned name_length = strlen(name);
	unsigned value_length = strlen(value);

    /* Filter out some common names that I see */
    if (MATCHESZ(name, "domain")) {
        if (MATCHESZ(value, "savvis.net"))
            return;
    }


	pixie_enter_critical_section(sqdb->cs);


	sta = sqdb_lookup_substation(sqdb, mac_address, bssid);
	if (sta == NULL)
		goto _return;

	for (r_data =  &sta->data; *r_data; r_data = &(*r_data)->next) {
		d = *r_data;

		if (MATCHESZ(d->name, name) && MATCHESZ(d->value, value))
			goto _return;
	}

	d = (struct NVPair*)malloc(sizeof(*d));
	d->name = (char*)malloc(name_length+1);
	memcpy(d->name, name, name_length+1);
	d->value = (char*)malloc(value_length+1);
	memcpy(d->value, value, value_length+1);
	d->next = 0;

	*r_data = d;

_return:
	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 15
0
void
regmac_base(struct SQDB *sqdb, const unsigned char *bssid, const unsigned char *mac_address)
{
	struct SQDB_AccessPoint *base;
	struct XMAC *xmac;

	pixie_enter_critical_section(sqdb->cs);

	base = sqdb_create_bssid(sqdb, bssid);

    if (!sqdb_contains_mac_address(base, mac_address)) {
        sqdb_ap_add_mac_address(base, mac_address);

		/* Create a link to this from the master MAC address registery */
		xmac = xmac_create(&sqdb->macs, bssid);
		xmac->type = STATION_TYPE_BASE;
		xmac->base = base;
	}
	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 16
0
unsigned
sqdb_set_bssid_packet(struct SQDB *sqdb, const unsigned char *bssid, unsigned type, const struct SquirrelPacket *pkt)
{
	struct SQDB_AccessPoint *ap;
	unsigned i;

	pixie_enter_critical_section(sqdb->cs);

	ap = sqdb_create_bssid(sqdb, bssid);

    if (pkt->px[0] == 0x80)
        i = 0; /* Beacon */
    else if (pkt->px[0] == 0x50)
        i = 1; /* Probe Response */
    else
        return 0;

	if (ap) {
		unsigned char *px;

		if (ap->packets[i].px == NULL) {
            /* If no existing packets, then allocate a buffer */
			px = (unsigned char*)malloc(pkt->length);
		} else if (ap->packets[i].length < pkt->length) {
            /* If there was already a buffer, but it's too short,
             * then allocate a replacement buffer that's long enough */
			free((unsigned char*)ap->packets[i].px);
			px = (unsigned char*)malloc(pkt->length);
        } else {
            /* The existing buffer is big enough, so just reusee it */
			px = (unsigned char*)ap->packets[i].px;
        }
		memcpy(&ap->packets[i], pkt, sizeof(*pkt));
		ap->packets[i].px = px;
		memcpy(px, pkt->px, pkt->length);
        
	}

	pixie_leave_critical_section(sqdb->cs);
	return 0;
}
Esempio n. 17
0
void
regmac_base_rates(struct SQDB *sqdb, const unsigned char *bssid, struct SQDB_RateList *rates1, struct SQDB_RateList *rates2)
{
	struct SQDB_AccessPoint *entry;

	pixie_enter_critical_section(sqdb->cs);

	entry = sqdb_create_bssid(sqdb, bssid);

	if (rates1) {
		if (!sqdb_ratesfield_equal(&entry->rates1, rates1)) {
			sqdb_ratesfield_copy(&entry->rates1, rates1);
		}
	}
	if (rates2) {
		if (!sqdb_ratesfield_equal(&entry->rates2, rates2)) {
			sqdb_ratesfield_copy(&entry->rates2, rates2);
		}
	}
	pixie_leave_critical_section(sqdb->cs);

}
Esempio n. 18
0
void regmac_station_ctrl(struct SQDB *sqdb, const unsigned char *bssid, const unsigned char *mac_address, unsigned dir)
{
	struct SQDB_SubStation *sta;
	struct SQDB_AccessPoint *base;

	pixie_enter_critical_section(sqdb->cs);

	base = sqdb_create_bssid(sqdb, bssid);
	sta = sqdb_lookup_substation(sqdb, mac_address, bssid);
	switch (dir) {
	case DIR_RECEIVED:
	case DIR_BASE_TO_STA:
		base->ctrl_sent++;
		sta->ctrl_received++;
		break;
	case DIR_SENT:
	case DIR_STA_TO_BASE:
		base->ctrl_received++;
		sta->ctrl_sent++;
		break;
	}
	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 19
0
void
regmac_transmit_power(struct SQDB *sqdb, const unsigned char *src, int dbm, time_t timestamp)
{
	struct XMAC *xmac;
	if (dbm == 0)
		return;

	pixie_enter_critical_section(sqdb->cs);

	xmac = xmac_create(&sqdb->macs, src);

	switch (xmac->type) {
	case STATION_TYPE_BASE:
		{
			struct SQDB_AccessPoint *entry = xmac->base;
			entry->dbm = dbm;
			entry->dbm_last_update = timestamp;
		}
		break;
	case STATION_TYPE_STA:
		{
			struct SQDB_SubStation *entry = xmac->sta;
			entry->dbm = dbm;
			entry->dbm_last_update = timestamp;
		}
		break;
	case STATION_TYPE_STA_ALONE:
		{
			struct SQDB_Station *entry = xmac->sta_alone;
			entry->dbm = dbm;
			entry->dbm_last_update = timestamp;
		}
		break;
	}

	pixie_leave_critical_section(sqdb->cs);
}
Esempio n. 20
0
/*===========================================================================
 *===========================================================================*/
void
display_station_item(struct mg_connection *c, const struct mg_request_info *ri, void *user_data)
{
	struct SQDB *sqdb = (struct SQDB*)user_data;
	unsigned char mac_address[6];
	char mac_address_str[16];
	char buf[64];
    struct TMP_STATIONS *stations = NULL;
    unsigned station_count = 0;
    unsigned i;

	if (strstr(ri->uri, ".xml")) {
		xml_station_item(c, ri, user_data);
		return;
	}
	pixie_enter_critical_section(sqdb->cs);

	if (memcmp(ri->uri, "/station/", 9) != 0) {
		mg_printf(c, "404 Not Found\r\nConnection: closed\r\n\r\n");
		goto _return;
	}

	/*
	 * Lookup this BSSID entry
	 */
	parse_mac_address(mac_address, sizeof(mac_address), ri->uri+strlen("/station/"));
	stations = sqdb_find_station(sqdb, mac_address, &station_count);
	if (stations == 0 || station_count == 0) {
		mg_printf(c, "404 Not Found\r\nConnection: closed\r\n\r\n");
		goto _return;
	}


	
	sprintf_s(mac_address_str, sizeof(mac_address_str), "%02x%02x%02x%02x%02x%02x", 
					mac_address[0],mac_address[1],mac_address[2],
					mac_address[3],mac_address[4],mac_address[5]
					);

	mg_headers_ok(c, "text/html");
	X(c, "Connection: close\r\n");
	X(c, "\r\n");

	//X(c, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\r\n");
	X(c,"<html>\n");
	X(c,"<head>\n");
	X(c," <title>Squirrel WiFi monitor</title>\n");
	X(c," <link rel=\"stylesheet\" type=\"text/css\" href=\"../squirrel.css\" />\n");
	X(c," <link rel=\"Shortcut Icon\" href=\"../favicon.ico\" type=\"image/x-icon\">\n");
	X(c," <script type=\"text/javascript\" src=\"../squirrel.js\"></script>\n");
	X(c, "<script type=\"text/javascript\">var bssid_item_address = '%s';</script>\n", mac_address_str);
	X(c,"</head>\n");
	X(c,"<body onLoad=\"setInterval(refresh_station_item,1000)\">\n");

	display_topmenu(c, ri, user_data, 1);

    for (i=0; i<station_count; i++) {
        struct TMP_STATIONS *tmp = &stations[i];

        /*
         * ASSOCIATED station
         */
        if (tmp->type == 2) {
            struct SQDB_SubStation *sta = tmp->sta.associated;
            struct SQDB_AccessPoint *ap = tmp->sta.accesspoint;

	        X(c, "<table id=\"station\" class=\"station\">\n");
            X(c, "  <tr id=\"0\"><th colspan=\"6\" class=\"title\">ASSOCIATED STATION</th></tr>\n");
	        X(c, "  <tr id=\"1\">\n");
	        X(c, "   <th>MAC:</th><td id=\"mac\" class=\"mac\">[%02x:%02x:%02x:%02x:%02x:%02x]</td>\n",
					        mac_address[0],mac_address[1],mac_address[2],
					        mac_address[3],mac_address[4],mac_address[5],
					        mac_address[0],mac_address[1],mac_address[2],
					        mac_address[3],mac_address[4],mac_address[5]
					        );
	        X(c, "   <th>Data Sent:</th><td id=\"dataout\" class=\"sent\">%s</td>\n", format_unsigned(sta->data_sent,buf,sizeof(buf)));
	        X(c, "   <th>Data Recv:</th><td id=\"datain\" class=\"sent\">%s</td>\n", format_unsigned(sta->data_received,buf,sizeof(buf)));
	        X(c, "  </tr>\n");
	        X(c, "  <tr id=\"2\">\n");
	        X(c, "   <th>SSID:</th><td id=\"essid\" class=\"essid\"><a href=\"/bssid/%02x%02x%02x%02x%02x%02x.html\">%.*s</a></td>\n", 
                ap->bssid[0], ap->bssid[1], ap->bssid[2], 
                ap->bssid[3], ap->bssid[4], ap->bssid[5], 
                ap->ssid.length, ap->ssid.value);
	        X(c, "   <th>Ctrl Sent:</th><td id=\"ctrlout\" class=\"sent\">%s</td>\n", format_unsigned(sta->ctrl_sent,buf,sizeof(buf)));
	        X(c, "   <th>Ctrl Recv:</th><td id=\"ctrlin\" class=\"sent\">%s</td>\n", format_unsigned(sta->ctrl_received,buf,sizeof(buf)));
	        X(c, "  </tr>\n");
	        X(c, "  <tr id=\"4\">\n");
	        X(c, "   <th>BSSID:</th><td id=\"bssid\" class=\"bssid\"><a href=\"/bssid/%02x%02x%02x%02x%02x%02x.html\">%02x:%02x:%02x:%02x:%02x:%02x</a></td>\n", 
                ap->bssid[0], ap->bssid[1], ap->bssid[2], 
                ap->bssid[3], ap->bssid[4], ap->bssid[5], 
                ap->bssid[0], ap->bssid[1], ap->bssid[2], 
                ap->bssid[3], ap->bssid[4], ap->bssid[5]
                );
	        X(c, "   <th>Power:</th><td id=\"power\" class=\"power\">%s</td>\n", format_signed(sta->dbm,buf,sizeof(buf)));
	        X(c, "   <th>Channels:</th><td id=\"channels\" class=\"channels\">");
	        {
		        unsigned j;
		        for (j=0; j<ap->channel_count; j++) {
			        X(c, "%u%c", ap->channels[j], (j+1<ap->channel_count?',':' '));
		        }
	        }
            X(c, "</td>\n");
	        X(c, "  </tr>\n");
	        X(c, "  <tr id=\"6\">\n");
	        X(c, "   <th>MANUF:</th><td id=\"manuf\" class=\"manuf\">%s</td>\n", manuf_from_mac(mac_address));
	        X(c, "   <th>Desc:</th><td id=\"manuf2\" class=\"manuf2\" colspan=\"3\">%s</td>\n", manuf2_from_mac(mac_address));
	        X(c, "  </tr>\n");
	        X(c, "  <tr id=\"7\">\n");
	        X(c, "   <th>Info:</th><td id=\"manuf\" class=\"manuf\" colspan=\"5\">\n");
            {
                struct NVPair *nv = sta->data;
                while (nv) {
                    X(c, "    %s = %s<br/>\n", nv->name, nv->value);
                    nv = nv->next;
                }
            }
            X(c, "   </th>\n");
	        X(c, "  </tr>\n");
	        X(c, "</table><br/>\n");
        }

        if (tmp->type == 1) {
            struct SQDB_Station *sta = tmp->sta.unassociated;

	        X(c, "<table id=\"station\" class=\"station\">\n");
            X(c, "  <tr id=\"0\"><th colspan=\"6\" class=\"title\">UNASSOCIATED PROBER</th></tr>\n");
	        X(c, "  <tr id=\"1\">\n");
	        X(c, "   <th>MAC:</th><td id=\"mac\" class=\"mac\">[%02x:%02x:%02x:%02x:%02x:%02x]</td>\n",
					        mac_address[0],mac_address[1],mac_address[2],
					        mac_address[3],mac_address[4],mac_address[5],
					        mac_address[0],mac_address[1],mac_address[2],
					        mac_address[3],mac_address[4],mac_address[5]
					        );
	        X(c, "   <th>Probes:</th><td id=\"dataout\" class=\"sent\">%s</td>\n", format_unsigned(sta->probe_count,buf,sizeof(buf)));
	        X(c, "   <th>Responses:</th><td id=\"datain\" class=\"sent\">%s</td>\n", format_unsigned(0,buf,sizeof(buf)));
	        X(c, "  </tr>\n");
	        X(c, "  <tr id=\"7\">\n");
	        X(c, "   <th>SSIDs:</th><td id=\"essid\" class=\"essid\" colspan=\"5\">\n");
            {
                struct EntrySSID *s;
                for (s=&sta->ssid; s; s = s->next) {
                    char defanged[1024];
                    defang_ssid(defanged, sizeof(defanged), (const char*)s->ssid.value, s->ssid.length);
                    X(c, "%s<br/>", defanged);
                }
            }
            X(c, "   </th>\n");
	        X(c, "  </tr>\n");
	        X(c, "</table><br/>\n");
        }
    }

	X(c,	"</body>\n"
			"</html>\n"
			);

_return:
	pixie_leave_critical_section(sqdb->cs);
    if (stations)
        free(stations);
}
Esempio n. 21
0
/*===========================================================================
 *===========================================================================*/
void
display_adapters(struct mg_connection *c, const struct mg_request_info *ri, void *user_data)
{
	struct Squirrel *squirrel = (struct Squirrel *)user_data;
	char errbuf[1024];
	unsigned interface_channel = 0;
	char *action = mg_get_var(c, "action");

	pixie_enter_critical_section(squirrel->cs);

	/* If a CGI request was sent to change an adapter status, then do that change */
	if (action)
		; //change_adapter_status(

	mg_headers_ok(c, "text/html");
	X(c, "Connection: close\r\n");
	X(c, "\r\n");

	//X(c, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\r\n");
	X(c,"<html>\n");
	X(c,"<head>\n");
	X(c," <title>Squirrel WiFi monitor / Adapters</title>\n");
	X(c," <link rel=\"stylesheet\" type=\"text/css\" href=\"squirrel.css\" />\n");
	X(c," <link rel=\"Shortcut Icon\" href=\"favicon.ico\" type=\"image/x-icon\">\n");
	X(c,"</head>\n");
	X(c,"<body>\n");


	display_topmenu(c, ri, user_data, 0);

	if (!pcap.is_available) {
		X(c, "<h1>ERROR: no libpcap</h1>\n");
		X(c, " On Unix, install libpcap from tcpdump site. On Windows, instal WinPcap from WinDump site.\n");
		goto _return;
	} else if (pcap.findalldevs(&alldevs, errbuf) == -1) {
		X(c, "<h1>ERROR: no adapters found</h1>\n");
		X(c, "<p>%s</p>\n", errbuf);
		X(c, "<p>Make sure you have root/administrator privileges</p>\n");
		goto _return;
	} else if (alldevs == NULL) {
		X(c, "<h1>ERROR: no adapters found</h1>\n");
		X(c, "<p>Make sure you have root/administrator privileges</p>\n");
		goto _return;
	} else {
		pcap_if_t *d;
		unsigned i=0;

		/* Print the list */
		X(c, "<table class=\"bssids\">\n");
		X(c, " <tr><th>Index</th><th>Name</th><th>Driver</th><th>Description</th><th>Monitor</th><th>Channel</th></tr>\n");
		for(d=alldevs; d; d=d->next)
		{
			const char *driver = "";
			if (strstr(d->name, "\\airpcap")) {
				driver = "airpcap";
			} else {
				driver = "airpcap";
			}
			++i;
			X(c, " <tr>\n");
			X(c, "  <td class=\"index\"><a href=\"monitor.php?index=%d\">%d</a></td>\n", i, i);
			X(c, "  <td><a href=\"adapter/%s.html\">%s</td>\n", d->name, d->name);
			if (strstr(d->name, "\\airpcap")) {
				X(c, "  <td>airpcap</td>\n\n");  
			} else {
				X(c, "  <td>ndis</td>\n");  
			}
			if (d->description)
				X(c, "  <td>%s</td>\n", d->description);
			else
				X(c, "  <td>%s</td>\n", "");
	
			if (squirrel_get_interface_status(squirrel, d->name, &interface_channel)) {
				X(c, "  <td id=\"status\">"
						"<form action=\"/adapters.html\">"
						"<input type=\"hidden\" name=\"adapter\" value=\"%s\">"
						"<input type=\"submit\" name=\"action\" value=\"Stop\">"
						"</form></td>\n", d->name);
				if (interface_channel == 0)
					X(c, "  <td id=\"channel\">%s</td>\n", "");
				else if (interface_channel == (unsigned)-1)
					X(c, "  <td id=\"channel\">%s</td>\n", "scan");
				else
					X(c, "  <td id=\"channel\">%u</td>\n", interface_channel);

			} else {
				X(c, "  <td id=\"status\">"
						"<form action=\"/adapters.html\">"
						"<input type=\"hidden\" name=\"adapter\" value=\"%s\">"
						"<input type=\"submit\" name=\"action\" value=\"Start\">"
						"</form></td>\n", d->name);
					X(c, "  <td id=\"channel\">%s</td>\n", "");
			}

		}
		X(c, "</table>\n");
	}
_return:
	pixie_leave_critical_section(squirrel->cs);
}
Esempio n. 22
0
/*===========================================================================
 *===========================================================================*/
void
display_adapter(struct mg_connection *c, const struct mg_request_info *ri, void *user_data)
{
	struct Squirrel *squirrel = (struct Squirrel *)user_data;
	char adapter_name[256];
	char description[256];
	unsigned exists;
	const char *driver = "";
	unsigned interface_channel = 0;

	pixie_enter_critical_section(squirrel->cs);

	if (memcmp(ri->uri, "/adapter/", 9) != 0) {
		mg_printf(c, "404 Not Found\r\nConnection: closed\r\n\r\n");
		goto _return;
	} else
		sprintf_s(adapter_name, sizeof(adapter_name), "%s", ri->uri+9);

	if (strlen(adapter_name) > 5 && memcmp(adapter_name+strlen(adapter_name)-5, ".html", 5) == 0)
		adapter_name[strlen(adapter_name)-5] = '\0';
	if (strlen(adapter_name) > 7 && memcmp(adapter_name, "airpcap", 7) == 0 && strlen(adapter_name) < sizeof(adapter_name)-5) {
		memmove(adapter_name+4, adapter_name, strlen(adapter_name)+1);
		memcpy(adapter_name, "\\\\.\\", 4);
	}

	exists = adapter_description(adapter_name, description, sizeof(description));
	if (!exists) {
		mg_printf(c, "404 Not Found\r\nConnection: closed\r\n\r\n");
		goto _return;
	}
	if (strstr(adapter_name, "\\airpcap")) {
		driver = "airpcap";
	} else {
		driver = "ndis";
	}

	mg_headers_ok(c, "text/html");
	X(c, "Connection: close\r\n");
	X(c, "\r\n");

	//X(c, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\r\n");
	X(c,"<html>\n");
	X(c,"<head>\n");
	X(c," <title>Squirrel WiFi monitor / Adapter</title>\n");
	X(c," <link rel=\"stylesheet\" type=\"text/css\" href=\"../squirrel.css\" />\n");
	X(c," <link rel=\"Shortcut Icon\" href=\"../favicon.ico\" type=\"image/x-icon\">\n");
	X(c,"</head>\n");
	X(c,"<body>\n");

	display_topmenu(c, ri, user_data, 0);

	/*
	 * Do any necessary changes
	 */
	{
		char *status = mg_get_var(c, "status");
		char *channel = mg_get_var(c, "channel");

		if (status && channel) {
			unsigned is_running = squirrel_get_interface_status(squirrel, adapter_name, &interface_channel);
			unsigned new_channel;
			if (strcmp(channel, "scan") == 0)
				new_channel = (unsigned)-1;
			else if (isdigit(channel[0]))
				new_channel = atoi(channel);
			else
				new_channel = 0;

			if (is_running && strcmp(status, "monitor") != 0) {
				/* Turn off the adapter */
				squirrel_set_interface_status(squirrel, adapter_name, 0, 0);
				X(c, "<b>Turned off adapter</b>\n");
			} else if (!is_running && strcmp(status, "monitor") == 0) {
				launch_thread(squirrel, adapter_name);
				squirrel_set_interface_status(squirrel, adapter_name, 1, new_channel);
				X(c, "<b>Turned on adapter, channel %u</b>\n", new_channel);
			} else if (is_running && interface_channel != new_channel) {
				squirrel_set_interface_status(squirrel, adapter_name, 1, new_channel);
				X(c, "<b>Changed channel to %u</b>\n", new_channel);
			} else
				X(c, "<b>Nothing changed</b>\n");
		}
		if (status)
			free(status);
		if (channel)
			free(channel);
	}

	X(c, "<table class=\"adapter\">\n");
	X(c, "  <tr><th>Adapter:</th><td>%s</td></tr>\n", adapter_name);
	X(c, "  <tr><th>Description:</th><td>%s</td></tr>\n", description);
	X(c, "  <tr><th>Driver:</th><td>%s</td></tr>\n", driver);
	X(c, "  <tr><th>Monitor Mode:</th><td>%s</td></tr>\n", can_monitor_mode(adapter_name)?"yes":"no");
	X(c, "  <tr><th>Can Transmit:</th><td>%s</td></tr>\n", can_transmit(adapter_name)?"yes":"no");


	if (squirrel_get_interface_status(squirrel, adapter_name, &interface_channel)) {
		X(c, "  <tr><th>Status:</th><td>%s</td></tr>\n", "monitoring");
		if (interface_channel == 0)
			X(c, "  <tr><th>Channel:</th><td>%s</td></tr>\n", "");
		else if (interface_channel == (unsigned)-1)
			X(c, "  <tr><th>Channel:</th><td>%s</td></tr>\n", "scan");
		else
			X(c, "  <tr><th>Channel:</th><td>%u</td></tr>\n", interface_channel);

	} else {
		X(c, "  <tr><th>Status:</th><td>%s</td></tr>\n", "off");
		X(c, "  <tr><th>Channel:</th><td>%s</td></tr>\n", "");
	}
	X(c, "</table>\n");

	X(c, "<hr/>\n");
	X(c, "<form action=\"%s.html\">\n", adapter_name);
	X(c, " <input type=\"radio\" name=\"status\" value=\"monitor\" /> Monitor<br/>\n");
	X(c, " <input type=\"radio\" name=\"status\" value=\"off\" /> Off<br/>\n");
	X(c, " Channel: <input type=\"text\" name=\"channel\" value=\"scan\"/><br/>\n");
	X(c, " <input type=\"submit\" value=\"Submit\">\n");
	X(c, "</form>\n");

_return:
	pixie_leave_critical_section(squirrel->cs);
}
Esempio n. 23
0
unsigned sqdb_add_probe_request(
	struct SQDB *sqdb, 
	const unsigned char *src_mac,
	struct SQDB_String ssid,
	struct SQDB_RateList rates1,
	struct SQDB_RateList rates2
)
{
	struct SQDB_Station *entry;
	unsigned is_new = false;

	pixie_enter_critical_section(sqdb->cs);

	/*  
	 * Look up the entry in the hash table 
	 */
	{
		struct SQDB_Station **r_entry;
		unsigned index = bssid_hash(src_mac);

		r_entry = &sqdb->stations[index];
		while ((*r_entry) && memcmp((*r_entry)->mac_address, src_mac, 6) != 0)
			r_entry = &((*r_entry)->next);
		if (*r_entry == NULL) {
			struct XMAC *xmac;
			char myssid[256];
			unsigned myssid_length;

			*r_entry = (struct SQDB_Station*)malloc(sizeof(**r_entry));
			memset(*r_entry, 0, sizeof(**r_entry));
			memcpy((*r_entry)->mac_address, src_mac, 6);
			sqdb_string_copy(&(*r_entry)->ssid.ssid, &ssid);
			is_new = true;

			/* Create a link to this from the master MAC address registery */
			xmac = xmac_create(&sqdb->macs, src_mac);
			xmac->type = STATION_TYPE_STA_ALONE;
			xmac->sta_alone = *r_entry;

			myssid_length = format_ssid(myssid, sizeof(myssid), (const char*)ssid.value,  ssid.length);

			SQUIRREL_EVENT(" %02X:%02X:%02X:%02X:%02X:%02X  "
				"probe=\"%.*s\" "
				"%.*s"
				"\n",
				PRINTMAC(src_mac),
				myssid_length, myssid, 
				(ssid.length>16)?0:(16-ssid.length), "                 "
				);
		}
		entry = *r_entry;
	}
    
    entry->probe_count++;

	/*
	 * See if the SSID of the network has changed. This should
	 * never really happen.
	 */
	if (!sqdb_string_is_equal(&entry->ssid.ssid, &ssid)) {
		struct EntrySSID **r;
		unsigned found = 0;

		for (r=&entry->ssid.next; *r; r = &((*r)->next)) {
			if (sqdb_string_is_equal(&(*r)->ssid, &ssid)) {
				found = 1;
				break;
			}
		}
		if (!found) {
			char myssid[256];
			unsigned myssid_length;

			myssid_length = format_ssid(myssid, sizeof(myssid), (const char*)ssid.value,  ssid.length);

			*r = (struct EntrySSID*)malloc(sizeof(**r));
			memset(*r, 0, sizeof(**r));
			sqdb_string_copy(&(*r)->ssid, &ssid);
			SQUIRREL_EVENT(" %02X:%02X:%02X:%02X:%02X:%02X  probe=\"%.*s\"\n", 
				PRINTMAC(src_mac), myssid_length, myssid);
		}
	}

	/*
	 * See if the Rates fields are the same
	 */
	if (!sqdb_ratesfield_equal(&entry->rates1, &rates1)) {
		sqdb_ratesfield_copy(&entry->rates1, &rates1);
	}
	if (!sqdb_ratesfield_equal(&entry->rates2, &rates2)) {
		sqdb_ratesfield_copy(&entry->rates2, &rates2);
	}


	pixie_leave_critical_section(sqdb->cs);
	return 0;
}