Example #1
0
void reader_libpcapfile_opened()
{
    int dlt_to_linktype(int dlt);

    pcapFileHeader.linktype = dlt_to_linktype(pcap_datalink(pcap)) | pcap_datalink_ext(pcap);
    pcapFileHeader.snaplen = pcap_snapshot(pcap);

    offlineFile = pcap_file(pcap);

    if (config.bpf) {
        struct bpf_program   bpf;

        if (pcap_compile(pcap, &bpf, config.bpf, 1, PCAP_NETMASK_UNKNOWN) == -1) {
            LOG("ERROR - Couldn't compile filter: '%s' with %s", config.bpf, pcap_geterr(pcap));
            exit(1);
        }

	if (pcap_setfilter(pcap, &bpf) == -1) {
            LOG("ERROR - Couldn't set filter: '%s' with %s", config.bpf, pcap_geterr(pcap));
            exit(1);
        }
    }

    int t;
    for (t = 0; t < MOLOCH_FILTER_MAX; t++) {
        if (config.bpfsNum[t]) {
            int i;
            if (bpf_programs[t]) {
                for (i = 0; i < config.bpfsNum[t]; i++) {
                    pcap_freecode(&bpf_programs[t][i]);
                }
            } else {
                bpf_programs[t] = malloc(config.bpfsNum[t]*sizeof(struct bpf_program));
            }
            for (i = 0; i < config.bpfsNum[t]; i++) {
                if (pcap_compile(pcap, &bpf_programs[t][i], config.bpfs[t][i], 1, PCAP_NETMASK_UNKNOWN) == -1) {
                    LOG("ERROR - Couldn't compile filter: '%s' with %s", config.bpfs[t][i], pcap_geterr(pcap));
                    exit(1);
                }
            }
            moloch_reader_should_filter = reader_libpcapfile_should_filter;
        }
    }

    if (config.flushBetween)
        moloch_session_flush();

    offlinePcapName = strdup(offlinePcapFilename);

    int fd = pcap_fileno(pcap);
    if (fd == -1) {
        g_timeout_add(0, reader_libpcapfile_read, NULL);
    } else {
        moloch_watch_fd(fd, MOLOCH_GIO_READ_COND, reader_libpcapfile_read, NULL);
    }
}
Example #2
0
pcap_dumper_t *
pcap_ng_dump_open(pcap_t *p, const char *fname)
{
	FILE *f;
	int linktype;
	
	/*
	 * If this pcap_t hasn't been activated, it doesn't have a
	 * link-layer type, so we can't use it.
	 */
	if (!p->activated) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				 "%s: not-yet-activated pcap_t passed to pcap_ng_dump_open",
				 fname);
		return (NULL);
	}
	
	if (fname[0] == '-' && fname[1] == '\0') {
		f = stdout;
		fname = "standard output";
	} else {
		f = fopen(fname, "wb");
		if (f == NULL) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
					 fname, pcap_strerror(errno));
			return (NULL);
		}
	}
	
	/*
	 * Make sure a section header will be added and that
	 * any information to a previous section gets cleared.
	 */
	pcap_ng_init_section_info(p);
	
	/*
	 * When using the block based API, the section header and 
	 * interface description blocks are given by the caller
	 */
	if (p->linktype != DLT_PKTAP && p->linktype != DLT_PCAPNG) {
		linktype = dlt_to_linktype(p->linktype);
		if (linktype == -1) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
					 "%s: link-layer type %d isn't supported in savefiles",
					 fname, p->linktype);
			if (f != stdout)
				fclose(f);
			return (NULL);
		}
		linktype |= p->linktype_ext;
		
		return (pcap_ng_setup_dump(p, linktype, f, fname));
	} else {
		return ((pcap_dumper_t *)f);
	}
}
Example #3
0
void reader_libpcap_start() {
    int dlt_to_linktype(int dlt);

    //ALW - Bug: assumes all linktypes are the same
    pcapFileHeader.linktype = dlt_to_linktype(pcap_datalink(pcaps[0])) | pcap_datalink_ext(pcaps[0]);
    pcapFileHeader.snaplen = pcap_snapshot(pcaps[0]);

    pcap_t *dpcap = pcap_open_dead(pcapFileHeader.linktype, pcapFileHeader.snaplen);
    int t;
    for (t = 0; t < MOLOCH_FILTER_MAX; t++) {
        if (config.bpfsNum[t]) {
            int i;
            if (bpf_programs[t]) {
                for (i = 0; i < config.bpfsNum[t]; i++) {
                    pcap_freecode(&bpf_programs[t][i]);
                }
            } else {
                bpf_programs[t] = malloc(config.bpfsNum[t]*sizeof(struct bpf_program));
            }
            for (i = 0; i < config.bpfsNum[t]; i++) {
                if (pcap_compile(dpcap, &bpf_programs[t][i], config.bpfs[t][i], 1, PCAP_NETMASK_UNKNOWN) == -1) {
                    LOG("ERROR - Couldn't compile filter: '%s' with %s", config.bpfs[t][i], pcap_geterr(dpcap));
                    exit(1);
                }
            }
            moloch_reader_should_filter = reader_libpcap_should_filter;
        }
    }

    int i;
    for (i = 0; i < MAX_INTERFACES && config.interface[i]; i++) {
        if (config.bpf) {
            struct bpf_program   bpf;

            if (pcap_compile(pcaps[i], &bpf, config.bpf, 1, PCAP_NETMASK_UNKNOWN) == -1) {
                LOG("ERROR - Couldn't compile filter: '%s' with %s", config.bpf, pcap_geterr(pcaps[i]));
                exit(1);
            }

            if (pcap_setfilter(pcaps[i], &bpf) == -1) {
                LOG("ERROR - Couldn't set filter: '%s' with %s", config.bpf, pcap_geterr(pcaps[i]));
                exit(1);
            }
        }

        char name[100];
        snprintf(name, sizeof(name), "moloch-pcap%d", i);
        g_thread_new(name, &reader_libpcap_thread, (gpointer)pcaps[i]);
    }
}
Example #4
0
/*
 * Initialize so that sf_write() will output to the given stream.
 */
