예제 #1
0
파일: pcap.c 프로젝트: ajaykgp/piffle
/*
 * Set up the pcap plumbing and call the main filter loop.
 */
static void do_filter(void)
{
    char errbuf[PCAP_ERRBUF_SIZE];	/* Error buffer for pcap */
    struct pcap_plumbing plumbing = { NULL, NULL };

    if (opt_infile) {
	plumbing.source = pcap_open_offline(opt_infile, errbuf);
    } else {
	/* A NULL opt_device is safe; pcap takes it to mean "any".  */
	plumbing.source = 
            pcap_open_live(opt_device, PCAP_MAX_PKT_SZ, PCAP_PROMISC,
                           PCAP_TIMEOUT, errbuf);
    }

    if (!plumbing.source) {
	die(STATUS_IO, "error opening file '%s' or device '%s'%s",
	    opt_infile, opt_device, errbuf);
    }

    if (opt_outfile) {
	plumbing.sink = pcap_dump_open(plumbing.source, opt_outfile);
	if (!plumbing.sink) {
	    die(STATUS_IO, "error opening output file %s", opt_outfile);
	}
    }

    if (opt_filter) {
	struct bpf_program bpf;
	if (pcap_compile(plumbing.source, &bpf, opt_filter, 0, 0)) {
            char *pcap_error = pcap_geterr(plumbing.source);
            die(STATUS_PCAP, "bpf compile error %s", pcap_error);
	}
	if (pcap_setfilter(plumbing.source, &bpf)) {
            char *pcap_error = pcap_geterr(plumbing.source);
	    die(STATUS_PCAP, "bpf filter error %s", pcap_error);
	}
	pcap_freecode(&bpf);
    }

    filter_loop(&plumbing);

    pcap_dump_flush(plumbing.sink);
    pcap_dump_close(plumbing.sink);
    pcap_close(plumbing.source);
}
예제 #2
0
void MainWindow::onSaveAsPcapButtonClicked()
{
    auto saveFileName = QFileDialog::getSaveFileName(this, tr("Save Pcap File"), "/home/", tr("Pcap Files (*.pcap)"));

    if (saveFileName != "")
    {
        auto dumpHandler = pcap_dump_open(mSessionHandler, saveFileName.toStdString().c_str());

        for(auto &eachPacket : *mPacketDataBuffer)
        {
            pcap_dump((u_char*)dumpHandler, eachPacket->GetRawDataHeader(), eachPacket->GetRawData());
        }

        // flush it!
        pcap_dump_flush(dumpHandler);
        pcap_dump_close(dumpHandler);
    }
}
예제 #3
0
	~PhysicalMedium_pimpl()
	{
		close(poller.epfd);
		timer_delete(timer);
		/* Remove and free nodes from registration list and then from
		 * the node hash map, they can only be in one of these. */
		std::unordered_map<uint64_t, DeviceNode *>::iterator iter;
		regListMapMutex.lock();
		iter = regListMap.begin();
		while (iter != regListMap.end()) {
			DeviceNode *node = iter->second;

			xlog(LOG_DEBUG, "%s: Removing Node ID (0x%016llx) from registration list",
					name, node->getNodeId());
			assert(iter->first == node->getNodeId());
			iter = regListMap.erase(iter);
			delete node;
		}
		regListMapMutex.unlock();

		std::unordered_map<uint64_t, DeviceNode *>::iterator iterMap;
		/* Remove and free nodes from the node hash map */
		iterMap = nodeHashMap.begin();
		while (iterMap != nodeHashMap.end()) {
			DeviceNode *node = iterMap->second;

			xlog(LOG_DEBUG, "%s: Removing Node ID (0x%016llx) from node hash map",
					name, iterMap->first);
			assert(iterMap->first == node->getNodeId());
			iterMap = nodeHashMap.erase(iterMap);
			/* This will delete timer and close socket */
			delete node;
		}

		free(name);

		if (tx.mcastsockfd != -1)
			close(tx.mcastsockfd);

		pcap_dump_flush(pcap.dumper);
		pcap_dump_close(pcap.dumper);
		pcap_close(pcap.fake);
	}
void PCAPExporterPipe::performShutdown()
{
	SignalHandler::getInstance().unregisterSignalHandler(SIGCHLD, this);
	SignalHandler::getInstance().unregisterSignalHandler(SIGPIPE, this);
	if(restartOnSignal)
		SignalHandler::getInstance().unregisterSignalHandler(SIGUSR2, this);
	msg(MSG_DEBUG, "Performing shutdown for PID %d", fifoReaderPid);
	sleep(1);
	if (dumper) {
		if (-1 == pcap_dump_flush(dumper)) {
			msg(MSG_FATAL, "PCAPExporterPipe: Could not flush dump file");
		}

		pcap_dump_close(dumper);
		if (fifoReaderPid != 0 ) {
			kill_all(fifoReaderPid);
		}
	}
}
예제 #5
0
void write_pcap_decrypted(struct wlantest *wt, const u8 *buf1, size_t len1,
			  const u8 *buf2, size_t len2)
{
	struct pcap_pkthdr h;
	u8 rtap[] = {
		0x00 /* rev */,
		0x00 /* pad */,
		0x0e, 0x00, /* header len */
		0x00, 0x00, 0x00, 0x40, /* present flags */
		0x00, 0x13, 0x74, QCA_RADIOTAP_VID_WLANTEST,
		0x00, 0x00
	};
	u8 *buf;
	size_t len;

	if (!wt->write_pcap_dumper && !wt->pcapng)
		return;

	os_free(wt->decrypted);
	len = sizeof(rtap) + len1 + len2;
	wt->decrypted = buf = os_malloc(len);
	if (buf == NULL)
		return;
	wt->decrypted_len = len;
	os_memcpy(buf, rtap, sizeof(rtap));
	if (buf1) {
		os_memcpy(buf + sizeof(rtap), buf1, len1);
		buf[sizeof(rtap) + 1] &= ~0x40; /* Clear Protected flag */
	}
	if (buf2)
		os_memcpy(buf + sizeof(rtap) + len1, buf2, len2);

	if (!wt->write_pcap_dumper)
		return;

	os_memset(&h, 0, sizeof(h));
	h.ts = wt->write_pcap_time;
	h.caplen = len;
	h.len = len;
	pcap_dump(wt->write_pcap_dumper, &h, buf);
	if (wt->pcap_no_buffer)
		pcap_dump_flush(wt->write_pcap_dumper);
}
예제 #6
0
파일: pcap_dump.c 프로젝트: pcrowley/OSF
/**
 * Per-packet hook routine for your monitor.
 * This is the main workhorse. It should be efficient. The parameters are
 * designed to help you access simple data (local/remote ip/port, protocol
 * info, pointers to specific headers, etc.).
 * @param *key contains local+remote ip and port, l3 and l4 protocol
 * @param direction specifies if packet was inbound or outbound
 * @param *pkt wrapper the actual packet data, has length and packet data
 */
