DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; CaptureJob *j; DWORD result; check_pssdk(); dprintf("sniffer>> stop_capture()"); ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID); dprintf("sniffer>> stop_capture(0x%.8x)", ifid); result = ERROR_SUCCESS; do { // the interface is invalid if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface is not being captured #ifdef _WIN32 if (!j->adp) #else if (!j->pcap) #endif { result = ERROR_INVALID_PARAMETER; break; } lock_acquire(snifferm); j->active = 0; #ifdef _WIN32 AdpSetMacFilter(j->adp, 0); AdpCloseAdapter(j->adp); AdpDestroy(j->adp); #else thread_sigterm(j->thread); thread_join(j->thread); // should take less than 1 second :p #endif packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes); lock_release(snifferm); dprintf("sniffer>> stop_capture() interface %d processed %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes); } while (0); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
DWORD request_sniffer_capture_release(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid,i; CaptureJob *j; DWORD result; check_pssdk(); dprintf("sniffer>> release_capture()"); ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID); dprintf("sniffer>> release_capture(0x%.8x)", ifid); result = ERROR_SUCCESS; do { // the interface is invalid if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface is not being captured #ifdef _WIN32 if(! j->adp || j->active == 1) #else if(! j->pcap || j->active == 1) #endif { result = ERROR_INVALID_PARAMETER; break; } lock_acquire(snifferm); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int) j->cur_bytes); dprintf("sniffer>> release_capture() interface %d released %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes); for(i=0; i<j->max_pkts; i++) { if(!j->pkts[i]) break; PktDestroy(j->pkts[i]); j->pkts[i] = NULL; } free(j->pkts); memset(j, 0, sizeof(CaptureJob)); lock_release(snifferm); } while(0); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid,i; CaptureJob *j; DWORD result; check_pssdk(); dprintf("sniffer>> stop_capture()"); ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID); dprintf("sniffer>> stop_capture(0x%.8x)", ifid); result = ERROR_SUCCESS; do { // the interface is invalid if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface is not being captured if(! j->adp) { result = ERROR_INVALID_PARAMETER; break; } EnterCriticalSection(&sniffercs); j->active = 0; AdpSetMacFilter(j->adp, 0); AdpCloseAdapter(j->adp); AdpDestroy(j->adp); for(i=0; i<j->max_pkts; i++) { if(!j->pkts[i]) break; PktDestroy(j->pkts[i]); j->pkts[i] = NULL; } free(j->pkts); memset(j, 0, sizeof(CaptureJob)); LeaveCriticalSection(&sniffercs); dprintf("sniffer>> stop_capture() interface %d processed %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes); } while(0); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
static DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; unsigned int bcnt; CaptureJob *j; DWORD result; check_pssdk(); dprintf("sniffer>> capture_dump_read()"); ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID); bcnt = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_BYTE_COUNT); bcnt = min(bcnt, 32*1024*1024); dprintf("sniffer>> capture_dump_read(0x%.8x, %d)", ifid, bcnt); result = ERROR_SUCCESS; do { // the interface is invalid if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0); break; } j = &open_captures[ifid]; if(! j->dbuf) { packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0); break; } if(j->didx + bcnt > j->dlen) { bcnt = j->dlen - j->didx; } packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt); packet_add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf+j->didx, bcnt); j->didx += bcnt; } while(0); // Free memory if the read is complete if(j->didx >= j->dlen-1) { free(j->dbuf); j->dbuf = NULL; j->didx = 0; j->dlen = 0; } packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }
DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; CaptureJob *j; DWORD result; check_pssdk(); dprintf("sniffer>> capture_stats()"); ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID); dprintf("sniffer>> capture_stats(0x%.8x)", ifid); result = ERROR_SUCCESS; do { // the interface is invalid if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface was not captured #ifdef _WIN32 if(! j->adp) #else if (!j->pcap) #endif { result = ERROR_INVALID_PARAMETER; break; } lock_acquire(snifferm); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes); lock_release(snifferm); } 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? */ 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_dump(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; unsigned int rbuf,mbuf; unsigned int *tmp; CaptureJob *j; DWORD result,pcnt,bcnt,rcnt,i; DWORD thi, tlo; check_pssdk(); dprintf("sniffer>> capture_dump()"); ifid = packet_get_tlv_value_uint(packet,TLV_TYPE_SNIFFER_INTERFACE_ID); dprintf("sniffer>> capture_dump(0x%.8x)", ifid); result = ERROR_SUCCESS; EnterCriticalSection(&sniffercs); do { // the interface is invalid if(ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface was not captured if(! j->adp) { result = ERROR_INVALID_PARAMETER; break; } // Free any existing packet buffer if(j->dbuf) { free(j->dbuf); j->dbuf = NULL; j->dlen = 0; j->didx = 0; } // Add basic stats pcnt = 0; bcnt = 0; rcnt = 0; mbuf = (1024*1024); j->dbuf = malloc(mbuf); rbuf = 0; for(i=0; i<j->max_pkts; i++) { if(!j->pkts[i]) break; rbuf += (8 + 8 + 4 + PktGetPacketSize(j->pkts[i])); if(mbuf < rbuf) { mbuf += (1024*1024); j->dbuf = realloc(j->dbuf, mbuf); if(!j->dbuf) { dprintf("sniffer>> realloc of %d bytes failed!", rbuf); result = ERROR_NOT_ENOUGH_MEMORY; break; } } tmp = (unsigned int *)( j->dbuf + rcnt ); tlo = PktGetId(j->pkts[i], &thi); *tmp = htonl(thi); tmp++; *tmp = htonl(tlo); tmp++; tlo = PktGetTimeStamp(j->pkts[i], &thi); *tmp = htonl(thi); tmp++; *tmp = htonl(tlo); tmp++; tlo = PktGetPacketSize(j->pkts[i]); *tmp = htonl(tlo); tmp++; memcpy(j->dbuf+rcnt+20, PktGetPacketData(j->pkts[i]), tlo); rcnt += 20 + tlo; pcnt++; PktDestroy(j->pkts[i]); j->pkts[i] = NULL; } j->dlen = rcnt; packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt); dprintf("sniffer>> finished processing packets"); j->cur_bytes = 0; j->cur_pkts = 0; j->idx_pkts = 0; } while(0); LeaveCriticalSection(&sniffercs); 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_capture_dump_read(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid, i; unsigned int bcnt; CaptureJob *j; DWORD result; check_pssdk(); dprintf("sniffer>> capture_dump_read()"); ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID); bcnt = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_BYTE_COUNT); bcnt = min(bcnt, 32 * 1024 * 1024); dprintf("sniffer>> capture_dump_read(0x%.8x, %d)", ifid, bcnt); result = ERROR_SUCCESS; do { // the interface is invalid if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0); goto fail; } j = &open_captures[ifid]; if (!j->dbuf) { packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0); goto fail; } if (j->didx + bcnt > j->dlen) { bcnt = j->dlen - j->didx; } packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt); packet_add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf + j->didx, bcnt); j->didx += bcnt; } while (0); // Free memory if the read is complete if (j->didx >= j->dlen - 1) { free(j->dbuf); j->dbuf = NULL; j->didx = 0; j->dlen = 0; // if dump occurs when interface is not active, i.e sniff has ended, release info if (j->active == 0) { dprintf("sniffer>> capture_dump_read, release CaptureJob"); lock_acquire(snifferm); for (i = 0; i < j->max_pkts; i++) { if (!j->pkts[i]) break; PktDestroy(j->pkts[i]); j->pkts[i] = NULL; } free(j->pkts); memset(j, 0, sizeof(CaptureJob)); lock_release(snifferm); } } fail: 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; #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_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; }
DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); unsigned int ifid; unsigned int rbuf, mbuf; unsigned int *tmp; CaptureJob *j; DWORD result, pcnt, rcnt, i; #ifdef _WIN64 ULONGLONG thilo; #endif DWORD thi, tlo; check_pssdk(); dprintf("sniffer>> capture_dump()"); ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID); dprintf("sniffer>> capture_dump(0x%.8x)", ifid); result = ERROR_SUCCESS; lock_acquire(snifferm); do { // the interface is invalid if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES) { result = ERROR_INVALID_PARAMETER; break; } j = &open_captures[ifid]; // the interface was not captured #ifdef _WIN32 if (!j->adp) #else if(! j->pcap) #endif { result = ERROR_INVALID_PARAMETER; break; } // Free any existing packet buffer if (j->dbuf) { free(j->dbuf); j->dbuf = NULL; j->dlen = 0; j->didx = 0; } // Add basic stats pcnt = 0; rcnt = 0; mbuf = (1024 * 1024); j->dbuf = malloc(mbuf); rbuf = 0; for (i = 0; i < j->max_pkts; i++) { if (!j->pkts[i]) break; rbuf += (8 + 8 + 4 + PktGetPacketSize(j->pkts[i])); if (mbuf < rbuf) { mbuf += (1024 * 1024); j->dbuf = realloc(j->dbuf, mbuf); if (!j->dbuf) { dprintf("sniffer>> realloc of %d bytes failed!", rbuf); result = ERROR_NOT_ENOUGH_MEMORY; break; } } tmp = (unsigned int *)(j->dbuf + rcnt); #ifdef _WIN64 thilo = PktGetId(j->pkts[i]); thi = (DWORD)(thilo >> 32); tlo = (DWORD)(thilo & 0xFFFFFFFF); #else tlo = PktGetId(j->pkts[i], &thi); #endif *tmp = htonl(thi); tmp++; *tmp = htonl(tlo); tmp++; #ifdef _WIN64 thilo = PktGetTimeStamp(j->pkts[i]); thi = (DWORD)(thilo >> 32); tlo = (DWORD)(thilo & 0xFFFFFFFF); #else tlo = PktGetTimeStamp(j->pkts[i], &thi); #endif *tmp = htonl(thi); tmp++; *tmp = htonl(tlo); tmp++; tlo = PktGetPacketSize(j->pkts[i]); *tmp = htonl(tlo); tmp++; memcpy(j->dbuf + rcnt + 20, PktGetPacketData(j->pkts[i]), tlo); rcnt += 20 + tlo; pcnt++; PktDestroy(j->pkts[i]); j->pkts[i] = NULL; } j->dlen = rcnt; packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt); packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt); // add capture datalink, needed when saving capture file, use TLV_TYPE_SNIFFER_INTERFACE_ID not to create a new TLV type packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_INTERFACE_ID, j->capture_linktype); dprintf("sniffer>> finished processing packets"); j->cur_bytes = 0; j->cur_pkts = 0; j->idx_pkts = 0; } while (0); lock_release(snifferm); packet_transmit_response(result, remote, response); return ERROR_SUCCESS; }