pcap_dumper_t *
pcap_dump_fopen(pcap_t *p, FILE *f)
{	
	int linktype;

	linktype = dlt_to_linktype(p->linktype);
	if (linktype == -1) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "stream: link-layer type %d isn't supported in savefiles",
		    p->linktype);
		return (NULL);
	}
	linktype |= p->linktype_ext;

	return (pcap_setup_dump(p, linktype, f, "stream"));
}
Example #5
0
/*
 * Initialize so that sf_write() will output to the file named 'fname'.
 */
pcap_dumper_t *
pcap_dump_open(pcap_t *p, const char *fname)
{
	FILE *f;
	int linktype;

	/*
	 * If this pcap_t hasn't been activated, it doesn't have a
	 * link-layer type, so we can't use it.
	 */
	if (!p->activated) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "%s: not-yet-activated pcap_t passed to pcap_dump_open",
		    fname);
		return (NULL);
	}
	linktype = dlt_to_linktype(p->linktype);
	if (linktype == -1) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "%s: link-layer type %d isn't supported in savefiles",
		    fname, p->linktype);
		return (NULL);
	}
	linktype |= p->linktype_ext;

	if (fname[0] == '-' && fname[1] == '\0') {
		f = stdout;
		fname = "standard output";
	} else {
#if !defined(WIN32) && !defined(MSDOS)
		f = fopen(fname, "w");
#else
		f = fopen(fname, "wb");
#endif
		if (f == NULL) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
			    fname, pcap_strerror(errno));
			return (NULL);
		}
	}
	return (pcap_setup_dump(p, linktype, f, fname));
}
Example #6
0
pcap_dumper_t *
pcap_dump_open_append(pcap_t *p, const char *fname)
{
	FILE *f;
	int linktype;
	int amt_read;
	struct pcap_file_header ph;

	linktype = dlt_to_linktype(p->linktype);
	if (linktype == -1) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
		    "%s: link-layer type %d isn't supported in savefiles",
		    fname, linktype);
		return (NULL);
	}
	if (fname[0] == '-' && fname[1] == '\0')
		return (pcap_setup_dump(p, linktype, stdout, "standard output"));

#if !defined(_WIN32) && !defined(MSDOS)
	f = fopen(fname, "r+");
#else
	f = fopen(fname, "rb+");
#endif
	if (f == NULL) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
		    fname, pcap_strerror(errno));
		return (NULL);
	}

	/*
	 * Try to read a pcap header.
	 */
	amt_read = fread(&ph, 1, sizeof (ph), f);
	if (amt_read != sizeof (ph)) {
		if (ferror(f)) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
			    fname, pcap_strerror(errno));
			fclose(f);
			return (NULL);
		} else if (feof(f) && amt_read > 0) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: truncated pcap file header", fname);
			fclose(f);
			return (NULL);
		}
	}

#if defined(_WIN32) || defined(MSDOS)
	/*
	 * We turn off buffering.
	 * XXX - why?  And why not on the standard output?
	 */
	setbuf(f, NULL);
