int proc_sta_auth_notif(ugw_netlink_data_t *report_data, int recv_len) { int data_len = sizeof(ugw_netlink_data_t) + \ report_data->count * sizeof(ugw_sta_auth_notif_t); if (recv_len != data_len) { printf("error: recv_len[%d] != data_len[%d]\n", recv_len, data_len); return -1; } if (NULL == report_data->buf) { printf("report_data->buf is null.\n"); return -1; } ugw_sta_auth_notif_t *sta_notif = (ugw_sta_auth_notif_t *)report_data->buf; printf("mac[%-16s] ap_devid[%016"PRIX64"] rf_type[%u] curr_users[%u] ", \ MAC_STR(sta_notif->sta_mac), sta_notif->ap_devid, sta_notif->rf_type, \ sta_notif->curr_users); printf("bssid[%-16s] wlan_id[%u] action[%u]\n", \ MAC_STR(sta_notif->bssid), sta_notif->wlan_id, sta_notif->action); return 0; }
int proc_nwlan_info(ugw_netlink_data_t *report_data, int recv_len) { int data_len = sizeof(ugw_netlink_data_t) + \ report_data->count * sizeof(ugw_nwlan_info_t); if (recv_len != data_len) { printf("error: recv_len[%d] != data_len[%d]\n", recv_len, data_len); return -1; } if (NULL == report_data->buf) { printf("report_data->buf is null.\n"); return -1; } ugw_nwlan_info_t *nwlans = (ugw_nwlan_info_t *)report_data->buf; int i; for (i = 0; i < report_data->count; i++) { printf("%d ssid[%-16s] bssid[%-16s] apid[%-16s] wlanid[%-4u] " "rf_type[%-4u] channel[%-3u] rssi[%-4d]\n", \ i, \ nwlans[i].ssid, MAC_STR(nwlans[i].bssid), \ PRINT_APID(nwlans[i].ap_devid), nwlans[i].wlan_id, \ nwlans[i].rf_type, nwlans[i].channel_id, nwlans[i].rssi-100); } return 0; }
int proc_scan_sta_info(ugw_netlink_data_t *report_data, int recv_len) { int data_len = sizeof(ugw_netlink_data_t) + \ report_data->count * sizeof(ugw_scan_sta_info_t); if (recv_len != data_len) { printf("error: recv_len[%d] != data_len[%d] ugw_scan_sta_info_t:%d\n", \ recv_len, data_len, sizeof(ugw_scan_sta_info_t)); return -1; } if (NULL == report_data->buf) { printf("report_data->buf is null.\n"); return -1; } ugw_scan_sta_info_t *scan_stas = (ugw_scan_sta_info_t *)report_data->buf; int i = 0; for (; i < report_data->count; i++) { printf("[%-2d]mac[%-16s] rssi[%d]dBm rf_type[%d]\n", \ i, \ MAC_STR(scan_stas[i].sta_mac), \ scan_stas[i].rssi-100, \ scan_stas[i].rf_type); } return 0; }
int proc_assoc_sta_info(ugw_netlink_data_t *report_data, int recv_len) { int data_len = sizeof(ugw_netlink_data_t) + \ report_data->count * sizeof(ugw_sta_info_t); if (recv_len != data_len) { printf("error: recv_len[%d] != data_len[%d]\n", recv_len, data_len); return -1; } if (NULL == report_data->buf) { printf("report_data->buf is null.\n"); return -1; } ugw_sta_info_t *assoc_stas = (ugw_sta_info_t *)report_data->buf; int i; for (i = 0; i < report_data->count; i++) { printf("mac[%-16s] ip[%u.%u.%u.%u] ssid[%-16s] ", \ MAC_STR(assoc_stas[i].sta_mac), \ assoc_stas[i].ip[0], assoc_stas[i].ip[1], \ assoc_stas[i].ip[2], assoc_stas[i].ip[3], \ assoc_stas[i].ssid); printf("bssid[%-16s] rssi[%-4d] " "rf_type[%u] dual_band[%u] channel[%-3u] " "avg_tx_goodput:%uB/s avg_rx_goodput:%uB/s\n", \ MAC_STR(assoc_stas[i].bssid), (assoc_stas[i].rssi-100), \ assoc_stas[i].rf_type, assoc_stas[i].is_dualband, \ assoc_stas[i].channel_id, \ assoc_stas[i].avg_tx_bytes, \ assoc_stas[i].avg_rx_bytes); } return 0; }
/** * Figures out if a MAC is listed in a comma delimited * string of MAC addresses. * returns TCPR_DIR_C2S if listed * returns TCPR_DIR_S2C if not listed */ tcpr_dir_t macinstring(const char *macstring, const u_char *mac) { char *tok, *tempstr, *ourstring; u_char tempmac[6]; int len = 6, ret = TCPR_DIR_S2C; ourstring = safe_strdup(macstring); tempstr = strtok_r(ourstring, ",", &tok); if (strlen(tempstr)) { mac2hex(tempstr, tempmac, len); if (memcmp(mac, tempmac, len) == 0) { dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac)); ret = TCPR_DIR_C2S; goto EXIT_MACINSTRING; } } else { goto EXIT_MACINSTRING; } while ((tempstr = strtok_r(NULL, ",", &tok)) != NULL) { mac2hex(tempstr, tempmac, len); if (memcmp(mac, tempmac, len) == 0) { ret = TCPR_DIR_C2S; dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac)); goto EXIT_MACINSTRING; } } EXIT_MACINSTRING: safe_free(ourstring); #ifdef DEBUG if (ret == TCPR_DIR_S2C) dbg(3, "Packet doesn't match any MAC addresses sending out secondary.\n"); #endif return ret; }
/** * This is the callback we use with pcap_dispatch to process * each packet recieved by libpcap on the two interfaces. * Need to return > 0 to denote success */ static int live_callback(struct live_data_t *livedata, struct pcap_pkthdr *pkthdr, const u_char * nextpkt) { ipv4_hdr_t *ip_hdr = NULL; ipv6_hdr_t *ip6_hdr = NULL; pcap_t *send = NULL; static u_char *pktdata = NULL; /* full packet buffer */ int cache_mode, retcode; static unsigned long packetnum = 0; struct macsrc_t *node, finder; /* rb tree nodes */ #ifdef DEBUG u_char dstmac[ETHER_ADDR_LEN]; #endif u_int16_t l2proto; packetnum++; dbgx(2, "packet %lu caplen %d", packetnum, pkthdr->caplen); /* only malloc the first time */ if (pktdata == NULL) { /* create packet buffers */ pktdata = (u_char *)safe_malloc(MAXPACKET); } else { /* zero out the old packet info */ memset(pktdata, '\0', MAXPACKET); } /* copy the packet to our buffer */ memcpy(pktdata, nextpkt, pkthdr->caplen); #ifdef ENABLE_VERBOSE /* decode packet? */ if (livedata->options->verbose) tcpdump_print(livedata->options->tcpdump, pkthdr, nextpkt); #endif /* lookup our source MAC in the tree */ memcpy(&finder.key, &pktdata[ETHER_ADDR_LEN], ETHER_ADDR_LEN); #ifdef DEBUG memcpy(&dstmac, pktdata, ETHER_ADDR_LEN); dbgx(1, "SRC MAC: " MAC_FORMAT "\tDST MAC: " MAC_FORMAT, MAC_STR(finder.key), MAC_STR(dstmac)); #endif /* first, is this a packet sent locally? If so, ignore it */ if ((memcmp(livedata->options->intf1_mac, &finder.key, ETHER_ADDR_LEN)) == 0) { dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf1); return (1); } else if ((memcmp(livedata->options->intf2_mac, &finder.key, ETHER_ADDR_LEN)) == 0) { dbgx(1, "Packet matches the MAC of %s, skipping.", livedata->options->intf2); return (1); } node = RB_FIND(macsrc_tree, &macsrc_root, &finder); /* if we can't find the node, build a new one */ if (node == NULL) { dbg(1, "Unable to find MAC in the tree"); node = new_node(); node->source = livedata->source; memcpy(&node->key, &finder.key, ETHER_ADDR_LEN); RB_INSERT(macsrc_tree, &macsrc_root, node); } /* otherwise compare sources */ else if (node->source != livedata->source) { dbg(1, "Found the dest MAC in the tree and it doesn't match this source NIC... skipping packet"); /* * IMPORTANT!!! * Never send a packet out the same interface we sourced it on! */ return (1); } /* what is our cache mode? */ cache_mode = livedata->source == PCAP_INT1 ? TCPR_DIR_C2S : TCPR_DIR_S2C; l2proto = tcpedit_l3proto(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len); dbgx(2, "Packet protocol: %04hx", l2proto); /* should we skip this packet based on CIDR match? */ if (l2proto == ETHERTYPE_IP) { dbg(3, "Packet is IPv4"); ip_hdr = (ipv4_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len); /* look for include or exclude CIDR match */ if (livedata->options->xX.cidr != NULL) { if (!process_xX_by_cidr_ipv4(livedata->options->xX.mode, livedata->options->xX.cidr, ip_hdr)) { dbg(2, "Skipping IPv4 packet due to CIDR match"); return (1); } } } else if (l2proto == ETHERTYPE_IP6) { dbg(3, "Packet is IPv6"); ip6_hdr = (ipv6_hdr_t *)tcpedit_l3data(livedata->tcpedit, BEFORE_PROCESS, pktdata, pkthdr->len); /* look for include or exclude CIDR match */ if (livedata->options->xX.cidr != NULL) { if (!process_xX_by_cidr_ipv6(livedata->options->xX.mode, livedata->options->xX.cidr, ip6_hdr)) { dbg(2, "Skipping IPv6 packet due to CIDR match"); return (1); } } } if ((retcode = tcpedit_packet(livedata->tcpedit, &pkthdr, &pktdata, cache_mode)) < 0) { if (retcode == TCPEDIT_SOFT_ERROR) { return 1; } else { /* TCPEDIT_ERROR */ return -1; } } /* * send packets out the OTHER interface * and update the dst mac if necessary */ switch(node->source) { case PCAP_INT1: dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf1, livedata->options->intf2); send = livedata->options->pcap2; break; case PCAP_INT2: dbgx(2, "Packet source was %s... sending out on %s", livedata->options->intf2, livedata->options->intf1); send = livedata->options->pcap1; break; default: errx(-1, "wtf? our node->source != PCAP_INT1 and != PCAP_INT2: %c", node->source); } /* * write packet out on the network */ if (pcap_sendpacket(send, pktdata, pkthdr->caplen) < 0) errx(-1, "Unable to send packet out %s: %s", send == livedata->options->pcap1 ? livedata->options->intf1 : livedata->options->intf2, pcap_geterr(send)); stats.bytes_sent += pkthdr->caplen; stats.pkts_sent++; dbgx(1, "Sent packet " COUNTER_SPEC, stats.pkts_sent); return (1); } /* live_callback() */