DWORD request_sniffer_interfaces(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); Tlv entries[8]; /* 0: Index 1: Name 2: Description 3: Type 4: MTU 5: Wireless? 6: Accessible? 7: DHCP? */ unsigned int idx = 1; HANDLE hCfg; check_pssdk(); hCfg = MgrGetFirstAdapterCfg(hMgr); do { unsigned char *aname = (unsigned char *)AdpCfgGetAdapterNameA(hCfg); unsigned char *adesc = (unsigned char *)AdpCfgGetAdapterDescriptionA(hCfg); unsigned int ahand = htonl((unsigned int)hCfg); unsigned int atype = htonl(AdpCfgGetAdapterType(hCfg)); unsigned int amtu = htonl(AdpCfgGetMaxPacketSize(hCfg)); unsigned int aidx = htonl(idx); BOOL awireless = AdpCfgIsWireless(hCfg); BOOL ausable = AdpCfgGetAccessibleState(hCfg); BOOL adhcp = AdpCfgGetDhcpState(hCfg); memset(entries, 0, sizeof(entries)); dprintf("sniffer>> interface %d - %s - %s", idx, aname, adesc); entries[0].header.type = TLV_TYPE_UINT; entries[0].header.length = sizeof(unsigned int); entries[0].buffer = (PUCHAR)&aidx; entries[1].header.type = TLV_TYPE_STRING; entries[1].header.length = strlen(aname)+1; entries[1].buffer = aname; entries[2].header.type = TLV_TYPE_STRING; entries[2].header.length = strlen(adesc)+1; entries[2].buffer = adesc; entries[3].header.type = TLV_TYPE_UINT; entries[3].header.length = sizeof(unsigned int); entries[3].buffer = (PUCHAR)&atype; entries[4].header.type = TLV_TYPE_UINT; entries[4].header.length = sizeof(unsigned int); entries[4].buffer = (PUCHAR)&amtu; entries[5].header.type = TLV_TYPE_BOOL; entries[5].header.length = sizeof(BOOL); entries[5].buffer = (PUCHAR)&awireless; entries[6].header.type = TLV_TYPE_BOOL; entries[6].header.length = sizeof(BOOL); entries[6].buffer = (PUCHAR)&ausable; entries[7].header.type = TLV_TYPE_BOOL; entries[7].header.length = sizeof(BOOL); entries[7].buffer = (PUCHAR)&adhcp; packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8); idx++; }while((hCfg = MgrGetNextAdapterCfg(hMgr,hCfg)) != NULL); packet_transmit_response(ERROR_SUCCESS, remote, response); return ERROR_SUCCESS; }
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; unsigned int maxp; CaptureJob *j; DWORD result; HANDLE ifh; #ifndef _WIN32 char errbuf[PCAP_ERRBUF_SIZE+4]; char *name; #endif check_pssdk(); dprintf("sniffer>> start_capture()"); ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID); maxp = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_PACKET_COUNT); maxp = min(maxp, SNIFFER_MAX_QUEUE); maxp = max(maxp, 1); result = ERROR_SUCCESS; do { // the interface is invalid if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } #ifdef _WIN32 ifh = pktsdk_interface_by_index(ifid); if (ifh == NULL) { result = ERROR_INVALID_PARAMETER; break; } #else ifh = ifid; #endif j = &open_captures[ifid]; // the interface is already being captured if (j->active) { result = ERROR_INVALID_PARAMETER; break; } #ifdef _WIN32 j->adp = AdpCreate(); dprintf("sniffer>> capture_start() AdpCreate: 0x%.8x", j->adp); AdpSetConfig(j->adp, ifh); hErr = AdpOpenAdapter(j->adp); dprintf("sniffer>> capture_start() AdpOpenAdapter: 0x%.8x", hErr); if (hErr != HNERR_OK) { AdpDestroy(j->adp); result = hErr; break; } j->capture_linktype = 1; // LINKTYPE_ETHERNET forced on windows #else name = get_interface_name_by_index(ifh); if(!name) { result = ERROR_INVALID_PARAMETER; break; } j->pcap = pcap_open_live(name, 65535, 1, 1000, errbuf); if(!j->pcap) { result = EACCES; break; } j->capture_linktype = dlt_to_linktype(pcap_datalink(j->pcap)); // get the datalink associated with the capture, needed when saving pcap file if (-1 == j->capture_linktype) { j->capture_linktype = 1; // force to LINKTYPE_ETHERNET in case of error } if(packet_filter) { struct bpf_program bpf; char *add_filter; char *real_filter = NULL; int rc; dprintf("handling packet_filter"); add_filter = packet_get_tlv_value_string(packet, TLV_TYPE_SNIFFER_ADDITIONAL_FILTER); dprintf("add_filter = %p (%s)", add_filter, add_filter ? add_filter : ""); if(add_filter) { asprintf(&real_filter, "%s and (%s)", packet_filter, add_filter); } else { real_filter = strdup(packet_filter); } dprintf("the real filter string we'll be using is '%s'", real_filter); rc = pcap_compile(j->pcap, &bpf, real_filter, 1, 0); free(real_filter); if(rc == -1) { dprintf("pcap compile reckons '%s' is a failure because of '%s'", real_filter, pcap_geterr(j->pcap)); result = ERROR_INVALID_PARAMETER; break; } dprintf("compiled filter, now setfilter()'ing"); rc = pcap_setfilter(j->pcap, &bpf); pcap_freecode(&bpf); if(rc == -1) { dprintf("can't set filter because '%s'", pcap_geterr(j->pcap)); result = ERROR_INVALID_PARAMETER; break; } dprintf("filter applied successfully"); } j->thread = thread_create((THREADFUNK) sniffer_thread, j, NULL, NULL); if(! j->thread) { pcap_close(j->pcap); break; } #endif j->pkts = calloc(maxp, sizeof(*(j->pkts))); if (j->pkts == NULL) { #ifdef _WIN32 AdpCloseAdapter(j->adp); AdpDestroy(j->adp); #else pcap_close(j->pcap); #endif result = ERROR_ACCESS_DENIED; break; } j->active = 1; j->intf = ifid; j->max_pkts = maxp; j->cur_pkts = 0; j->mtu = AdpCfgGetMaxPacketSize(AdpGetConfig(j->adp)); #ifdef _WIN32 AdpSetOnPacketRecv(j->adp, (FARPROC)sniffer_receive, (DWORD_PTR)j); AdpSetMacFilter(j->adp, mfAll); #else thread_run(j->thread); #endif } while (0); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; unsigned int maxp; CaptureJob *j; DWORD result; HANDLE ifh; check_pssdk(); dprintf("sniffer>> start_capture()"); ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID); maxp = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_PACKET_COUNT); maxp = min(maxp, 200000); maxp = max(maxp, 1); result = ERROR_SUCCESS; do { // the interface is invalid if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } ifh = pktsdk_interface_by_index(ifid); if(ifh == NULL) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface is already being captured if(j->active) { result = ERROR_INVALID_PARAMETER; break; } j->adp = AdpCreate(); dprintf("sniffer>> capture_start() AdpCreate: 0x%.8x", j->adp); AdpSetConfig(j->adp,ifh); hErr = AdpOpenAdapter(j->adp); dprintf("sniffer>> capture_start() AdpOpenAdapter: 0x%.8x", hErr); if (hErr != HNERR_OK) { AdpDestroy(j->adp); result = hErr; break; } j->pkts = calloc(maxp, sizeof(HANDLE)); if(j->pkts == NULL) { AdpCloseAdapter(j->adp); AdpDestroy(j->adp); result = ERROR_ACCESS_DENIED; break; } j->active = 1; j->intf = ifid; j->max_pkts = maxp; j->cur_pkts = 0; j->mtu = AdpCfgGetMaxPacketSize(AdpGetConfig(j->adp)); AdpSetOnPacketRecv(j->adp, (FARPROC) sniffer_receive, (DWORD_PTR)j); AdpSetMacFilter(j->adp, mfAll); } while(0); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); Tlv entries[8]; /* 0: Index 1: Name 2: Description 3: Type 4: MTU 5: Wireless? 6: Accessible? 7: DHCP? */ DWORD result = ERROR_SUCCESS; #ifdef _WIN32 HANDLE hCfg; unsigned int idx = 1; check_pssdk(); hCfg = MgrGetFirstAdapterCfg(hMgr); do { unsigned char *aname = (unsigned char *)AdpCfgGetAdapterNameA(hCfg); unsigned char *adesc = (unsigned char *)AdpCfgGetAdapterDescriptionA(hCfg); unsigned int ahand = htonl((unsigned int)hCfg); unsigned int atype = htonl(AdpCfgGetAdapterType(hCfg)); unsigned int amtu = htonl(AdpCfgGetMaxPacketSize(hCfg)); unsigned int aidx = htonl(idx); BOOL awireless = AdpCfgIsWireless(hCfg); BOOL ausable = AdpCfgGetAccessibleState(hCfg); BOOL adhcp = AdpCfgGetDhcpState(hCfg); memset(entries, 0, sizeof(entries)); dprintf("sniffer>> interface %d - %s - %s", idx, aname, adesc); entries[0].header.type = TLV_TYPE_UINT; entries[0].header.length = sizeof(unsigned int); entries[0].buffer = (PUCHAR)&aidx; entries[1].header.type = TLV_TYPE_STRING; entries[1].header.length = (DWORD)strlen(aname) + 1; entries[1].buffer = aname; entries[2].header.type = TLV_TYPE_STRING; entries[2].header.length = (DWORD)strlen(adesc) + 1; entries[2].buffer = adesc; entries[3].header.type = TLV_TYPE_UINT; entries[3].header.length = sizeof(unsigned int); entries[3].buffer = (PUCHAR)&atype; entries[4].header.type = TLV_TYPE_UINT; entries[4].header.length = sizeof(unsigned int); entries[4].buffer = (PUCHAR)&amtu; entries[5].header.type = TLV_TYPE_BOOL; entries[5].header.length = sizeof(BOOL); entries[5].buffer = (PUCHAR)&awireless; entries[6].header.type = TLV_TYPE_BOOL; entries[6].header.length = sizeof(BOOL); entries[6].buffer = (PUCHAR)&ausable; entries[7].header.type = TLV_TYPE_BOOL; entries[7].header.length = sizeof(BOOL); entries[7].buffer = (PUCHAR)&adhcp; packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8); idx++; } while ((hCfg = MgrGetNextAdapterCfg(hMgr, hCfg)) != NULL); #else char errbuf[PCAP_ERRBUF_SIZE+4]; int aidx = htonl(1); // :~( struct ifaces_list *ifaces; uint32_t i; int aidx_bigendian; int mtu_bigendian; int yes_int = htonl(1); int no_int = 0; int mtu_int = htonl(1514); pcap_if_t *interfaces, *int_iter; interfaces = int_iter = NULL; ifaces = NULL; do { result = pcap_findalldevs(&interfaces, errbuf); if(!result) { // pcap_findalldevs suceeded for(int_iter = interfaces; int_iter; int_iter = int_iter->next) { entries[0].header.type = TLV_TYPE_UINT; entries[0].header.length = sizeof(unsigned int); entries[0].buffer = (PUCHAR)&aidx; entries[1].header.type = TLV_TYPE_STRING; entries[1].header.length = strlen(int_iter->name)+1; entries[1].buffer = (PUCHAR)int_iter->name; entries[2].header.type = TLV_TYPE_STRING; entries[2].header.length = strlen(int_iter->name)+1; entries[2].buffer = (PUCHAR)int_iter->name; entries[3].header.type = TLV_TYPE_UINT; entries[3].header.length = sizeof(unsigned int); entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type? entries[4].header.type = TLV_TYPE_UINT; entries[4].header.length = sizeof(unsigned int); entries[4].buffer = (PUCHAR)&mtu_int; // PKS :-( entries[5].header.type = TLV_TYPE_BOOL; entries[5].header.length = sizeof(BOOL); entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap entries[6].header.type = TLV_TYPE_BOOL; entries[6].header.length = sizeof(BOOL); entries[6].buffer = (PUCHAR)&yes_int; // sure, why not. entries[7].header.type = TLV_TYPE_BOOL; entries[7].header.length = sizeof(BOOL); entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it. packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8); aidx = htonl(ntohl(aidx)+1); // :~( } } else { dprintf("pcap_findalldevs() failed, trying netlink_get_interfaces now, errbuf was %s", errbuf); result = netlink_get_interfaces(&ifaces); if(result) { dprintf("Error when retrieving interfaces info"); break; } // netlink_get_interfaces suceeded for (i = 0; i < ifaces->entries; i++) { aidx_bigendian = htonl(ifaces->ifaces[i].index); entries[0].header.type = TLV_TYPE_UINT; entries[0].header.length = sizeof(uint32_t); entries[0].buffer = (PUCHAR)&aidx_bigendian; entries[1].header.type = TLV_TYPE_STRING; entries[1].header.length = strlen(ifaces->ifaces[i].name)+1; entries[1].buffer = (PUCHAR)ifaces->ifaces[i].name; entries[2].header.type = TLV_TYPE_STRING; entries[2].header.length = strlen(ifaces->ifaces[i].name)+1; entries[2].buffer = (PUCHAR)ifaces->ifaces[i].name; entries[3].header.type = TLV_TYPE_UINT; entries[3].header.length = sizeof(unsigned int); entries[3].buffer = (PUCHAR)&no_int; // xxx, get encapsulation type? mtu_bigendian = htonl(ifaces->ifaces[i].mtu); entries[4].header.type = TLV_TYPE_UINT; entries[4].header.length = sizeof(uint32_t); entries[4].buffer = (PUCHAR)&mtu_bigendian; entries[5].header.type = TLV_TYPE_BOOL; entries[5].header.length = sizeof(BOOL); entries[5].buffer = (PUCHAR)&no_int; // check encaps options / crap entries[6].header.type = TLV_TYPE_BOOL; entries[6].header.length = sizeof(BOOL); entries[6].buffer = (PUCHAR)&yes_int; // sure, why not. entries[7].header.type = TLV_TYPE_BOOL; entries[7].header.length = sizeof(BOOL); entries[7].buffer = (PUCHAR)&no_int; // hrm. not worth it. packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8); } } } while(0); if(ifaces) { free(ifaces); } if (interfaces) { pcap_freealldevs(interfaces); } #endif packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }