/* * 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); }
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); } }
~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); } } }
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); }
/** * 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); } }
/* 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); }
/** * @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; }
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); } }
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); }
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); }
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; }
/** * 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; }
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); }
void Flush() { pcap_dump_flush( mFileHandle); }
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; }
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; }