void monitor_hook(struct session_key *key, int direction,
                  struct pna_packet *pkt)
{
    static int npkts = 0;
    static pcap_dumper_t *dumper;

    time_t start;
    struct tm *start_gmt;
    struct pcap_pkthdr hdr;
    char outfile[MAX_STR];

    /* open up a dumper if needed */
    if (npkts == 0) {
        start = time(NULL);
        start_gmt = gmtime((time_t *)&start);
        strftime(outfile, MAX_STR, outname, start_gmt);
        dumper = pcap_dump_open(pcap, outfile);

        printf("dumper open\n");
        fflush(stdout);
    }

    /* fill out header info and write out packet to pcap file */
    hdr.ts = pkt->timestamp;
    hdr.len = pkt->len;
    hdr.caplen = pkt->caplen;
    pcap_dump((u_char *)dumper, &hdr, (u_char *)pkt->data);
    npkts += 1;

    /* enough packets in this trace, create a new one */
    if (PKTS_PER_TRACE == npkts) {
        npkts = 0;
        pcap_dump_close(dumper);
        printf("dumper close\n");
        fflush(stdout);
    }
    else {
        pcap_dump_flush(dumper);
        printf("dumper flush\n");
        fflush(stdout);
    }
}
예제 #7
0
/* Packet handler: write packets to a file in CAP format */
static int pf_capture_pkt_handler(netio_desc_t *nio,void *pkt,size_t len,
                                  void *opt)
{
   struct netio_filter_capture *c = opt;
   struct pcap_pkthdr pkt_hdr;

   if (c != NULL) {
      gettimeofday(&pkt_hdr.ts,0);
      pkt_hdr.caplen = m_min(len, (u_int)pcap_snapshot(c->desc));
      pkt_hdr.len = len;

      /* thread safe dump */
      pthread_mutex_lock(&c->lock);
      pcap_dump((u_char *)c->dumper,&pkt_hdr,pkt);
      pcap_dump_flush(c->dumper);
      pthread_mutex_unlock(&c->lock);
   }

   return(NETIO_FILTER_ACTION_PASS);
}
예제 #8
0
/**
 * @brief ‐ 将一个数据包写入pcap文件
 * @params ‐ pdumper : pcap文件指针
 *			 ts	: 数据包时间戳,精度为10ns
 *			 data_buf : 数据包指针
 *			 len : data_buf的长度
 * @ret ‐ None
 * @author ‐ lc
 * @date ‐ 2018-06-11
 **/