#endif

	/*
	 * If a header is already present and:
	 *
	 *	it's not for a pcap file of the appropriate resolution
	 *	and the right byte order for this machine;
	 *
	 *	the link-layer header types don't match;
	 *
	 *	the snapshot lengths don't match;
	 *
	 * return an error.
	 */
	if (amt_read > 0) {
		/*
		 * A header is already present.
		 * Do the checks.
		 */
		switch (ph.magic) {

		case TCPDUMP_MAGIC:
			if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				    "%s: different time stamp precision, cannot append to file", fname);
				fclose(f);
				return (NULL);
			}
			break;

		case NSEC_TCPDUMP_MAGIC:
			if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
				    "%s: different time stamp precision, cannot append to file", fname);
				fclose(f);
				return (NULL);
			}
			break;

		case SWAPLONG(TCPDUMP_MAGIC):
		case SWAPLONG(NSEC_TCPDUMP_MAGIC):
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: different byte order, cannot append to file", fname);
			fclose(f);
			return (NULL);

		case KUZNETZOV_TCPDUMP_MAGIC:
		case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC):
		case NAVTEL_TCPDUMP_MAGIC:
		case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: not a pcap file to which we can append", fname);
			fclose(f);
			return (NULL);

		default:
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: not a pcap file", fname);
			fclose(f);
			return (NULL);
		}

		/*
		 * Good version?
		 */
		if (ph.version_major != PCAP_VERSION_MAJOR ||
		    ph.version_minor != PCAP_VERSION_MINOR) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: version is %u.%u, cannot append to file", fname,
			    ph.version_major, ph.version_minor);
			fclose(f);
			return (NULL);
		}
		if (linktype != ph.linktype) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: different linktype, cannot append to file", fname);
			fclose(f);
			return (NULL);
		}
		if (p->snapshot != ph.snaplen) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
			    "%s: different snaplen, cannot append to file", fname);
			fclose(f);
			return (NULL);
		}
	} else {
		/*
		 * A header isn't present; attempt to write it.
		 */
		if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) {
			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
			    fname, pcap_strerror(errno));
			(void)fclose(f);
			return (NULL);
		}
	}

	/*
	 * Start writing at the end of the file.
	 */
	if (fseek(f, 0, SEEK_END) == -1) {
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't seek to end of %s: %s",
		    fname, pcap_strerror(errno));
		(void)fclose(f);
		return (NULL);
	}
	return ((pcap_dumper_t *)f);
}
Example #7
0
LOCAL void reader_libpcapfile_opened()
{
    int dlt_to_linktype(int dlt);

    if (config.flushBetween)
        moloch_session_flush();

    moloch_packet_set_linksnap(dlt_to_linktype(pcap_datalink(pcap)) | pcap_datalink_ext(pcap), pcap_snapshot(pcap));

    offlineFile = pcap_file(pcap);

    if (config.bpf && pcapFileHeader.linktype != 239) {
        struct bpf_program   bpf;

        if (pcap_compile(pcap, &bpf, config.bpf, 1, PCAP_NETMASK_UNKNOWN) == -1) {
            LOGEXIT("ERROR - Couldn't compile filter: '%s' with %s", config.bpf, pcap_geterr(pcap));
        }

	if (pcap_setfilter(pcap, &bpf) == -1) {
            LOGEXIT("ERROR - Couldn't set filter: '%s' with %s", config.bpf, pcap_geterr(pcap));
        }
    }

    readerPos++;
    if (readerFileName[readerPos])
        moloch_free_later(readerFileName[readerPos], g_free);
    readerFileName[readerPos] = g_strdup(offlinePcapFilename);

    int fd = pcap_fileno(pcap);
    if (fd == -1) {
        g_timeout_add(0, reader_libpcapfile_read, NULL);
    } else {
        moloch_watch_fd(fd, MOLOCH_GIO_READ_COND, reader_libpcapfile_read, NULL);
    }

    if (filenameOpsNum > 0) {

        // Free any previously allocated
        if (readerFieldOps[readerPos].size > 0)
            moloch_field_ops_free(&readerFieldOps[readerPos]);

        moloch_field_ops_init(&readerFieldOps[readerPos], filenameOpsNum, MOLOCH_FIELD_OPS_FLAGS_COPY);

        // Go thru all the filename ops looking for matches and then expand the value string
        int i;
        for (i = 0; i < filenameOpsNum; i++) {
            GMatchInfo *match_info = 0;
            g_regex_match(filenameOps[i].regex, offlinePcapFilename, 0, &match_info);
            if (g_match_info_matches(match_info)) {
                GError *error = 0;
                char *expand = g_match_info_expand_references(match_info, filenameOps[i].expand, &error);
                if (error) {
                    LOG("Error expanding '%s' with '%s' - %s", offlinePcapFilename, filenameOps[i].expand, error->message);
                    g_error_free(error);
                }
                if (expand) {
                    moloch_field_ops_add(&readerFieldOps[readerPos], filenameOps[i].field, expand, -1);
                    g_free(expand);
                }
            }
            g_match_info_free(match_info);
        }
    }
}
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;
}