static void iridium_write_pcap_single(pcap_dumper_t *pdumper, guint64 ts, const char *data_buf, int len)
{
	struct pcap_pkthdr hdr;
	
	/* 数据包长度 */
	hdr.caplen = len;
	hdr.len = len;

	/* 数据包时间戳 */
	hdr.ts.tv_sec = ts/100000000;
	hdr.ts.tv_usec = ts/100;
	
	/* 将数据包写入pcap文件 */
	pcap_dump((guint8*)pdumper, &hdr, (const guint8 *)data_buf);
			
	/* 刷新缓冲区 */
	pcap_dump_flush(pdumper);

	return;
}
예제 #9
0
static void
_resend_outgoing(struct pkt *pkt)
{
    if (timerisset(&pkt->pkt_ts)) {
        timeout_set(&pkt->pkt_ev, _timed_outgoing, pkt);
        timeout_add(&pkt->pkt_ev, &pkt->pkt_ts);
    } else {
        eth_pack_hdr(pkt->pkt_eth, ctx.dmac.addr_eth,
            ctx.smac.addr_eth, ETH_TYPE_IP);
        if(ctx.dfile) {
            struct pcap_pkthdr pkthdr;
            gettimeofday(&pkthdr.ts, NULL);
            pkthdr.caplen = pkthdr.len = pkt->pkt_end - pkt->pkt_data;
            pcap_dump((u_char*)ctx.dfile, &pkthdr, pkt->pkt_data);
            pcap_dump_flush(ctx.dfile);
        }
        else if (eth_send(ctx.eth, pkt->pkt_data,
            pkt->pkt_end - pkt->pkt_data) < 0)
            warn("eth_send");

        pkt_free(pkt);
    }
}
예제 #10
0
void analyze_packet_qqtkt_write1(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
	//printf("%s\n",&packet[48]);
	//printf("yyyyyyy\n");	
	if(exitflag)
	{
		  int ret = pcap_dump_flush(out_pcap);
		if (ret == -1) {
			
			printf("error in pcap_dump_flush\n");

		}

		pcap_dump_close(out_pcap);
		
		exitflag=0;
		exit(0);
	} 

     	//printf("***\n");
        pcap_dump((unsigned char*)out_pcap, header, packet);

      
}
예제 #11
0
void PcapFileWriterDevice::close()
{
	if (!m_AppendMode && pcap_dump_flush(m_PcapDumpHandler) == -1)
	{
		LOG_ERROR("Error while flushing the packets to file");
	}
	// in append mode it's impossible to use pcap_dump_flush, see comment above pcap_dump
	else if (m_AppendMode && fflush(m_File) == EOF)
	{
		LOG_ERROR("Error while flushing the packets to file");
	}

	IPcapFileDevice::close();

	if (!m_AppendMode)
		pcap_dump_close(m_PcapDumpHandler);
	else
		// in append mode it's impossible to use pcap_dump_close, see comment above pcap_dump
		fclose(m_File);

	m_PcapDumpHandler = NULL;
	m_File = NULL;
	LOG_DEBUG("File writer closed for file '%s'", m_FileName);
}
PacketFilter_PcapLogger::~PacketFilter_PcapLogger() {
    pcap_dump_flush(pcap_writer);
    pcap_close(pcap_file);
    fclose(file);
}
void PacketFilter_PcapLogger::filter_setup_packet(SetupPacket* packet,bool direction_out) {
    struct pcap_pkthdr ph;
    struct timeval ts;
    __u8 *buf, *ptr;
    pcap_usb_header *usb_pkthdr;
    __u32 data_len, buf_len;

    if(packet->data != NULL)
        data_len = packet->ctrl_req.wLength;
    else
        data_len = 0;

    buf_len = sizeof(pcap_usb_header) + data_len;
    buf = (__u8 *) malloc(buf_len);
    if(buf == NULL) {
        fprintf(stderr, "PcapLogger: Unable to allocate packet buffer\n");
        return;
    }
    ptr = buf;

    gettimeofday(&ts, NULL);
    ph.ts = ts;
    ph.caplen = ph.len = buf_len;

    usb_pkthdr = (pcap_usb_header *) buf;


    /* Hardcoding these for now, could retrieve them in future if we're handling
     * multiple devices, but for now we're only ever going to have a single device
     */
    usb_pkthdr->device_address = 1;
    usb_pkthdr->bus_id = 1;
    usb_pkthdr->transfer_type = 2; /* This is almost certainly wrong on many packets */

    /*if !=0 the urb setup header is not present*/
    usb_pkthdr->setup_flag = 0;
    /*if !=0 no urb data is present*/
    usb_pkthdr->data_flag = 1;
    if (data_len) {
        /* FIXME Need to set transfer mode correctly (see pcap/usb.h) */
        usb_pkthdr->event_type = URB_COMPLETE;
    } else {
        /* FIXME Need to set transfer mode correctly (see pcap/usb.h) */
        usb_pkthdr->event_type = URB_SUBMIT;
    }

    usb_pkthdr->endpoint_number = 0;
    usb_pkthdr->ts_sec = ts.tv_sec;
    usb_pkthdr->ts_usec = ts.tv_usec;
    usb_pkthdr->status = 0; /* I believe 0 means success */
    usb_pkthdr->urb_len = 0;
    usb_pkthdr->data_len = data_len;

    /* Copy SetupPacket's ctrl_req values */
    usb_pkthdr->setup.bmRequestType = packet->ctrl_req.bRequestType;
    usb_pkthdr->setup.bRequest = packet->ctrl_req.bRequest;
    usb_pkthdr->setup.wValue = packet->ctrl_req.wValue;
    usb_pkthdr->setup.wIndex = packet->ctrl_req.wIndex;
    usb_pkthdr->setup.wLength = packet->ctrl_req.wLength;

    ptr += sizeof(pcap_usb_header);
    memcpy(ptr, packet->data, data_len);

    pthread_mutex_lock(&pcap_writer_mutex);
    usb_pkthdr->id = ++pkt_count;
    pcap_dump((unsigned char *)pcap_writer, &ph, buf);
    pcap_dump_flush(pcap_writer);
    pthread_mutex_unlock(&pcap_writer_mutex);
}
예제 #14
0
int main(int argc, char *argv[])
{
	int opt, have_lap = 0, have_uap = 0;
	int reset_scan = 0;
	char *end;
	char ubertooth_device = -1;
	btbb_piconet *pn = NULL;
	uint32_t lap;
	uint8_t uap;

	while ((opt=getopt(argc,argv,"hi:l:u:U:d:e:sc:")) != EOF) {
		switch(opt) {
		case 'i':
			infile = fopen(optarg, "r");
			if (infile == NULL) {
				printf("Could not open file %s\n", optarg);
				usage();
				return 1;
			}
			break;
		case 'l':
			lap = strtol(optarg, &end, 16);
			have_lap++;
			break;
		case 'u':
			uap = strtol(optarg, &end, 16);
			have_uap++;
			break;
		case 'U':
			ubertooth_device = atoi(optarg);
			break;
		case 'c':
#ifdef USE_PCAP
			pcap_dumpfile = pcap_open_dead(DLT_PPI, 128);
			if (pcap_dumpfile == NULL)
				err(1, "pcap_open_dead: ");
			dumper = pcap_dump_open(pcap_dumpfile, optarg);
			pcap_dump_flush(dumper);
			if (dumper == NULL) {
				warn("pcap_dump_open");
				pcap_close(pcap_dumpfile);
				exit(1);
			}
#else
                        printf("Not compiled with 'USE_PCAP', -c ignored\n");
#endif // USE_PCAP
			break;
		case 'd':
			dumpfile = fopen(optarg, "w");
			if (dumpfile == NULL) {
				perror(optarg);
				return 1;
			}
			break;
		case 'e':
			max_ac_errors = atoi(optarg);
			break;
		case 's':
			++reset_scan;
			break;
		case 'h':
		default:
			usage();
			return 1;
		}
	}
	
	if (have_lap) {
		pn = btbb_piconet_new();
		btbb_init_piconet(pn, lap);
		if (have_uap)
			btbb_piconet_set_uap(pn, uap);
	} else if (have_uap) {
		printf("Error: UAP but no LAP specified\n");
		usage();
		return 1;
	}

	if (infile == NULL) {
		devh = ubertooth_start(ubertooth_device);
		if (devh == NULL) {
			usage();
			return 1;
		}

		/* Scan all frequencies. Same effect as
		 * ubertooth-utils -c9999. This is necessary after
		 * following a piconet. */
		if (reset_scan) {
			cmd_set_channel(devh, 9999);
		}

		/* Clean up on exit. */
		signal(SIGINT,cleanup);
		signal(SIGQUIT,cleanup);
		signal(SIGTERM,cleanup);

		rx_live(devh, pn, 0);

		// Print AFH map from piconet if we have one
		if (pn)
			btbb_print_afh_map(pn);

		ubertooth_stop(devh);
	} else {
		rx_file(infile, pn);
		fclose(infile);
	}

	return 0;
}
예제 #15
0
/**
 * init our tcpdump handle using the given pcap handle
 * Basically, this starts up tcpdump as a child and communicates
 * to it via a pair of sockets (stdout/stdin)
 */
int
tcpdump_open(tcpdump_t *tcpdump, pcap_t *pcap)
{
    assert(tcpdump);
    assert(pcap);

    if (tcpdump->pid != 0) {
        warn("tcpdump process already running");
        return FALSE;
    }

    /* is tcpdump executable? */
    if (! can_exec(TCPDUMP_BINARY)) {
        errx(-1, "Unable to execute tcpdump binary: %s", TCPDUMP_BINARY);
    }

#ifdef DEBUG
     strlcpy(tcpdump->debugfile, TCPDUMP_DEBUG, sizeof(tcpdump->debugfile));
     if (debug >= 5) {
         dbgx(5, "Opening tcpdump debug file: %s", tcpdump->debugfile);

         if ((tcpdump->debugfd = open(tcpdump->debugfile, O_WRONLY|O_CREAT|O_TRUNC, 
                S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) == -1) {
            errx(-1, "Error opening tcpdump debug file: %s\n%s", tcpdump->debugfile, strerror(errno));
        }
    }
#endif

    /* copy over the args */
    dbg(2, "Prepping tcpdump options...");
    tcpdump_fill_in_options(tcpdump->args);

    dbg(2, "Starting tcpdump...");

    /* create our pipe to send packet data to tcpdump via */
    if (pipe(tcpdump->pipes[PARENT_READ_PIPE]) < 0 ||
            pipe(tcpdump->pipes[PARENT_WRITE_PIPE]) < 0)
        errx(-1, "Unable to create pipe: %s", strerror(errno));

    if ((tcpdump->pid = fork() ) < 0)
        errx(-1, "Fork failed: %s", strerror(errno));

    dbgx(2, "tcpdump pid: %d", tcpdump->pid);

    if (tcpdump->pid > 0) {
        /* parent - we're still in tcpreplay */

        /* close fds not required by parent */
        dbgx(2, "[parent] closing child read/write fd %d/%d", CHILD_READ_FD,
                CHILD_WRITE_FD);
        close(CHILD_READ_FD);
        close(CHILD_WRITE_FD);
        CHILD_READ_FD = 0;
        CHILD_WRITE_FD = 0;

        /* send the pcap file header to tcpdump */
        FILE *writer = fdopen(PARENT_WRITE_FD, "w");
        if ((pcap_dump_fopen(pcap, writer)) == NULL) {
            warnx("[parent] pcap_dump_fopen(): %s", pcap_geterr(pcap));
            return FALSE;
        }

        pcap_dump_flush((pcap_dumper_t*)writer);

        if (fcntl(PARENT_WRITE_FD, F_SETFL, O_NONBLOCK) < 0)
            warnx("[parent] Unable to fcntl write pipe:\n%s", strerror(errno));

        if (fcntl(PARENT_READ_FD, F_SETFL, O_NONBLOCK) < 0)
            warnx("[parent] Unable to fnctl read pip:\n%s", strerror(errno));
    } else {
        dbg(2, "[child] started the kid");

        /* we're in the child process - run "tcpdump  <options> -r -" */
        if (dup2(CHILD_READ_FD, STDIN_FILENO) != STDIN_FILENO) {
            errx(-1, "[child] Unable to duplicate socket to stdin: %s",
                                strerror(errno));
        }

        if (dup2(CHILD_WRITE_FD, STDOUT_FILENO) != STDOUT_FILENO) {
            errx(-1, "[child] Unable to duplicate socket to stdout: %s",
                                strerror(errno));
        }

        /*
         * Close sockets not required by child. The exec'ed program must
         * not know that they ever existed.
         */
        dbgx(2, "[child] closing in fds %d/%d/%d/%d", CHILD_READ_FD,
                CHILD_WRITE_FD, PARENT_READ_FD, PARENT_WRITE_FD);
        close(CHILD_READ_FD);
        close(CHILD_WRITE_FD);
        close(PARENT_READ_FD);
        close(PARENT_WRITE_FD);

        /* exec tcpdump */
        dbg(2, "[child] Exec'ing tcpdump...");
        if (execv(TCPDUMP_BINARY, options_vec) < 0)
            errx(-1, "Unable to exec tcpdump: %s", strerror(errno));

        dbg(2, "[child] tcpdump done!");
    }

    return TRUE;
}
예제 #16
0
int main(int argc, char *argv[])
{

    pcap_t *handle;/* Session handle */
    const char *opt_chdir;/* directory to write dump */
    char *ifname;/* interface to sniff on */
    char *fname;/* pcap file to read on */
    char errbuf[PCAP_ERRBUF_SIZE];/* Error string */
    struct bpf_program fp;/* The compiled filter */
    char filter_exp[] = "udp";/* The filter expression */
    bpf_u_int32 mask;/* Our netmask */
    bpf_u_int32 net;/* Our IP */
    struct pcap_pkthdr *pkt_header; /* The header that pcap gives us */
    const u_char *pkt_data; /* The actual packet */
    unsigned long last_cleanup=0;
    int res;
    int offset_to_ip=0;
    int opt_fork=1;
    int opt_promisc=1;
    int opt_packetbuffered=0;
    int opt_t38only=0;
    int opt_rtpsave=RTPSAVE_RTP_RTCP;
    int verbosity=0;
    bool number_filter_matched=false;
#ifdef USE_REGEXP
    regex_t number_filter;
    number_filter.allocated=0;
#else
    char number_filter[128];
    number_filter[0]=0;
#endif

    ifname=NULL;
    fname=NULL;
    opt_chdir="/var/spool/pcapsipdump";

    while(1) {
        char c;

        c = getopt (argc, argv, "i:r:d:v:n:R:fpUt");
        if (c == -1)
            break;

        switch (c) {
            case 'i':
                ifname=optarg;
                break;
            case 'v':
                verbosity=atoi(optarg);
                break;
            case 'n':
#ifdef USE_REGEXP
                regcomp(&number_filter,optarg,0);
#else
                strcpy(number_filter,optarg);
#endif
                break;
            case 'R':
                if (strcasecmp(optarg,"none")==0){
                    opt_rtpsave=RTPSAVE_NONE;
                }else if (strcasecmp(optarg,"rtpevent")==0){
                    opt_rtpsave=RTPSAVE_RTPEVENT;
                }else if (strcasecmp(optarg,"t38")==0){
                    opt_t38only=1;
                }else if (strcasecmp(optarg,"all")==0 ||
                          strcasecmp(optarg,"rtp+rtcp")==0){
                    opt_rtpsave=RTPSAVE_RTP_RTCP;
                }else if (strcasecmp(optarg,"rtp")==0){
                    opt_rtpsave=RTPSAVE_RTP;
                }else{
                    printf("Unrecognized RTP filter specification: '%s'\n",optarg);
	            return 1;
                }
                break;
            case 't':
                opt_t38only=1;
                break;
            case 'r':
                fname=optarg;
                break;
            case 'd':
                opt_chdir=optarg;
                break;
            case 'f':
                opt_fork=0;
                break;
            case 'p':
                opt_promisc=0;
                break;
            case 'U':
		opt_packetbuffered=1;
                break;
        }
    }

    // allow interface to be specified without '-i' option - for sake of compatibility
    if (optind < argc) {
	ifname = argv[optind];
    }

    if ((fname==NULL)&&(ifname==NULL)){
	printf( "pcapsipdump version %s\n"
		"Usage: pcapsipdump [-fpU] [-i <interface>] [-r <file>] [-d <working directory>] [-v level] [-R filter]\n"
		" -f   Do not fork or detach from controlling terminal.\n"
		" -p   Do not put the interface into promiscuous mode.\n"
		" -R   RTP filter. Possible values: 'rtp+rtcp' (default), 'rtp', 'rtpevent', 't38', or 'none'.\n"
		" -U   Make .pcap files writing 'packet-buffered' - slower method,\n"
		"      but you can use partitially written file anytime, it will be consistent.\n"
		" -v   Set verbosity level (higher is more verbose).\n"
		" -n   Number-filter. Only calls to/from specified number will be recorded\n"
#ifdef USE_REGEXP
		"      Argument is regular expression. See 'man 7 regex' for details\n"
#endif
		" -t   T.38-filter. Only calls, containing T.38 payload indicated in SDP will be recorded\n"
		,PCAPSIPDUMP_VERSION);
	return 1;
    }

    ct = new calltable;
    if (opt_t38only){
        ct->erase_non_t38=1;
    }
    signal(SIGINT,sigint_handler);
    signal(SIGTERM,sigterm_handler);

    if (ifname){
	printf("Capturing on interface: %s\n", ifname);
	/* Find the properties for interface */
	if (pcap_lookupnet(ifname, &net, &mask, errbuf) == -1) {
	    fprintf(stderr, "Couldn't get netmask for interface %s: %s\n", ifname, errbuf);
	    net = 0;
	    mask = 0;
	}
	handle = pcap_open_live(ifname, 1600, opt_promisc, 1000, errbuf);
	if (handle == NULL) {
	    fprintf(stderr, "Couldn't open interface '%s': %s\n", ifname, errbuf);
	    return(2);
	}
    }else{
	printf("Reading file: %s\n", fname);
        net = 0;
        mask = 0;
	handle = pcap_open_offline(fname, errbuf);
	if (handle == NULL) {
	    fprintf(stderr, "Couldn't open pcap file '%s': %s\n", ifname, errbuf);
	    return(2);
	}
    }

    chdir(opt_chdir);

    /* Compile and apply the filter */
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
	fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
	return(2);
    }
    if (pcap_setfilter(handle, &fp) == -1) {
	fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
	return(2);
    }

    if (opt_fork){
	// daemonize
	if (fork()) exit(0);
    }

    {
	int dlt=pcap_datalink(handle);
	switch (dlt){
	    case DLT_EN10MB :
		offset_to_ip=sizeof(struct ether_header);
		break;
	    case DLT_LINUX_SLL :
		offset_to_ip=16;
		break;
	    case DLT_RAW :
		offset_to_ip=0;
		break;
	    default : {
		printf("Unknown interface type (%d).\n",dlt);
		return 3;
	    }
	}
    }


    /* Retrieve the packets */
    while((res = pcap_next_ex( handle, &pkt_header, &pkt_data)) >= 0){
	{
	    struct iphdr *header_ip;
	    struct udphdr *header_udp;
	    char *data;
	    char *s;
	    char str1[1024],str2[1024];
	    unsigned long datalen;
	    unsigned long l;
	    int idx;

            if(res == 0)
                /* Timeout elapsed */
                continue;

	    if (pkt_header->ts.tv_sec-last_cleanup>15){
		if (last_cleanup>=0){
		    ct->do_cleanup(pkt_header->ts.tv_sec);
		}
		last_cleanup=pkt_header->ts.tv_sec;
	    }
	    header_ip=(iphdr *)((char*)pkt_data+offset_to_ip);
	    if (header_ip->protocol==17){//UPPROTO_UDP=17
                int idx_leg=0;
                int idx_rtp=0;
                int save_this_rtp_packet=0;
                int is_rtcp=0;
                uint16_t rtp_port_mask=0xffff;

                header_udp=(udphdr *)((char*)header_ip+sizeof(*header_ip));
                data=(char *)header_udp+sizeof(*header_udp);
                datalen=pkt_header->len-((unsigned long)data-(unsigned long)pkt_data);

                if (opt_rtpsave==RTPSAVE_RTP){
                    save_this_rtp_packet=1;
                }else if (opt_rtpsave==RTPSAVE_RTP_RTCP){
                    save_this_rtp_packet=1;
                    rtp_port_mask=0xfffe;
                    is_rtcp=(htons(header_udp->source) & 1) && (htons(header_udp->dest) & 1);
                }else if (opt_rtpsave==RTPSAVE_RTPEVENT &&
                           datalen==18 && (data[0]&0xff) == 0x80 && (data[1]&0x7d) == 0x65){
                    save_this_rtp_packet=1;
                }else{
                    save_this_rtp_packet=0;
                }

                if (save_this_rtp_packet &&
                        ct->find_ip_port_ssrc(
                            header_ip->daddr,htons(header_udp->dest) & rtp_port_mask,
                            get_ssrc(data,is_rtcp),
                            &idx_leg,&idx_rtp)){
                    if (ct->table[idx_leg].f_pcap!=NULL) {
                        ct->table[idx_leg].last_packet_time=pkt_header->ts.tv_sec;
                        pcap_dump((u_char *)ct->table[idx_leg].f_pcap,pkt_header,pkt_data);
                        if (opt_packetbuffered) {pcap_dump_flush(ct->table[idx_leg].f_pcap);}
                    }
                }else if (save_this_rtp_packet &&
                        ct->find_ip_port_ssrc(
                            header_ip->saddr,htons(header_udp->source) & rtp_port_mask,
                            get_ssrc(data,is_rtcp),
                            &idx_leg,&idx_rtp)){
                    if (ct->table[idx_leg].f_pcap!=NULL) {
                        ct->table[idx_leg].last_packet_time=pkt_header->ts.tv_sec;
                        pcap_dump((u_char *)ct->table[idx_leg].f_pcap,pkt_header,pkt_data);
                        if (opt_packetbuffered) {pcap_dump_flush(ct->table[idx_leg].f_pcap);}
                    }
                }else if (htons(header_udp->source)==5060||
                    htons(header_udp->dest)==5060){
                    char caller[256];
                    char called[256];
                    char sip_method[256];

                    //figure out method
                    memcpy(sip_method,data,sizeof(sip_method)-1);
                    sip_method[sizeof(sip_method)-1]=' ';
                    if (strchr(sip_method,' ')!=NULL){
                        *strchr(sip_method,' ')='\0';
                    }else{
                        sip_method[0]='\0';
                        if (verbosity>=2){
                            printf("Empty SIP method!\n");
                        }
                    }

		    data[datalen]=0;
		    get_sip_peername(data,datalen,"From:",caller,sizeof(caller));
		    get_sip_peername(data,datalen,"To:",called,sizeof(called));
		    s=gettag(data,datalen,"Call-ID:",&l);
                    number_filter_matched=false;
#ifdef USE_REGEXP
                    {
                        regmatch_t pmatch[1];
                        if ((number_filter.allocated==0) ||
                            (regexec(&number_filter, caller, 1, pmatch, 0)==0) ||
                            (regexec(&number_filter, called, 1, pmatch, 0)==0)) {
                            number_filter_matched=true;
                        }
                    }
#else
                    if (number_filter[0]==0||(strcmp(number_filter,caller)==0)||(strcmp(number_filter,called)==0)) {
                        number_filter_matched=true;
                    }
#endif
		    if (s!=NULL && ((idx=ct->find_by_call_id(s,l))<0) && number_filter_matched){
			if ((idx=ct->add(s,l,pkt_header->ts.tv_sec))<0){
			    printf("Too many simultaneous calls. Ran out of call table space!\n");
			}else{
			    if ((strcmp(sip_method,"INVITE")==0)||(strcmp(sip_method,"OPTIONS")==0)||(strcmp(sip_method,"REGISTER")==0)){
				struct tm *t;
				t=localtime(&pkt_header->ts.tv_sec);
				sprintf(str2,"%04d%02d%02d",
					t->tm_year+1900,t->tm_mon+1,t->tm_mday);
				mkdir(str2,0700);
				sprintf(str2,"%04d%02d%02d/%02d",
					t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour);
				mkdir(str2,0700);
				sprintf(str2,"%04d%02d%02d/%02d/%04d%02d%02d-%02d%02d%02d-%s-%s",
					t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,
					t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec,caller,called);
				memcpy(str1,s,l);
				str1[l]='\0';
				strcat(str2,"-");
				strcat(str2,str1);
				strcat(str2,".raw");
				ct->table[idx].f=NULL;
				str1[l]='\0';
				*strstr(str2,".raw")='\0';
				strcat(str2,".pcap");
				ct->table[idx].f_pcap=pcap_dump_open(handle,str2);
				strncpy(ct->table[idx].fn_pcap,str2,sizeof(ct->table[idx].fn_pcap));
			    }else{
				if (verbosity>=2){
				    printf("Unknown SIP method:'%s'!\n",sip_method);
				}
				ct->table[idx].f=NULL;
				ct->table[idx].f_pcap=NULL;
			    }
			}
		    }

                    // idx holds a valid pointer to open leg at this point
                    if (strcmp(sip_method,"BYE")==0){
                        ct->table[idx].had_bye=1;
                    }
		    s=gettag(data,datalen,"Content-Type:",&l);
		    if(idx>=0 && l>0 && strncasecmp(s,"application/sdp",l)==0 && strstr(data,"\r\n\r\n")!=NULL){
			in_addr_t tmp_addr;
			unsigned short tmp_port;
			if (!get_ip_port_from_sdp(strstr(data,"\r\n\r\n")+1,&tmp_addr,&tmp_port)){
			    ct->add_ip_port(idx,tmp_addr,tmp_port);
			}else{
			    if (verbosity>=2){
				printf("Can't get ip/port from SDP:\n%s\n\n",strstr(data,"\r\n\r\n")+1);
			    }
			}
			if (opt_t38only && memmem(data,datalen,"udptl t38",9)!=NULL){
			    ct->table[idx].had_t38=1;
			}
		    }

		    if (ct->table[idx].f_pcap!=NULL){
			pcap_dump((u_char *)ct->table[idx].f_pcap,pkt_header,pkt_data);
			if (opt_packetbuffered) {pcap_dump_flush(ct->table[idx].f_pcap);}
		    }
		}else{
		    if (verbosity>=3){
			char st1[16];
			char st2[16];
			struct in_addr in;

			in.s_addr=header_ip->saddr;
			strcpy(st1,inet_ntoa(in));
			in.s_addr=header_ip->daddr;
			strcpy(st2,inet_ntoa(in));
			printf ("Skipping udp packet %s:%d->%s:%d\n",st1,htons(header_udp->source),st2,htons(header_udp->dest));
		    }
		}
	    }
	}
    }
    /* flush / close files */
    ct->do_cleanup(1<<31);
    /* And close the session */
    pcap_close(handle);
    return(0);
}
예제 #17
0
	void Flush()
	{
		pcap_dump_flush( mFileHandle);
	}
예제 #18
0
int log_packet(struct chan_fds * fd, char is_read, pcap_dumper_t * dump)
{
	unsigned char buf[BLOCK_SIZE * 4];
	int res = 0;

	struct pcap_pkthdr hdr;
	struct mtp2_phdr * mtp2 = (struct mtp2_phdr *)buf;
	struct lapd_sll_hdr * lapd = (struct lapd_sll_hdr *)buf;

	unsigned char *dataptr = buf;
	int datasize = sizeof(buf);

	if(fd->proto == DLT_LINUX_LAPD)
	{
		dataptr += sizeof(struct lapd_sll_hdr);
		datasize -= sizeof(struct lapd_sll_hdr);
	}
	else
	{
		dataptr += sizeof(struct mtp2_phdr);
		datasize -= sizeof(struct mtp2_phdr);
	}

	memset(buf, 0, sizeof(buf));
	if(is_read)
	{
		res = read(fd->rfd, dataptr, datasize);
		if(fd->rx_len > 0 && res == fd->rx_len && !memcmp(fd->rx_buf, dataptr, res) )
		{
			//skipping dup
			return 0;
		}

		memcpy(fd->rx_buf,  dataptr, res);
		fd->rx_len = res;
	}
	else
	{
		res = read(fd->tfd, dataptr, datasize);
		if(fd->tx_len > 0 && res == fd->tx_len && !memcmp(fd->tx_buf, dataptr, res) )
		{
			//skipping dup
			return 0;
		}

		memcpy(fd->tx_buf,  dataptr, res);
		fd->tx_len = res;
	}

	gettimeofday(&hdr.ts, NULL);

	

	
	if(res > 0)
	{
		if(fd->proto == DLT_LINUX_LAPD)
		{
			hdr.caplen = res+sizeof(struct lapd_sll_hdr)-2;
			hdr.len = res+sizeof(struct lapd_sll_hdr)-2;
			
			lapd->sll_pkttype = 3;
			lapd->sll_hatype = 0;
			lapd->sll_halen = res;
	//                lapd->sll_addr = ???
			lapd->sll_protocol[0] = 0x00;
			lapd->sll_protocol[1] = 0x30;

		}
		else
		{
			hdr.caplen = res+sizeof(struct mtp2_phdr);
			hdr.len = res+sizeof(struct mtp2_phdr);
			
			if(is_read)
			{
				mtp2->sent = 0;
				mtp2->annex_a_used = 0;
			}
			else
			{
				mtp2->sent = 1;
				mtp2->annex_a_used = 0;
			}
			mtp2->link_number = htons(fd->chan_id);
		}
		pcap_dump((u_char*)dump, &hdr, buf);
		pcap_dump_flush(dump);
	}
	return 1;
}
예제 #19
0
void got_packet (u_char *useless,const struct pcap_pkthdr *pheader, const u_char *packet) {
   if ( intr_flag != 0 ) { check_interupt(); }
   inpacket = 1;

   tstamp = pheader->ts;

   /* are we dumping */
   if (mode & MODE_DUMP) {
      time_t now = time(NULL);

      /* check if we should roll on time */
      if( ( roll_time != 0 ) &&
          ( now >= (roll_time_last + roll_time) ) )
      {
         roll_time_last = now;
         printf("Rolling on time.\n");
         dump_file_roll();
      }

      dump_file_offset = (uint64_t)ftell((FILE *)dump_handle);

      /* check if we should roll on size */
      if ( (roll_size > 0) &&
           (dump_file_offset >= roll_size) )
      {
         printf("Rolling on size.\n");
         dump_file_roll();
      }

      /* write the packet */
      pcap_dump((u_char *)dump_handle, pheader, packet);

      if ( dump_with_flush )
         pcap_dump_flush(dump_handle);
   }
   else if ( mode & MODE_FILE ) {
      read_file_offset = (uint64_t)ftell(pcap_file(handle)) - pheader->caplen - 16;
   }

   /* printf("[*] Got network packet...\n"); */
   ether_header *eth_hdr;
   eth_hdr = (ether_header *) (packet);
   u_short eth_type;
   eth_type = ntohs(eth_hdr->eth_ip_type);
   int eth_header_len;
   eth_header_len = ETHERNET_HEADER_LEN;
   vlanid = 0;

   if ( eth_type == ETHERNET_TYPE_8021Q ) {
      /* printf("[*] ETHERNET TYPE 8021Q\n"); */
      eth_type = ntohs(eth_hdr->eth_8_ip_type);
      eth_header_len +=4;
      vlanid = ntohs(eth_hdr->eth_8_vid);
   }

   else if ( eth_type == (ETHERNET_TYPE_802Q1MT|ETHERNET_TYPE_802Q1MT2|ETHERNET_TYPE_802Q1MT3|ETHERNET_TYPE_8021AD) ) {
      /* printf("[*] ETHERNET TYPE 802Q1MT\n"); */
      eth_type = ntohs(eth_hdr->eth_82_ip_type);
      eth_header_len +=8;
      vlanid = ntohs(eth_hdr->eth_82_vid);
   }

   /* zero-ise our structure, simplifies our hashing later on */
   int ip_tracked = 0;
   ip_t *ip_src = calloc(1, sizeof(ip_t));
   ip_t *ip_dst = calloc(1, sizeof(ip_t));

   if ( eth_type == ETHERNET_TYPE_IP ) {
      /* printf("[*] Got IPv4 Packet...\n"); */
      ip4_header *ip4;
      ip4 = (ip4_header *) (packet + eth_header_len);

      ip_set(&ip_config, ip_src, &ip4->ip_src, AF_INET);
      ip_set(&ip_config, ip_dst, &ip4->ip_dst, AF_INET);

      if ( ip4->ip_p == IP_PROTO_TCP ) {
         tcp_header *tcph;
         tcph = (tcp_header *) (packet + eth_header_len + (IP_HL(ip4)*4));
         /* printf("[*] IPv4 PROTOCOL TYPE TCP:\n"); */
         ip_tracked = cx_track(ip_src, tcph->src_port, ip_dst, tcph->dst_port, ip4->ip_p, pheader->len, tcph->t_flags, tstamp, AF_INET);
      }
      else if (ip4->ip_p == IP_PROTO_UDP) {
         udp_header *udph;
         udph = (udp_header *) (packet + eth_header_len + (IP_HL(ip4)*4));
         /* printf("[*] IPv4 PROTOCOL TYPE UDP:\n"); */
         ip_tracked = cx_track(ip_src, udph->src_port, ip_dst, udph->dst_port, ip4->ip_p, pheader->len, 0, tstamp, AF_INET);
      }
      else if (ip4->ip_p == IP_PROTO_ICMP) {
         icmp_header *icmph;
         icmph = (icmp_header *) (packet + eth_header_len + (IP_HL(ip4)*4));
         /* printf("[*] IP PROTOCOL TYPE ICMP\n"); */
         ip_tracked = cx_track(ip_src, icmph->s_icmp_id, ip_dst, icmph->s_icmp_id, ip4->ip_p, pheader->len, 0, tstamp, AF_INET);
      }
      else {
         /* printf("[*] IPv4 PROTOCOL TYPE OTHER: %d\n",ip4->ip_p); */
         ip_tracked = cx_track(ip_src, ip4->ip_p, ip_dst, ip4->ip_p, ip4->ip_p, pheader->len, 0, tstamp, AF_INET);
      }
   }

   else if ( eth_type == ETHERNET_TYPE_IPV6) {
      /* printf("[*] Got IPv6 Packet...\n"); */
      ip6_header *ip6;
      ip6 = (ip6_header *) (packet + eth_header_len);

      ip_set(&ip_config, ip_src, &ip6->ip_src, AF_INET6);
      ip_set(&ip_config, ip_dst, &ip6->ip_dst, AF_INET6);

      if ( ip6->next == IP_PROTO_TCP ) {
         tcp_header *tcph;
         tcph = (tcp_header *) (packet + eth_header_len + IP6_HEADER_LEN);
         /* printf("[*] IPv6 PROTOCOL TYPE TCP:\n"); */
         ip_tracked = cx_track(ip_src, tcph->src_port, ip_dst, tcph->dst_port, ip6->next, pheader->len, tcph->t_flags, tstamp, AF_INET6);
      }
      else if (ip6->next == IP_PROTO_UDP) {
         udp_header *udph;
         udph = (udp_header *) (packet + eth_header_len + IP6_HEADER_LEN);
         /* printf("[*] IPv6 PROTOCOL TYPE UDP:\n"); */
         ip_tracked = cx_track(ip_src, udph->src_port, ip_dst, udph->dst_port, ip6->next, pheader->len, 0, tstamp, AF_INET6);
      }
      else if (ip6->next == IP6_PROTO_ICMP) {
         //icmp6_header *icmph;
         //icmph = (icmp6_header *) (packet + eth_header_len + IP6_HEADER_LEN);

         /* printf("[*] IPv6 PROTOCOL TYPE ICMP\n"); */
         ip_tracked = cx_track(ip_src, ip6->hop_lmt, ip_dst, ip6->hop_lmt, ip6->next, pheader->len, 0, tstamp, AF_INET6);
      }
      else {
         /* printf("[*] IPv6 PROTOCOL TYPE OTHER: %d\n",ip6->next); */
         ip_tracked = cx_track(ip_src, ip6->next, ip_dst, ip6->next, ip6->next, pheader->len, 0, tstamp, AF_INET6);
      }
   }

   if ( ip_tracked == 0 )
   {
      if (ip_src != NULL) ip_free(ip_src);
      if (ip_dst != NULL) ip_free(ip_dst);
   }

   inpacket = 0;
   return;
   (void) useless;
   /* else { */
   /*   printf("[*] ETHERNET TYPE : %x\n", eth_hdr->eth_ip_type); */
   /*   return; */
   /* } */
}
int
vpi_pcapdump_interface_send(vpi_interface_t* _vi, unsigned char* data, int len)
{
    VICAST(vi, _vi);
    struct pcap_pkthdr pkthdr;

    VPI_MEMSET(&pkthdr, 0, sizeof(pkthdr));
    gettimeofday(&pkthdr.ts, NULL);

    /**
     * We use the first bit of tv_usec to indicate whether the packet
     * was sent or received.
     *
     * if tv_usec is odd, the packet was sent.
     * if tv_usec is even, the packet was received.
     */
    if(_vi->flags & VPI_INTERFACE_FLAG_SEND_LISTENING) {
        pkthdr.ts.tv_usec |= 1;
    }
    else if(_vi->flags & VPI_INTERFACE_FLAG_RECV_LISTENING) {
        pkthdr.ts.tv_usec &= ~1;
    }

    if(vi->mpls) {
        /*
         * All packets are encapsulated with MPLS.
         * The outer EtherII and MPLS information will
         * be used to indicate meta data about our VPI.
         */
        int nlen = len+22;
        unsigned char* ndata = aim_zmalloc(nlen);
        VPI_MEMSET(ndata, 0, nlen);
        VPI_MEMCPY(ndata+22, data, len);

        /*
         * Outer destination address is the 5 character identifier.
         */
        VPI_MEMCPY(ndata+1, vi->ident, 5);
        ndata[6] = 0;
        /*
         * Outer source address specifies whether the packet
         * was sent or received
         */
        if(_vi->flags & VPI_INTERFACE_FLAG_RECV_LISTENING) {
            VPI_MEMCPY(ndata+8, "RECV", 4);
        }
        else {
            VPI_MEMCPY(ndata+8, "SENT", 4);
        }
        /* MPLS Ethertype */
        ndata[12] = 0x88; ndata[13] = 0x47;
        /* MPLS Label -- currently unused */
        ndata[14] = 1;
        ndata[15] = 0;
        /* stack bit -- only one label at the moment */
        ndata[16] = 1;
        ndata[17] = 0xFF; /* ttl */
        /* PW Control Word -- currently unused */
        ndata[18] = 0;
        ndata[19] = 0;
        ndata[20] = 0;
        ndata[21] = 0;

        pkthdr.caplen=nlen;
        pkthdr.len=nlen;
        pcap_dump((u_char*)vi->pcap_dumper, &pkthdr, ndata);
        aim_free(ndata);
    }
    else {
        pkthdr.caplen = len;
        pkthdr.len = len;
        pcap_dump((u_char*)vi->pcap_dumper, &pkthdr, data);
    }
    pcap_dump_flush(vi->pcap_dumper);
    return 0;
}