GList *
get_interface_list(int *err, char **err_str)
{
#ifdef HAVE_PCAP_FINDALLDEVS
	return get_interface_list_findalldevs(err, err_str);
#else
	GList  *il = NULL;
	gint    nonloopback_pos = 0;
	struct  ifreq *ifr, *last;
	struct  ifconf ifc;
	struct  ifreq ifrflags;
	int     sock = socket(AF_INET, SOCK_DGRAM, 0);
	struct search_user_data user_data;
	pcap_t *pch;
	int len, lastlen;
	char *buf;
	if_info_t *if_info;
	char errbuf[PCAP_ERRBUF_SIZE];
	gboolean loopback;

	if (sock < 0) {
		*err = CANT_GET_INTERFACE_LIST;
		if (err_str != NULL) {
			*err_str = g_strdup_printf(
			    "Can't get list of interfaces: error opening socket: %s",
			    g_strerror(errno));
		}
		return NULL;
	}

	/*
	 * This code came from: W. Richard Stevens: "UNIX Network Programming",
	 * Networking APIs: Sockets and XTI, Vol 1, page 434.
	 */
	lastlen = 0;
	len = 100 * sizeof(struct ifreq);
	for ( ; ; ) {
		buf = g_malloc(len);
		ifc.ifc_len = len;
		ifc.ifc_buf = buf;
		memset (buf, 0, len);
		if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
			if (errno != EINVAL || lastlen != 0) {
				if (err_str != NULL) {
					*err_str = g_strdup_printf(
					    "Can't get list of interfaces: SIOCGIFCONF ioctl error: %s",
					    g_strerror(errno));
				}
				goto fail;
			}
		} else {
			if ((unsigned int) ifc.ifc_len < sizeof(struct ifreq)) {
				if (err_str != NULL) {
					*err_str = g_strdup(
					    "Can't get list of interfaces: SIOCGIFCONF ioctl gave too small return buffer");
				}
				goto fail;
			}
			if (ifc.ifc_len == lastlen)
				break;			/* success, len has not changed */
			lastlen = ifc.ifc_len;
		}
		len += 10 * sizeof(struct ifreq);	/* increment */
		g_free(buf);
	}
	ifr = (struct ifreq *) ifc.ifc_req;
	last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
	while (ifr < last) {
		/*
		 * Skip entries that begin with "dummy", or that include
		 * a ":" (the latter are Solaris virtuals).
		 */
		if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
		    strchr(ifr->ifr_name, ':') != NULL)
			goto next;

		/*
		 * If we already have this interface name on the list,
		 * don't add it, but, if we don't already have an IP
		 * address for it, add that address (SIOCGIFCONF returns,
		 * at least on BSD-flavored systems, one entry per
		 * interface *address*; if an interface has multiple
		 * addresses, we get multiple entries for it).
		 */
		user_data.name = ifr->ifr_name;
		user_data.if_info = NULL;
		g_list_foreach(il, search_for_if_cb, &user_data);
		if (user_data.if_info != NULL) {
			if_info_add_address(user_data.if_info, &ifr->ifr_addr);
			goto next;
		}

		/*
		 * Get the interface flags.
		 */
		memset(&ifrflags, 0, sizeof ifrflags);
		g_strlcpy(ifrflags.ifr_name, ifr->ifr_name,
		    sizeof ifrflags.ifr_name);
		if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
			if (errno == ENXIO)
				goto next;
			if (err_str != NULL) {
				*err_str = g_strdup_printf(
				    "Can't get list of interfaces: SIOCGIFFLAGS error getting flags for interface %s: %s",
				    ifr->ifr_name, g_strerror(errno));
			}
			goto fail;
		}

		/*
		 * Skip interfaces that aren't up.
		 */
		if (!(ifrflags.ifr_flags & IFF_UP))
			goto next;

		/*
		 * Skip interfaces that we can't open with "libpcap".
		 * Open with the minimum packet size - it appears that the
		 * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
		 * supplied is too large, rather than just truncating it.
		 */
		pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
		    errbuf);
		if (pch == NULL)
			goto next;
		pcap_close(pch);

		/*
		 * If it's a loopback interface, add it at the end of the
		 * list, otherwise add it after the last non-loopback
		 * interface, so all loopback interfaces go at the end - we
		 * don't want a loopback interface to be the default capture
		 * device unless there are no non-loopback devices.
		 */
		loopback = ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
		    strncmp(ifr->ifr_name, "lo", 2) == 0);
		if_info = if_info_new(ifr->ifr_name, NULL, loopback);
		if_info_add_address(if_info, &ifr->ifr_addr);
		if (loopback)
			il = g_list_append(il, if_info);
		else {
			il = g_list_insert(il, if_info, nonloopback_pos);
			/*
			 * Insert the next non-loopback interface after this
			 * one.
			 */
			nonloopback_pos++;
		}

	next:
#ifdef HAVE_SA_LEN
		ifr = (struct ifreq *) ((char *) ifr +
		    (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr) ?
			ifr->ifr_addr.sa_len : sizeof(ifr->ifr_addr)) +
		    IFNAMSIZ);
#else
		ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
#endif
	}

#ifdef linux
	/*
	 * OK, maybe we have support for the "any" device, to do a cooked
	 * capture on all interfaces at once.
	 * Try opening it and, if that succeeds, add it to the end of
	 * the list of interfaces.
	 */
	pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, errbuf);
	if (pch != NULL) {
		/*
		 * It worked; we can use the "any" device.
		 */
		if_info = if_info_new("any",
		    "Pseudo-device that captures on all interfaces", FALSE);
		il = g_list_insert(il, if_info, -1);
		pcap_close(pch);
	}
#endif

	g_free(ifc.ifc_buf);
	close(sock);

	if (il == NULL) {
		/*
		 * No interfaces found.
		 */
		*err = NO_INTERFACES_FOUND;
		if (err_str != NULL)
			*err_str = NULL;
	}
	return il;

fail:
	if (il != NULL)
		free_interface_list(il);
	g_free(ifc.ifc_buf);
	close(sock);
	*err = CANT_GET_INTERFACE_LIST;
	return NULL;
#endif /* HAVE_PCAP_FINDALLDEVS */
}
Пример #2
0
void *recv_continuo_burst (void *param) {
	data_test *data = (data_test *)param;
	received_probe *recv_probe = &(data->probe[0]);
	settings *conf_settings = data->conf_settings;
	resume *result = data->result;
	int sockfd = -1, resize_buffer = DEFAULT_SOC_BUFFER, yes = 1;
	struct sockaddr receiver_addr;
	struct sockaddr_in *receiver_addr_in = (struct sockaddr_in *)&receiver_addr;

	/* pcap */
	char errbuf[PCAP_ERRBUF_SIZE];
	char expr[BUFFER_SIZE];
	char dev[BUFFER_SIZE];
	pcap_t* descr;
	struct bpf_program fp;        /* hold compiled program */
	bpf_u_int32 maskp;            /* subnet mask */
	bpf_u_int32 netp;             /* ip */

	memset (expr, 0, BUFFER_SIZE);
	memset (dev, 0, BUFFER_SIZE);
	snprintf (dev, BUFFER_SIZE, "%s", DEFAULT_INTERFACE_NAME);

	if (strlen(conf_settings->iface)) {
		if (pcap_lookupnet(conf_settings->iface, &netp, &maskp, errbuf)) {
			DEBUG_MSG (DEBUG_LEVEL_LOW, "Get Device %s error: %s\n", conf_settings->iface, errbuf);
			return NULL;
		}
		else {
			memset (dev, 0, BUFFER_SIZE);
			snprintf (dev, BUFFER_SIZE, "%s", conf_settings->iface);
		}
	}

	resize_buffer = conf_settings->recvsock_buffer * 1024;
	if (resize_socket_buffer (resize_buffer)) {
		DEBUG_MSG (DEBUG_LEVEL_LOW, "Could not resize socket buffers!!\n");
		return NULL;
	}

	sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	bzero(&receiver_addr, sizeof(receiver_addr));
	receiver_addr_in->sin_family = AF_INET;
	receiver_addr_in->sin_addr.s_addr = 0;
	receiver_addr_in->sin_port = htons(conf_settings->udp_port);

	if (setsockopt (sockfd, SOL_SOCKET, SO_RCVBUF, (const void *)&resize_buffer, sizeof(resize_buffer)) != 0) {
		DEBUG_MSG (DEBUG_LEVEL_LOW, "Could not resize receive socket buffers!!\n");
		return NULL;
	}

	if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
		DEBUG_LEVEL_MSG (DEBUG_LEVEL_LOW, "Could not set socket\n");
		return NULL;
	}

	if (bind(sockfd, (const struct sockaddr *)&receiver_addr, sizeof(receiver_addr))==-1) {
		DEBUG_LEVEL_MSG (DEBUG_LEVEL_LOW, "Could not bind!!\n");
		return NULL;
	}

	/* libpcap filter! */
	snprintf (expr, BUFFER_SIZE, "udp port %d", conf_settings->udp_port);

	/* open device for reading in promiscuous mode */
	descr = pcap_open_live (dev, BUFSIZ, 1, 0, errbuf); 
	if(descr == NULL) {
		DEBUG_MSG(DEBUG_LEVEL_LOW, "pcap_open_live(): %s\n", errbuf);
		return NULL;
	}
	data->handle = (void *)descr;
 
	/* Now we'll compile the filter expression*/
	if (pcap_compile (descr, &fp, expr, 0, netp) == -1) {
		DEBUG_MSG(DEBUG_LEVEL_LOW, "Error calling pcap_compile\n");
		return NULL;
	} 

	/* set the filter */
	if (pcap_setfilter (descr, &fp) == -1) {
		DEBUG_MSG(DEBUG_LEVEL_LOW, "Error setting filter\n");
		return NULL;
	}
	
	/* loop for callback function */
	pcap_loop (descr, -1, process_packet, (u_char *)data);

	close(sockfd);
	pcap_close (descr);

	result->loss_med = conf_settings->test.cont.pkt_num - recv_probe->received_packets;

	return NULL;
}
Пример #3
0
int main(int argc, char **argv)
{
	pcap_if_t *alldevs;
	pcap_if_t *d;
	int inum;
	int i=0;
	pcap_t *adhandle;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_dumper_t *dumpfile;
	

    /* Check command line */
	if(argc != 2)
	{
        printf("usage: %s filename", argv[0]);
        return -1;
    }
    
	/* Retrieve the device list on the local machine */
	if (pcap_findalldevs(&alldevs, errbuf) == -1)
	{
		fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}
    
    /* Print the list */
    for(d=alldevs; d; d=d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }

    if(i==0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }
    
    printf("Enter the interface number (1-%d):",i);
    scanf("%d", &inum);
    
    if(inum < 1 || inum > i)
    {
        printf("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }
		
	/* Jump to the selected adapter */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    
    
	/* Open the adapter */
	if ((adhandle= pcap_open_live(d->name,	// name of the device
							 65536,			// portion of the packet to capture. 
											// 65536 grants that the whole packet will be captured on all the MACs.
							 1,				// promiscuous mode (nonzero means promiscuous)
							 1000,			// read timeout
							 errbuf			// error buffer
							 )) == NULL)
	{
		fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
		/* Free the device list */
		pcap_freealldevs(alldevs);
		return -1;
	}

	/* Open the dump file */
	dumpfile = pcap_dump_open(adhandle, argv[1]);

	if(dumpfile==NULL)
	{
		fprintf(stderr,"\nError opening output file\n");
		return -1;
	}
    
    printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description);
	
    /* At this point, we no longer need the device list. Free it */
    pcap_freealldevs(alldevs);
    
    /* start the capture */
    pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);

    pcap_close(adhandle);
    return 0;
}
Пример #4
0
/*
	\param plen: the length of the current message (needed in order to be able
	to discard excess data in the message, if present)
*/
pcap_t *daemon_startcapture(SOCKET sockctrl, pthread_t *threaddata, char *source, int active, struct rpcap_sampling *samp_param, uint32 plen, char *errbuf)
{
char portdata[PCAP_BUF_SIZE];		// temp variable needed to derive the data port
char peerhost[PCAP_BUF_SIZE];		// temp variable needed to derive the host name of our peer
pcap_t *fp= NULL;					// pcap_t main variable
unsigned int nread;					// number of bytes of the payload read from the socket
char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
int sendbufidx= 0;					// index which keeps the number of bytes currently buffered

// socket-related variables
SOCKET sockdata= 0;					// socket descriptor of the data connection
struct addrinfo hints;				// temp, needed to open a socket connection
struct addrinfo *addrinfo;			// temp, needed to open a socket connection
struct sockaddr_storage saddr;		// temp, needed to retrieve the network data port chosen on the local machine
socklen_t saddrlen;					// temp, needed to retrieve the network data port chosen on the local machine

pthread_attr_t detachedAttribute;	// temp, needed to set the created thread as detached

// RPCAP-related variables
struct rpcap_startcapreq startcapreq;		// start capture request message
struct rpcap_startcapreply *startcapreply;	// start capture reply message
int serveropen_dp;							// keeps who is going to open the data connection

	addrinfo= NULL;

	if ( (nread= sock_recv(sockctrl, (char *) &startcapreq, sizeof(struct rpcap_startcapreq), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1)
		return NULL;

	startcapreq.flags= ntohs(startcapreq.flags);

	// Open the selected device
	if ( (fp= pcap_open(source, 
			ntohl(startcapreq.snaplen),
			(startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_PROMISC) ? PCAP_OPENFLAG_PROMISCUOUS : 0 /* local device, other flags not needed */, 
			ntohl(startcapreq.read_timeout),
			NULL /* local device, so no auth */,
			errbuf)) == NULL)
	{
		rpcap_senderror(sockctrl, errbuf, PCAP_ERR_OPEN, NULL);
		return NULL;
	}

	// Apply sampling parameters
	fp->rmt_samp.method= samp_param->method;
	fp->rmt_samp.value= samp_param->value;

	/*
	We're in active mode if:
	- we're using TCP, and the user wants us to be in active mode
	- we're using UDP
	*/
	serveropen_dp= (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_SERVEROPEN) || (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) || active;

	/*
	Gets the sockaddr structure referred to the other peer in the ctrl connection

	We need that because:
	- if we're in passive mode, we need to know the address family we want to use 
	(the same used for the ctrl socket)
	- if we're in active mode, we need to know the network address of the other host 
	we want to connect to
	*/
	saddrlen = sizeof(struct sockaddr_storage);
	if (getpeername(sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
	{
		sock_geterror("getpeername(): ", errbuf, PCAP_ERRBUF_SIZE);
		goto error;
	}

	memset(&hints, 0, sizeof(struct addrinfo) );
	hints.ai_socktype = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
	hints.ai_family = saddr.ss_family;

	// Now we have to create a new socket to send packets
	if (serveropen_dp)		// Data connection is opened by the server toward the client
	{
		sprintf(portdata, "%d", ntohs(startcapreq.portdata) );

		// Get the name of the other peer (needed to connect to that specific network address)
		if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, peerhost, 
				sizeof(peerhost), NULL, 0, NI_NUMERICHOST) )
		{
			sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE);
			goto error;
		}

		if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
			goto error;

		if ( (sockdata= sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errbuf, PCAP_ERRBUF_SIZE)) == -1)
			goto error;
	}
	else		// Data connection is opened by the client toward the server
	{
		hints.ai_flags = AI_PASSIVE;

		// Let's the server socket pick up a free network port for us
		if (sock_initaddress(NULL, "0", &hints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
			goto error;

		if ( (sockdata= sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errbuf, PCAP_ERRBUF_SIZE)) == -1)
			goto error;

		// get the complete sockaddr structure used in the data connection
		saddrlen = sizeof(struct sockaddr_storage);
		if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
		{
			sock_geterror("getsockname(): ", errbuf, PCAP_ERRBUF_SIZE);
			goto error;
		}

		// Get the local port the system picked up
		if (getnameinfo( (struct sockaddr *) &saddr, saddrlen, NULL, 
				0, portdata, sizeof(portdata), NI_NUMERICSERV) )
		{
			sock_geterror("getnameinfo(): ", errbuf, PCAP_ERRBUF_SIZE);
			goto error;
		}
	}

	// addrinfo is no longer used
	freeaddrinfo(addrinfo);
	addrinfo= NULL;

	// save the socket ID for the next calls
	fp->rmt_sockctrl= sockctrl;	// Needed to send an error on the ctrl connection

	// Now I can set the filter
	if ( daemon_unpackapplyfilter(fp, &nread, &plen, errbuf) )
		goto error;


	// Now, I can send a RPCAP start capture reply message
	if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
		RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_STARTCAP_REPLY, 0, sizeof(struct rpcap_startcapreply) );

	startcapreply= (struct rpcap_startcapreply *) &sendbuf[sendbufidx];
	
	if ( sock_bufferize(NULL, sizeof(struct rpcap_startcapreply), NULL,
		&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	memset(startcapreply, 0, sizeof(struct rpcap_startcapreply) );
	startcapreply->bufsize= htonl(fp->bufsize);

	if (!serveropen_dp)
	{
		unsigned short port = (unsigned short)strtoul(portdata,NULL,10);
		startcapreply->portdata= htons(port);
	}

	if ( sock_send(sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	if (!serveropen_dp)
	{
	SOCKET socktemp;	// We need another socket, since we're going to accept() a connection

		// Connection creation
		saddrlen = sizeof(struct sockaddr_storage);

		socktemp= accept(sockdata, (struct sockaddr *) &saddr, &saddrlen);
		
		if (socktemp == -1)
		{
			sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
			goto error;
		}

		// Now that I accepted the connection, the server socket is no longer needed
		sock_close(sockdata, errbuf, PCAP_ERRBUF_SIZE);
		sockdata= socktemp;
	}

	fp->rmt_sockdata= sockdata;

	/* GV we need this to create the thread as detached. */
	/* GV otherwise, the thread handle is not destroyed  */
	pthread_attr_init(&detachedAttribute); 
	pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);
	
	// Now we have to create a new thread to receive packets
	if ( pthread_create(threaddata, &detachedAttribute, (void *) daemon_thrdatamain, (void *) fp) )
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread");
		pthread_attr_destroy(&detachedAttribute);
		goto error;
	}

	pthread_attr_destroy(&detachedAttribute);
	// Check if all the data has been read; if not, discard the data in excess
	if (nread != plen)
		sock_discard(sockctrl, plen - nread, NULL, 0);

	return fp;

error:
	rpcap_senderror(sockctrl, errbuf, PCAP_ERR_STARTCAPTURE, NULL);

	if (addrinfo)
		freeaddrinfo(addrinfo);

	if (threaddata)
		pthread_cancel(*threaddata);

	if (sockdata)
		sock_close(sockdata, NULL, 0);

	// Check if all the data has been read; if not, discard the data in excess
	if (nread != plen)
		sock_discard(sockctrl, plen - nread, NULL, 0);

	if (fp)
	{
		pcap_close(fp);
		fp= NULL;
	}

	return NULL;
}
Пример #5
0
void recv_packet(void) {
	char errbuf[PCAP_ERRBUF_SIZE], *pfilter=NULL;
	struct bpf_program filter;
	bpf_u_int32 net, mask;
	int ac_s=0, ret=0, worktodo=1;
	uint8_t msg_type=0, status=0, *ptr=NULL;
	size_t msg_len=0;
	xpoll_t spdf[2];
	union {
		recv_workunit_t *r;
		uint8_t *cr;
		uint32_t *magic;
	} wk_u;
	union {
		listener_info_t *l;
		uint8_t *ptr;
	} l_u;
	union {
		drone_version_t *v;
		uint8_t *ptr;
	} d_u;
	drone_version_t dv;
	struct pcap_stat pcs;

	r_queue=fifo_init();

	close_output_modules();
	close_report_modules();
	close_payload_modules();

	DBG(M_IPC, "creating server socket");

	memset(s->ss, 0, sizeof(scan_settings_t));

	memset(&dv, 0, sizeof(dv));
	d_u.v=&dv;
	dv.magic=DRONE_MAGIC;
	dv.maj=DRONE_MAJ;
	dv.min=DRONE_MIN;
	recv_stats_t recv_stats;

	/* heh */
	if ((ac_s=socktrans_bind(s->ipcuri)) < 0) {
		terminate("cant create listener socket");
	}

	DBG(M_IPC, "waiting for main to connect");

	parent_sync();

	lc_s=socktrans_accept(ac_s, DEF_SOCK_TIMEOUT);
	if (lc_s < 0) {
		terminate("main didnt connect, exiting");
	}

	DBG(M_IPC, "got connection");

	if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) {
		terminate("unexpected sequence of messages from parent waiting for ident request, exiting");
	}

	if (msg_type != MSG_IDENT || status != MSG_STATUS_OK) {
		ERR("got an unknown message type `%s' or bad status %d from parent, exiting", strmsgtype(msg_type), status);
	}

	if (send_message(lc_s, MSG_IDENTLISTENER, MSG_STATUS_OK, d_u.ptr, sizeof(drone_version_t)) < 0) {
		terminate("cant send back msgident to parent");
	}

	if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) {
		terminate("cant read ident ack message from parent, exiting");
	}
	if (msg_type != MSG_ACK || status != MSG_STATUS_OK) {
		ERR("got an unknown message type `%s' or bad status %d from parent, exiting", strmsgtype(msg_type), status);
	}

	DBG(M_IPC, "sending ready message to parent");

	l_u.l=(listener_info_t *)xmalloc(sizeof(listener_info_t));

	memcpy(&l_u.l->myaddr, &s->vi[0]->myaddr, sizeof(struct sockaddr_storage));
	memcpy(&l_u.l->mymask, &s->vi[0]->mymask, sizeof(struct sockaddr_storage));
	memcpy(l_u.l->hwaddr, s->vi[0]->hwaddr, THE_ONLY_SUPPORTED_HWADDR_LEN);
	l_u.l->mtu=s->vi[0]->mtu;

	assert(s->interface_str != NULL);

	if (pcap_lookupnet(s->interface_str, &net, &mask, errbuf) < 0) {
		ERR("pcap_lookupnet fails, ignoring: %s", errbuf);
	}

	if (s->pcap_readfile == NULL) {
		pdev=pcap_open_live(s->interface_str, /* XXX haha */ s->vi[0]->mtu + 64, (GET_PROMISC() ? 1 : 0), 0, errbuf);
		if (pdev == NULL) {
			ERR("pcap open live: %s", errbuf);

			DBG(M_IPC, "sending ready error message to parent");
			if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
				terminate("cant send message ready error");
			}
			terminate("informed parent, exiting");
		}
	}
	else {
		pdev=pcap_open_offline(s->pcap_readfile, errbuf);
		if (pdev == NULL) {
			ERR("pcap open offline: %s", errbuf);

			DBG(M_IPC, "sending ready error message to parent");
			if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
				terminate("cant send message ready error");
			}
			terminate("informed parent, exiting");
		}
	}

	ret=util_getheadersize(pdev, errbuf);
	if (ret < 0 || ret > 0xffff) {
		ERR("error getting link header size: %s", errbuf);

		DBG(M_IPC, "sending ready error message to parent");
		if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
			terminate("cant send message ready error");
		}
		terminate("informed parent, exiting");
	}
	s->ss->header_len=(uint16_t)ret;

	if (s->pcap_dumpfile != NULL) {
		VRB(0, "opening `%s' for pcap log", s->pcap_dumpfile);
		pdump=pcap_dump_open(pdev, s->pcap_dumpfile);
		if (pdump == NULL) {
			ERR("cant log to pcap file `%s'", pcap_geterr(pdev));

			DBG(M_IPC, "sending ready error message to parent");
			if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
				terminate("cant send message ready error");
			}
			terminate("informed parent, exiting");
		}
	}
	else {
		DBG(M_CLD, "not logging to pcap file");
	}

	if (util_preparepcap(pdev, errbuf) < 0) {
		ERR("cant setup pcap filedesc to immediate mode: %s", errbuf);

		DBG(M_IPC, "sending ready error message to parent");
		if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
			terminate("cant send message ready error");
		}
		terminate("informed parent, exiting");
	}

	/* pcap_fd will be -1 for a pcap file */
	pcap_fd=pcap_get_selectable_fd(pdev);

	if (pcap_fd < 0 && s->pcap_readfile == NULL) {
		ERR("cant get selectable fd from pcap device, exiting");

		DBG(M_IPC, "sending ready error message to parent");
		if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
			terminate("sant send message ready error");
		}
		terminate("informed parent, exiting");
	}

#ifdef PCAP_D_IN
	if (pcap_setdirection(pdev, PCAP_D_IN) < 0) {
		ERR("cant set pcap direction to in, exiting");

		DBG(M_IPC, "sending ready error message to parent");
		if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
			terminate("sant send message ready error");
		}
		terminate("informed parent, exiting");
	}
#endif

	DBG(M_CLD, "listener dropping privs");

	if (drop_privs() < 0) {
		terminate("cant drop privs");
	}

	if (send_message(lc_s, MSG_READY, MSG_STATUS_OK, l_u.ptr, sizeof(listener_info_t)) < 0) {
		terminate("cant send message ready");
	}

	xfree(l_u.l);

	/* XXX */
	s->ss->syn_key=0;

	do {
		if (get_singlemessage(lc_s, &msg_type, &status, &wk_u.cr, &msg_len) != 1) {
			terminate("unexpected sequence of messages from parent looking for a workunit");
		}

		if (status != MSG_STATUS_OK) {
			terminate("bad message status %u", status);
		}

		if (msg_type == MSG_QUIT) {
			worktodo=0;
			break;
		}
		else if (msg_type == MSG_WORKUNIT) {
			;
		}
		else {
			terminate("unexpected message, expecting workunit or quit message");
		}

		if (msg_len < sizeof(uint32_t)) {
			terminate("bad message, too short [" STFMT "]", msg_len);
		}

		if (msg_len < sizeof(recv_workunit_t)) {
			terminate("short workunit");
		}

		worktodo=1;

		DBG(M_WRK, "workunit `%s'", strworkunit(wk_u.cr, msg_len));

		s->ss->recv_timeout=wk_u.r->recv_timeout;
		s->ss->ret_layers=wk_u.r->ret_layers;
		s->recv_opts=wk_u.r->recv_opts;
		s->ss->window_size=wk_u.r->window_size;

		s->ss->syn_key=wk_u.r->syn_key;

		if (wk_u.r->pcap_len) {
			if ((msg_len - sizeof(recv_workunit_t)) == wk_u.r->pcap_len) {
				extract_pcapfilter(wk_u.cr + sizeof(recv_workunit_t), wk_u.r->pcap_len);
			}
			else {
				terminate("pcap option length illegal");
			}
		}

		switch (*wk_u.magic) {
			case UDP_RECV_MAGIC:
				s->ss->mode=MODE_UDPSCAN;
				break;

			case TCP_RECV_MAGIC:
				s->ss->mode=MODE_TCPSCAN;
				break;

			case ARP_RECV_MAGIC:
				s->ss->mode=MODE_ARPSCAN;
				break;

			default:
				terminate("unknown recv workunit type");
				break;
		}

		DBG(M_IPC, "from ipc, got workunit: %s", strworkunit((const void *)wk_u.cr, msg_len));

		if (s->ss->mode == MODE_ARPSCAN) {
			if (s->ss->header_len != 14) {

				DBG(M_IPC, "sending msg error");
				if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
					terminate("cant send message ready");
				}
				terminate("wrong linktype for arp scan");
			}
		}

		if (s->ss->ret_layers > 0) {
			DBG(M_CLD, "setting up packet queue");
			p_queue=fifo_init();
		}

		pfilter=get_pcapfilterstr();

		VRB(1, "using pcap filter: `%s'", pfilter);

		memset(&filter, 0, sizeof(filter));
		if (pcap_compile(pdev, &filter, pfilter, 0, net) < 0) {
			ERR("error compiling filter: %s",  pcap_geterr(pdev));

			if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
				ERR("cant send message ready error");
			}
			terminate("cant compile pcap filter");
		}

		if (pcap_setfilter(pdev, &filter) < 0) {
			ERR("error setting compiled filter: %s", pcap_geterr(pdev));

			if (send_message(lc_s, MSG_READY, MSG_STATUS_ERROR, NULL, 0) < 0) {
				ERR("cant send message ready error");
			}
			terminate("cant set compiled pcap filter");
		}

		pcap_freecode(&filter);

		if (s->ss->ret_layers > 0) {
			DBG(M_IPC, "returning whole packet via ipc");
		}

		DBG(M_IPC, "sending ready message to parent");

		if (pcap_setnonblock(pdev, 1, errbuf) < 0) {
			terminate("cant set pcap non-blocking mode");
		}

		if (send_message(lc_s, MSG_READY, MSG_STATUS_OK, NULL, 0) < 0) {
			terminate("cant send message ready");
		}

		while (1) {
			spdf[0].fd=lc_s;
			spdf[1].fd=pcap_fd;

			/* if pdev is a socket  ( ! -1 ) */
			if (xpoll(&spdf[0], 2, -1) < 0) {
				ERR("xpoll fails: %s", strerror(errno));
			}

			if (spdf[1].rw & XPOLL_READABLE) {
				pcap_dispatch(pdev, 1, parse_packet, NULL);
			}

			/* no packets, better drain the queue */
			drain_pqueue();

			if (spdf[0].rw & XPOLL_READABLE) {
				if (get_singlemessage(lc_s, &msg_type, &status, &ptr, &msg_len) != 1) {
					ERR("unexpected sequence of messages from parent in main read loop, exiting");
					worktodo=0;
					break;
				}

				if (msg_type == MSG_TERMINATE) {
					DBG(M_IPC, "parent wants me to stop listening, breaking");
					break;
				}
				else if (msg_type == MSG_QUIT) {
					DBG(M_IPC, "Parent wants me to quit, breaking");
					worktodo=0;
					break;
				}
				else {
					ERR("got strange message `%s' from parent, exiting", strmsgtype(msg_type));
					worktodo=0;
					break;
				}
			}
		}

		memset(&recv_stats, 0, sizeof(recv_stats));

		if (pcap_stats(pdev, &pcs) != -1) {

			recv_stats.packets_recv=pcs.ps_recv;
			recv_stats.packets_dropped=pcs.ps_drop;
			recv_stats.packets_dropped=pcs.ps_ifdrop;
		}

		if (send_message(lc_s, MSG_WORKDONE, MSG_STATUS_OK, (void *)&recv_stats, sizeof(recv_stats)) < 0) {
			terminate("cant send workdone message to parent, exiting");
		}

	} while (worktodo);

	pcap_close(pdev);
	if (s->pcap_dumpfile) {
		pcap_dump_close(pdump);
	}


	DBG(M_CLD, "listener exiting");

	shutdown(lc_s, SHUT_RDWR);
	close(lc_s);
 
	uexit(0);
}
Пример #6
0
int main(int argc, char** argv)
{
	const char* pcap_file;
	const char* capture_interface;
	const char* tmp;
	int is_live = 0;
	int snaplen = 65535;
	uint32_t packet_pool_size = 1;
	pthread_t worker_id;
	uint32_t conn_no = 0;
	uint32_t conn_max = 0;
	uint32_t flow_timeout = 0;
	int print_stats_enabled = 0;

	if (argc != 2) {
		usage(argv[0]);
		return -1;
	}

	msg_setlevel(MSG_INFO);

	// install signal handler
	if (SIG_ERR == signal(SIGINT, sig_handler)) {
		msg(MSG_ERROR, "Could not install signal handler for SIGINT.");
		return -1;
	}
	if (SIG_ERR == signal(SIGCHLD, sig_chld_handler)) {
		msg(MSG_ERROR, "Could not install signal handler for SIGCHLD");
		return -1;
	}

	struct dumpers dumps;
	dumpers_init(&dumps);

	struct config* conf = config_new(argv[1]);
	if (!conf) {
		msg(MSG_ERROR, "Invalid config. Abort!");
		return 0;
	}

	// check if we should have any output over msg
	// quite mode is necessary when we are dumping to stdout
	tmp = config_get_option(conf, MAIN_NAME, "quiet");
	if (tmp) {
		if (!strcmp(tmp, "yes")) {
			msg_setlevel(-1);
		}
	}
	
	// check if we have a config statement that changes message level
	tmp = config_get_option(conf, MAIN_NAME, "msg_level");
	if (tmp) {
		if (!strcmp(tmp, "fatal")) {
			msg_setlevel(MSG_FATAL);
		} else if (!strcmp(tmp, "error")) {
			msg_setlevel(MSG_ERROR);
		} else if (!strcmp(tmp, "debug")) {
			msg_setlevel(MSG_DEBUG);
		} else if (!strcmp(tmp, "info")) {
			msg_setlevel(MSG_INFO);
		} else if (!strcmp(tmp, "stats")) {
			msg_setlevel(MSG_STATS);
		} else {
			msg(MSG_FATAL, "Unknown msg level ...");
		}
	}
	
	// do we want to periodically output statistics on dropped/received packets?
	tmp = config_get_option(conf, "MAIN_NAME", "packet_stats");
	if (tmp) {
		if (!strcmp(tmp, "yes")) {
			print_stats_enabled = 1;
		}
	}

	msg(MSG_INFO, "%s is initializing ...", argv[2]);

	pcap_file = config_get_option(conf, MAIN_NAME, "pcapfile");
	capture_interface = config_get_option(conf, MAIN_NAME, "interface");

	if (!pcap_file && !capture_interface) {
		msg(MSG_FATAL, "main: Neither \"pcapfile\" nor \"interface\" given in config file.");
		exit(-1);
	} if (pcap_file && capture_interface) {
		msg(MSG_FATAL, "main: Got \'pcapfile\" *and* \"interface\". Please decide whether you want to work on- or offline!");
		exit(-1);
	}

	tmp = config_get_option(conf, MAIN_NAME, "max_packet_size");
	if (tmp) {
		snaplen = atoi(tmp);
	}

	tmp = config_get_option(conf, MAIN_NAME, "packet_pool");
	if (tmp) {
		packet_pool_size = atoi(tmp);
	}

	// init connection pool
	if (!config_get_option(conf, MAIN_NAME, "init_connection_pool")) {
		msg(MSG_ERROR, "main: \"init_connection_pool\" missing in section %s", MAIN_NAME);
		return -1;
	}
	conn_no = atoi(config_get_option(conf, MAIN_NAME, "init_connection_pool"));

	if (!config_get_option(conf, MAIN_NAME, "max_connection_pool")) {
		msg(MSG_ERROR, "main: \"max_connection_pool\" missing in section %s", MAIN_NAME);
		return -1;
	}
	conn_max = atoi(config_get_option(conf, MAIN_NAME, "max_connection_pool"));

	if (!config_get_option(conf, MAIN_NAME, "flow_timeout")) {
		msg(MSG_ERROR, "main: \"flow_timeout\" missing in section %s", MAIN_NAME);
		return -1;
	}
	flow_timeout = atoi(config_get_option(conf, MAIN_NAME, "flow_timeout"));

	connection_init_pool(conn_no, conn_max, flow_timeout);


	struct packet_pool* packet_pool = packet_pool_init(packet_pool_size, snaplen);
	struct thread_data worker_data;
	worker_data.pool = packet_pool;
	worker_data.dumpers = &dumps;

	pcap_t* pfile;
	if (pcap_file) { 
		pfile = open_pcap(pcap_file, 0, snaplen); 
		dumpers_create_all(&dumps, conf, pcap_datalink(pfile), snaplen);
		if (!dumps.count) {
			msg(MSG_FATAL, "Could not configure any modules.");
			return -1;
		}
		if (pthread_create(&worker_id, NULL, worker_thread, &worker_data)) {
			msg(MSG_FATAL, "Could not create worker thread: %s", strerror(errno));
			return -1;
		}
	} else {
		is_live = 1;
		pfile = open_pcap(capture_interface, 1, snaplen);
		dumpers_create_all(&dumps, conf, pcap_datalink(pfile), snaplen);
		if (!dumps.count) {
			msg(MSG_FATAL, "Could not configure any modules.");
			return -1;
		}
		// the dumper creating can take a significant amount of time.
		// We could not read any packets during this initialization phase and 
		// could therefore drop a significant amount of packets (depending on
		// the link speed). We therefore close and reopen the pcap descriptor
		// in order to reset the statistics and get more accurate packet
		// drop statistice (we had to open the pcap interface for retrieving the
		// interface link type which is important for module initialization
		pcap_close(pfile);
		if (pthread_create(&worker_id, NULL, worker_thread, &worker_data)) {
			msg(MSG_FATAL, "Could not create worker thread: %s", strerror(errno));
			return -1;
		}
		pfile = open_pcap(capture_interface, 1, snaplen);
	}
	msg(MSG_INFO, "%s is up and running. Starting to consume packets ...", argv[0]);

	struct pcap_pkthdr pcap_hdr;
	time_t last_stats = 0;
	time_t stats_interval = 10;
	uint64_t captured = 0;
	const unsigned char* data = NULL;
	while (running) {
		if (NULL != (data = pcap_next(pfile, &pcap_hdr))) {
			captured++;
			if (print_stats_enabled) {
				if (pcap_hdr.ts.tv_sec - last_stats > stats_interval && is_live) {
					last_stats = pcap_hdr.ts.tv_sec;
					print_stats(pfile, captured, packet_pool);
				}
			}
			packet_new(packet_pool, &pcap_hdr, data);
		} else {
			if (!is_live)
				running = 0;
		}
	}

	msg(MSG_INFO, "%s finished reading packets ...", argv[0]);

	// TODO: this is a hack! we might need to wake the worker thread
	// because it might be blocked at a mutex waiting for new packets
	// we have to insert a packet in order to wake the thread from the 
	// mutex. Hence, we re-include the last packet into the pool again ...
	// FIXME: The hack can result in a segmentation fault if no packet
	// has been read from the pcap_t ...
	unsigned char* useless = malloc(snaplen);
	packet_new(packet_pool, &pcap_hdr, useless);
	free(useless);
	pthread_join(worker_id, NULL);

	// ok, the second worker is stopped right now
	// we are therefore the only thread that works on the connection pool.
	// lets timeout all active connnections to update the statistics (e.g. for stats_module)
	connection_flush_all_active_conns();

	dumpers_finish(&dumps);
	connection_deinit_pool();
	packet_pool_deinit(packet_pool);
	config_free(conf);

	return 0;
}
int main(int argc, char **argv)
{
	int i,j,src;
	int max;
	int min;
	float avg,sum;
	unsigned int pkt_counter=0;   // packet counter
	unsigned long byte_counter=0; //total bytes seen in entire trace
	unsigned long cur_counter=0; //counter for current 1-second interval
	unsigned long max_volume = 0;  //max value of bytes in one-second interval
	unsigned long current_ts=0;
	struct pcap_pkthdr header;

	if (argc < 2)
	{
	fprintf(stderr, "Usage: %s [input pcaps]\n", argv[0]);
	exit(1);
	}
	pcap_t *handle;
	char errbuf[PCAP_ERRBUF_SIZE];
	handle = pcap_open_offline(argv[1], errbuf);
	if (handle == NULL)
	{
	fprintf(stderr,"Couldn't open pcap file %s: %s\n", argv[1], errbuf);
	return(2);
	}
	if (pcap_datalink(handle) != DLT_EN10MB) {
		printf("this is not an Ethernet\n");
		exit(EXIT_FAILURE);
	}

	/*if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1)
	{
		fprintf(stderr, "Couldn't parse filter %s: %s\n",
		    filter_exp, pcap_geterr(handle));
		exit(EXIT_FAILURE);
	}
	if (pcap_setfilter(handle, &fp) == -1) {
		fprintf(stderr, "Couldn't install filter %s: %s\n",
		    filter_exp, pcap_geterr(handle));
		exit(EXIT_FAILURE);
	}*/
	//u_char *user = "******";
		ip_des_list = fopen("ipdes.txt","w");
		ip_src_list = fopen("ipsrc.txt","w");
		eth_src_list = fopen("ethsrc.txt","w");
		eth_des_list = fopen("ethdes.txt","w");
		tcp_port_src_list = fopen("tcp_port_src.txt","w");
		tcp_port_des_list = fopen("tcp_port_des.txt","w");
		udp_port_src_list = fopen("udp_port_src.txt","w");
		udp_port_des_list = fopen("udp_port_des.txt","w");

		pcap_loop(handle, 0, packet_handler, NULL);
		pcap_close(handle);
		FILE *ip_des_read, *ip_src_read, *eth_src_read, *eth_des_read;
		FILE *tcp_port_src_read, *tcp_port_des_read, *udp_port_src_read, *udp_port_des_read;
		fclose(ip_des_list);
		fclose(ip_src_list);
		fclose(eth_src_list);
		fclose(tcp_port_src_list);
		fclose(tcp_port_des_list);
		fclose(udp_port_src_list);
		fclose(udp_port_des_list);

	printf("\n  Ethernet Source     \t\tCount\n");
		eth_src_read = fopen("ethsrc.txt","r");
		PrintIpCount(eth_src_read);        //Calling the function to print Source Ethernet addresses count
		fclose(eth_src_read);

	printf("\n  Ethernet Destination     \tCount\n");
		eth_des_read = fopen("ethdes.txt","r");
		PrintIpCount(eth_des_read);        //Calling the function to print Destination Ethernet addresses count
		fclose(eth_des_read);


	printf("\n  Source IP address     \tCount\n");
		ip_src_read = fopen("ipsrc.txt","r");
		PrintIpCount(ip_src_read);    //Calling the function to print Source IP addresses count
		fclose(ip_src_read);

	printf("\n  Destination IP address     \tCount\n");
		ip_des_read = fopen("ipdes.txt","r");
		PrintIpCount(ip_des_read);        //Calling the function to print Destination IP addresses count
	fclose(ip_des_read);

	printf("\n  TCP Source Port Address     \tCount\n");
		tcp_port_src_read = fopen("tcp_port_src.txt","r");
		PrintIpCount(tcp_port_src_read);
		fclose(tcp_port_src_read);

	printf("\n  TCP Destination Port Address  Count\n");
		tcp_port_des_read = fopen("tcp_port_des.txt","r");
		PrintIpCount(tcp_port_des_read);
		fclose(tcp_port_des_read);

	printf("\n  UDP Source Port Address     \tCount\n");
		udp_port_src_read = fopen("udp_port_src.txt","r");
		PrintIpCount(udp_port_src_read);
		fclose(udp_port_src_read);

	printf("\n  UDP Destination Port Address  Count\n");
		udp_port_des_read = fopen("udp_port_des.txt","r");
		PrintIpCount(udp_port_des_read);
		fclose(udp_port_des_read);


	printf("ack\t%d\n",ack);
	printf("rst\t%d\n",rst);
	printf("syn\t%d\n",syn);
	printf("push\t%d\n",psh);
	printf("fin\t%d\n",fin);
	printf("urg\t%d\n",urg);
	printf("ece\t%d\n",ece);
	printf("cwr\t%d\n",cwr);
	min=size[0];
	max=size[0];
	for(i=0;i<count;i++)
	{

		if(size[i]<min)
		min=size[i];
		else if(size[i]>max)
		max=size[i];

	}
	for(i=0;i<count;i++)
	{
		sum+=size[i];
	}
		avg=sum/count;

	printf("26\t\t%d\n",count26);
	printf("52\t\t%d\n",count52);
	printf("62\t\t%d\n",count62);
	printf("806\t\t%d\n",count806);
	printf("ip\t\t%d\n",ip);
	printf("\nDuration is %ld\n",end-start);
	printf("Average packet size is  %0.2f\n",avg);
	printf("Minimum packet size is %d\n",min);
	printf("Maximum packet size is %d\n\n",max);

	printf("Total Number of packets is %d\n\n",count);

	return 0;
}
Пример #8
0
int StartClient(char *BindIP, char *ServIP, char *targetdev, char *Filter)
{
	memset(FrameBuff,0,40960);
	FrameBuffOffset=0;
	ReassembleSize=0;
	char *dev = NULL;            				/* capture device name */
	struct bpf_program fp;            			/* compiled filter program (expression) */
	pcap_t *handle;              			  	/* packet capture handle */
	char errbuf[PCAP_ERRBUF_SIZE]; 		       	/* error buffer */
	bpf_u_int32 mask;            		   		/* subnet mask */
   	bpf_u_int32 net;               		  		/* ip */
	int num_packets = -1;               		/* number of packets to capture */
	dev = targetdev;								/*Set the target dev */
	char buff[100];
	bzero(buff,100);
	char filter_exp[128] = FILTER_EXP; 		 /*Define the caputer filter:LDAP only and no TCP 3 handshake*/
	int frc = strncmp(Filter,"NULL",4);
	
	if(Filter != NULL && frc !=0 ){
		sprintf(buff, " and host %s", Filter);
		strcat(filter_exp, buff); 
	}
	

	
//#ifdef DEBUG
	printf("The Filter:%s\n",filter_exp);
//#endif 	
	
	/* Socket defination */
	struct ifreq ifr;
	char *iface = BOND0;
	struct sockaddr_in client_addr;
	bzero(&client_addr,sizeof(client_addr));
	memset(&ifr, 0, sizeof(ifr));

	int client_socket = socket(AF_INET,SOCK_STREAM,0);
	
	//IPv4
	/* Need to improve , auto bind the bond0 */
	client_addr.sin_family = AF_INET;
	client_addr.sin_addr.s_addr = inet_addr(BindIP); 
	client_addr.sin_port = htons(0);
	
	//Create TCP socket
	
    if( client_socket < 0)
    {
        printf("Create Socket Failed!\n");
        exit(1);
    }
	
	//Bind the Socket with Struct
    if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr)))
    {
        printf("Client Bind Port Failed!\n");
        exit(1);
    }
	
	//Define the Server socket for comm
	struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
	
    if(inet_aton(ServIP,&server_addr.sin_addr) == 0) 
	
    {
        printf("Server IP Address Error!\n");
        exit(1);
    }
	server_addr.sin_port = htons(SERVER_PORT);
    socklen_t server_addr_length = sizeof(server_addr);
	    
	/*--------------------------------*/
	
	//Connect to the Server
	if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0)
    {
        printf("Can Not Connect To Server!\n");
        exit(1);
    }
	
      /* get network number and mask associated with capture device */
    if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
        fprintf(stderr, "Couldn't get netmask for device %s: %s\n",
         dev, errbuf);
        net = 0;
        mask = 0;
    }


    /* print capture info */
    //printf("Device: %s\n", dev);
    //printf("Number of packets: %d\n", num_packets);
    //printf("Filter expression: %s\n", filter_exp);
	int rc =0;

	
	handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        exit(EXIT_FAILURE);
    }

    /* compile the filter expression */
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n",
         filter_exp, pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }


    /* apply the compiled filter */
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n",
         filter_exp, pcap_geterr(handle));
        exit(EXIT_FAILURE);
    }
	printf("Initial Interface for CAP ...OK\n");
	
	printf("Callback func starting...\n"); 
    /* now we can set our callback function */

	pcap_loop(handle, num_packets, got_packet, (u_char *)&client_socket);


    /* cleanup */
    pcap_freecode(&fp);
    pcap_close(handle);


    printf("\nCapture complete.\n");
	printf("Done\n");


return rc;
}
Пример #9
0
void terminate()
{
	pcap_close(p);	
}
Пример #10
0
/*
 * func: 	restruct a new udp package.
 * param: 	
 * return: 	0 success; -1 fail
 */
int restruct_pkt(char *buf, 
        struct eth_hdr *pethh, 
        struct ip_hdr *piph, int iph_len, 
        struct udp_hdr *pudph,
        uint32_t multi_ip,
        uint16_t multi_port)
{
    char errbuf[PCAP_ERRBUF_SIZE] = {0};
   // char * device = "eth0";
    char device [DEV_BUF_SIZE];
    pcap_t *adhandle = NULL;
    int ret;

    char *str_dev = get_dev_name(piph->ip_destaddr, device);
    if(str_dev == NULL)
    {
        fprintf(gfp_log, "[%s:%d]get_dev_name is null!\n", __FILE__, __LINE__);
        fflush(gfp_log);
        return -1;
    }
    if((adhandle = pcap_open_live(device, 0x10000, PCAP_OPENFLAG_PROMISCUOUS, 1000,  errbuf)) == NULL)
    {
        fprintf(gfp_log, "[%s:%d][pcap_open_live error] : %s\n", __FILE__, __LINE__, errbuf);
        fflush(gfp_log);
        return -1;
    }

    pethh->ether_dhost[0] = 0x01;
    pethh->ether_dhost[1] = 0x00;
    pethh->ether_dhost[2] = 0x5e;
    pethh->ether_dhost[3] = (unsigned char)((multi_ip  >> 8) & 0x7F);;
    pethh->ether_dhost[4] = (unsigned char)((multi_ip >> 16) & 0xFF);;
    pethh->ether_dhost[5] = (unsigned char)((multi_ip >> 24) & 0xFF);;
//AC:85:3D:AF:C7:08
    pethh->ether_shost[0] = 0x00;
    pethh->ether_shost[1] = 0x16;
    pethh->ether_shost[2] = 0x3e;
    pethh->ether_shost[3] = 0x00;
    pethh->ether_shost[4] = 0x04;
    pethh->ether_shost[5] = 0x0e;

    pethh->ether_type = htons(ETHERTYPE_IP);

    if((sizeof(struct ip_hdr) % 4) != 0)
    {
        fprintf(gfp_log, "[%s:%d][IP Header error]\n", __FILE__, __LINE__);
        fflush(gfp_log);
        pcap_close(adhandle);
        return -1;
    }
    uint16_t ip_len = ntohs(piph->ip_totallength);
    uint16_t udp_len = htons(pudph->udp_length);

    piph->ip_tos = 0;
    piph->ip_id = htons(0x0000);
    piph->ip_offset = htons(0x4000);
    piph->ip_ttl = 0x20;
    piph->ip_checksum = 0;
    piph->ip_destaddr = multi_ip;
    piph->ip_totallength = htons(ip_len); 
    piph->ip_checksum  = checksum((uint16_t *)piph, iph_len);

    pudph->dest_portno = htons(multi_port);
    pudph->src_portno = htons(52540);
    pudph->udp_checksum = 0;
    pudph->udp_length = htons(udp_len);
    pudph->udp_checksum = udp_checksum(piph, iph_len, udp_len);
    //pudph->udp_checksum = htons(0x16ed);
    //////just for test printf
    //printf("rebuild multicast package: \n");
    //printf("   src : %s" , inet_ntoa(*((struct in_addr *)(&piph->ip_srcaddr))));
    //printf("   dst : %s\n" , inet_ntoa(*((struct in_addr *)(&piph->ip_destaddr))));
    ///////////////////////////////////////////////////
    int pkt_len = ip_len + ETHER_HEADER_SIZE;

    /* just print the pkt info */
    /*
    int i=0;
    for(i = 0 ; i != sizeof(struct ip_hdr); i++)
    {
        printf("%02x ",(*((char *)piph+i))&0xff);
    }
    */
    //printf("pkt len %u\n", pkt_len);
    ret = write(tun, piph, ip_len);
    if(pcap_sendpacket(adhandle, (const u_char*)buf, pkt_len) == -1)
    {
        fprintf(gfp_log, "[%s:%d][pcap_sendpacket error]\n", __FILE__, __LINE__);
        fflush(gfp_log);
        pcap_close(adhandle);
        return -1;
    }
    else
    {
     //   printf("=====send a pkt!\n");
    }
    pcap_close(adhandle);
    return 0;
}
Пример #11
0
/*
 * func: 	restruct a new others proto package.
 * param: 	
 * return: 	0 success; -1 fail
 */
int restruct_pkt_others_proto(char *buf, 
        struct eth_hdr *pethh, 
        struct ip_hdr *piph, int iph_len, 
        struct udp_hdr *pudph,
        uint32_t multi_ip,
        uint16_t multi_port)
{
    char errbuf[PCAP_ERRBUF_SIZE] = {0};
    char * device = "eth0";
    pcap_t *adhandle = NULL;

    if((adhandle = pcap_open_live(device, 0x10000, PCAP_OPENFLAG_PROMISCUOUS, 1000, errbuf)) == NULL)
    {
        fprintf(gfp_log, "[%s:%d][pcap_open_live error] : %s\n", __FILE__, __LINE__, errbuf);
        fflush(gfp_log);
        return -1;
    }

    pethh->ether_dhost[0] = 0x01;
    pethh->ether_dhost[1] = 0x00;
    pethh->ether_dhost[2] = 0x5e;
    pethh->ether_dhost[3] = 0x7e;
    pethh->ether_dhost[4] = 0x01;
    pethh->ether_dhost[5] = 0x02;

    pethh->ether_shost[0] = 0x00;
    pethh->ether_shost[1] = 0x16;
    pethh->ether_shost[2] = 0x3e;
    pethh->ether_shost[3] = 0x00;
    pethh->ether_shost[4] = 0x04;
    pethh->ether_shost[5] = 0x0e;

    pethh->ether_type = htons(ETHERTYPE_IP);

    if((sizeof(struct ip_hdr) % 4) != 0)
    {
        fprintf(gfp_log, "[%s:%d][IP Header error]\n", __FILE__, __LINE__);
        pcap_close(adhandle);
        return -1;
    }

    uint16_t ip_len = ntohs(piph->ip_totallength);

    piph->ip_tos = 0;
    piph->ip_id = htons(0x1000);
    piph->ip_offset = htons(0x0040);
    piph->ip_ttl = 0x80;
    piph->ip_checksum = 0;
    piph->ip_destaddr = multi_ip;
    piph->ip_totallength = htons(ip_len); 
    piph->ip_checksum = checksum((u_int16_t*)piph, iph_len);


    int pkt_len = ip_len + ETHER_HEADER_SIZE;
    if(pcap_sendpacket(adhandle, (const u_char*)buf, pkt_len) == -1)
    {
        fprintf(gfp_log, "[%s:%d][pcap_sendpacket error]\n", __FILE__, __LINE__);
        fflush(gfp_log);
        pcap_close(adhandle);
        return -1;
    }
    pcap_close(adhandle);
    return 0;
}
Пример #12
0
/*
 * 1. Open 'p' pcap-handle(s)
 * 2. Capture 'n' packets per pcap-handle using a round-robin algorithm
 * 3. Print global statistics information
 */
int main (int argc, char * argv [])
{
  int option;

  char * interface = DEFAULT_INTERFACE;    /* interface name */
  int promiscuous  = 1;
  int snapshot     = DEFAULT_SNAPSHOT;

  /* How many pcap-handles */
  int handles = DEFAULT_HANDLES;
  pcap_t ** table = NULL;
  int p;
  char ebuf [PCAP_ERRBUF_SIZE];
  const unsigned char * packet;
  struct pcap_pkthdr header;

  /* How many packets */
  unsigned long maxcount = DEFAULT_PACKETS;
  unsigned long partial  = 0;
  unsigned long errors   = 0;

  int hb = -1;      /* heartbeat */
  int quiet = 0;

  struct timeval started;
  struct timeval stopped;
  double delta;

  /* Notice the program name */
  char * progname = strrchr (argv [0], '/');
  progname = ! progname ? * argv : progname + 1;

#define OPTSTRING "hvi:s:n:c:b:q"
  while ((option = getopt (argc, argv, OPTSTRING)) != EOF)
    {
      switch (option)
	{
	default: return -1;

	case 'h': usage (progname);   return 0;
        case 'v': version (progname); return 0;

	case 'i': interface = optarg;       break;
	case 's': snapshot = atoi (optarg); break;

	case 'n': handles = atoi (optarg);
	  if (! handles)
	    handles = 1;
	  break;

	case 'c': maxcount = atoi (optarg); break;

	case 'b': hb = atoi (optarg); break;
	case 'q': quiet = 1; break;
	}
    }

  /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

  /* Set unbuffered stdout */
  setvbuf (stdout, NULL, _IONBF, 0);

  if ((getuid () && geteuid ()) || setuid (0))
    {
      printf ("%s: sorry, you must be root in order to run this program\n", progname);
      return -1;
    }

  /* Find a suitable interface, if you don't have one */
  if (! interface && ! (interface = pcap_lookupdev (ebuf)))
    {
      printf ("%s: no suitable interface found, please specify one with -d\n", progname);
      return -1;
    }

  signal (SIGINT, on_ctrl_c);

  /* Announce */
  printf ("%s: requested to open #%d pcap-handle%s\n", progname, handles, handles > 1 ? "s" : "");

  /* Allocate enough memory to keep the pointers to the pcap-handle(s) */
  table = calloc ((handles + 1) * sizeof (pcap_t *), 1);
  for (p = 0; p < handles; p ++)
    table [p] = NULL;
  table [p] = NULL;

  /* Open the interface for packet capturing */
  for (p = 0; p < handles; p ++)
    if (! (table [p] = pcap_open_live (interface, snapshot, promiscuous, 1000, ebuf)))
      {
	printf ("%s: cannot open interface '%s' due to '%s'\n", progname, interface, ebuf);
	return -1;
      }

  printf ("%s: listening from %s using %s\n\n", progname, interface, pcap_lib_version ());

  /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */

  if (hb == -1)
    hb = maxcount / DEFAULT_HB;
  if (! hb)
    hb = 1;

  printf ("%s: starting to capture #%lu pckts using #%d pcap-handle%s...\n", progname, maxcount, handles, handles > 1 ? "s" : "");

  gettimeofday (& started, NULL);

  p = 0;
  while (! maxcount || (partial + errors) < maxcount)
    {
      /* Please give me just a packet at once from the interface */
      if ((packet = pcap_next (table [p], & header)))
	{
	  partial ++;
	  if (! quiet)
	    {
	      if (! (partial % hb))
		{
		  static unsigned long previous = 0;
		  static struct timeval latest;

		  struct timeval now;

		  /* Show pkts/secs in the latest period */
		  gettimeofday (& now, NULL);
		  delta = delta_time_in_milliseconds (& now, & latest);

		  printf ("%s: pkts rcvd #%lu of #%lu %s", progname, partial, maxcount, percentage (partial, maxcount));
		  if (previous && delta)
		    printf (" [%8.2f pkts/sec => +%lu pkts in %s]",
			    (double) (partial - previous) * 1000 / delta,
			    partial - previous, elapsed_time (& latest, & now));
		  printf ("\n");

		  previous = partial;
		  latest = now;
		}
	      else
		showbar (partial);
	    }
	}
      else
	errors ++;

      /* Round-robin to choose the pcap-handle candidate for the packet capture */
      p = (p + 1) % handles;
    }

  /* Close the pcap-handle(s) */
  for (p = 0; p < handles; p ++)
    pcap_close (table [p]);
  free (table);

  gettimeofday (& stopped, NULL);
  delta = (double) delta_time_in_milliseconds (& stopped, & started);

  printf ("              \n");

  printf ("Time:\n");
  printf ("=====\n");
  print_time_in_secs (& started, "Started:       ");
  print_time_in_secs (& stopped, "Finished:      ");
  printf ("Elapsed Time:  %s\n", elapsed_time (& started, & stopped));
  printf ("\n");

  /* Print out test results */
  printf ("Great Totals:\n");
  printf ("=============\n");
  printf ("pkts rcvd #%lu pckts of #%lu => %7.2f pkts/sec\n", partial, maxcount, (double) partial * 1000 / delta);

  return 0;
}
Пример #13
0
main(int argc, char *argv[])
{
    int   len;
    char *infile;
    char *conn_name;
    int  lineno=0;
    struct connection *c1;
    pcap_t *pt;
    char   eb1[256];

    EF_PROTECT_BELOW=1;
    EF_PROTECT_FREE=1;
    EF_FREE_WIPES  =1;

    progname = argv[0];
    leak_detective = 1;

    init_crypto();

    if(argc != 4) {
	fprintf(stderr, "Usage: %s <whackrecord> <conn-name> <pcapin>\n", progname);
	exit(10);
    }
    /* argv[1] == "-r" */

    tool_init_log();
    init_fake_vendorid();
    
    infile = argv[1];
    conn_name = argv[2];

    readwhackmsg(infile);

    send_packet_setup_pcap("parentR1.pcap");
 
    c1 = con_by_name(conn_name, TRUE);

    show_one_connection(c1);
    cur_debugging = DBG_EMITTING|DBG_CONTROL|DBG_CONTROLMORE;

    pt = pcap_open_offline(argv[3], eb1);
    if(!pt) {
	perror(argv[3]);
	exit(50);
    }
    pcap_dispatch(pt, 1, recv_pcap_packet, NULL);
    pcap_close(pt);

    /* read same packet from network again, to see what we will do */
    pt = pcap_open_offline(argv[3], eb1);
    if(!pt) {
	perror(argv[3]);
	exit(50);
    }

    pcap_dispatch(pt, 1, recv_pcap_packet, NULL);
    pcap_close(pt);

    show_states_status();

    {
	struct state *st;

	/* find st involved */
	st = state_with_serialno(1);
	delete_state(st);
    }

    report_leaks();

    tool_close_log();
    exit(0);
}
Пример #14
0
int pcap_io_init(char *adapter)
{
	int dlt;
	char *dlt_name;
	emu_printf("Opening adapter '%s'...",adapter);
	u16 checksum;
	GetMACAddress(adapter,&host_mac);
	
	//Near copy of the host mac, butchered slightly, should be pretty good!
	eeprom[0] = host_mac.bytes[0];
	eeprom[1] = host_mac.bytes[1];
	eeprom[2] = host_mac.bytes[2];
	eeprom[3] = host_mac.bytes[2];
	eeprom[4] = host_mac.bytes[5];
	eeprom[5] = host_mac.bytes[4];

	//The checksum seems to be all the values of the mac added up in 16bit chunks
	checksum = dev9.eeprom[0] + dev9.eeprom[1] + dev9.eeprom[2] & 0xffff;

	dev9.eeprom[3] = checksum;

	//emu_printf("eeprom Mac set to %x %x %x %x %x %x", eeprom[0], eeprom[1], eeprom[2], eeprom[3], eeprom[4], eeprom[5]);
	//emu_printf("Checksum %x %x", eeprom[6], eeprom[7]);
	
	/* Open the adapter */
	if ((adhandle= pcap_open_live(adapter,	// name of the device
							 65536,			// portion of the packet to capture. 
											// 65536 grants that the whole packet will be captured on all the MACs.
		pcap_mode==switched?1:0,				// promiscuous mode (nonzero means promiscuous)
							 1,			// read timeout
							 errbuf			// error buffer
							 )) == NULL)
	{
		fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", adapter);
		return -1;
	}

	dlt = pcap_datalink(adhandle);
	dlt_name = (char*)pcap_datalink_val_to_name(dlt);

	fprintf(stderr,"Device uses DLT %d: %s\n",dlt,dlt_name);
	switch(dlt)
	{
	case DLT_EN10MB :
	//case DLT_IEEE802_11:
		break;
	default:
		SysMessage("ERROR: Unsupported DataLink Type (%d): %s",dlt,dlt_name);
		pcap_close(adhandle);
		return -1;
	}

	if(pcap_setnonblock(adhandle,1,errbuf)==-1)
	{
		fprintf(stderr,"WARNING: Error setting non-blocking mode. Default mode will be used.\n");
	}

	//Changing the LogSetting might not affect logging
	//directory of winPcap logs if done after Open()
	const std::string pfile(s_strLogPath + "/packet.log");
	packet_log = fopen(pfile.c_str(), "w");

	const std::string plfile(s_strLogPath + "/pkt_log.pcap");
	dump_pcap = pcap_dump_open(adhandle, plfile.c_str());

	pcap_io_running=1;
	emu_printf("Ok.\n");
	return 0;
}
Injector::~Injector()
{
	if( handle_ )
		pcap_close(handle_);
}
Пример #16
0
int main(int argc, char* argv[])
{
if ( argc<4 )
{
usage(argv[0]);
return EXIT_FAILURE;
}

int retVal;
struct addrinfo hints,*addrinfo;

ZeroMemory(&hints,sizeof(hints));

WSADATA wsaData;
if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != NO_ERROR )
{
fprintf( stderr, "Error in WSAStartup():%d\n",WSAGetLastError());
return EXIT_FAILURE;
}
//
// Get MAC address of remote host (assume link local IpV6 address)
//

hints.ai_family = PF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

retVal = getaddrinfo(argv[2],0, &hints, &addrinfo);
if ( retVal!=0 )
{
WSACleanup();
fprintf( stderr, "Error in getaddrinfo():%d\n",WSAGetLastError());
exit(EXIT_FAILURE);
}

//
// Open WinPCap adapter
//
if ( (pcap_handle = pcap_open_live (argv[1], 1514, PCAP_OPENFLAG_PROMISCUOUS, 
100, (char*)errbuf)) == NULL )
{
freeaddrinfo(addrinfo);
WSACleanup();
fprintf(stderr, "Error opening device: %s\n",argv[1]);
return EXIT_FAILURE;
}

ZeroMemory(packet,sizeof(packet));
struct sockaddr_in6 *sa = (struct sockaddr_in6 *) addrinfo->ai_addr;

// fill ethernet header
eth_hdr->ether_dhost[0] = eth_hdr->ether_shost[0] = 0;// assume address like 
00:something;
eth_hdr->ether_dhost[1] = eth_hdr->ether_shost[1] = sa->sin6_addr.u.Byte[9];
eth_hdr->ether_dhost[2] = eth_hdr->ether_shost[2] = sa->sin6_addr.u.Byte[10];
eth_hdr->ether_dhost[3] = eth_hdr->ether_shost[3] = sa->sin6_addr.u.Byte[13];
eth_hdr->ether_dhost[4] = eth_hdr->ether_shost[4] = sa->sin6_addr.u.Byte[14];
eth_hdr->ether_dhost[5] = eth_hdr->ether_shost[5] = sa->sin6_addr.u.Byte[15];
eth_hdr->ether_type = 0xdd86;


// fill IP header
// source ip == destination ip

memcpy(ip6_hdr->ip_src.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte));

memcpy(ip6_hdr->ip_dst.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte));
ip6_hdr->ip_hl = 255;
ip6_hdr->ip_nh = IPPROTO_TCP;
ip6_hdr->ip_len = htons (20);
ip6_hdr->ip_flags[0] = 0x06 << 4;
srand((unsigned int) time(0));
// fill tcp header
tcp_hdr->th_sport = tcp_hdr->th_dport = htons (atoi(argv[3])); // source 
port equal to destination
tcp_hdr->th_seq = rand();
tcp_hdr->th_ack = rand();
tcp_hdr->th_off = htons(5);
tcp_hdr->th_win = rand();
tcp_hdr->th_sum = 0;
tcp_hdr->th_urp = htons(10);
tcp_hdr->th_off = 5;
tcp_hdr->th_flags = 2;
// calculate tcp checksum
int chsum = libnet_in_cksum ((u_int16_t *) & ip6_hdr->ip_src, 32);
chsum += ntohs (IPPROTO_TCP + sizeof (struct libnet_tcp_hdr));
chsum += libnet_in_cksum ((u_int16_t *) tcp_hdr, sizeof (struct 
libnet_tcp_hdr));
tcp_hdr->th_sum = LIBNET_CKSUM_CARRY (chsum);
// send data to wire
retVal = pcap_sendpacket (pcap_handle, (u_char *) packet, sizeof(packet));
if ( retVal == -1 )
{
fprintf(stderr,"Error writing packet to wire!!\n");
}
//
// close adapter, free mem.. etc..
//
pcap_close(pcap_handle);
freeaddrinfo(addrinfo);
WSACleanup();
return EXIT_SUCCESS;
}
Пример #17
0
int main(int argc, char *argv[]) {
  char errbuf[PCAP_ERRBUF_SIZE];
  char *dev = NULL;
  char filter[2048];
  bpf_u_int32 net; 
  bpf_u_int32 mask;
  struct bpf_program bpf;

  int i = 0;
  memset(filter, 0, sizeof(filter));
  char *tmp = filter;

  signal(SIGTERM, sig_handler);
  signal(SIGINT, sig_handler);
  for(i = 1;i < argc;i++) {
    if(strcasecmp(argv[i], "-h") == 0) {
      print_usage();
    }
    if(strcasecmp(argv[i], "-i") == 0) {
      if(i == 1 || i == argc - 2) {
        dev = argv[++i];
        continue;
      } else {
        printf("%s, Syntax error\n", APP_NAME);
        print_usage();
      }
    }
    tmp = stpcpy(tmp, argv[i]);
    *tmp++ = ' ';
  }

  if(dev == NULL) {
    dev = pcap_lookupdev(errbuf);
    if(dev == NULL) {
      fprintf(stderr, "Couldn't find default device for you: %s\n", errbuf);
      exit(EXIT_FAILURE);
    }
  }

  if( pcap_lookupnet(dev, &net, &mask, errbuf) == -1 ) {
    fprintf(stderr, "Couldn't get network address for %s: %s\n", dev, errbuf);
    exit(EXIT_FAILURE);
  }
  handle = pcap_open_live(dev, 518, 1, 2000, errbuf);
  if( handle == NULL ) {
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
    exit(EXIT_FAILURE);
  }

  if( pcap_compile(handle, &bpf, filter, 0, net) == -1 ) {
    fprintf(stderr, "Couldn't parse filter '%s': %s\n", filter, pcap_geterr(handle));
    exit(EXIT_FAILURE);
  }
  if( pcap_setfilter(handle, &bpf) == -1 ) {
    fprintf(stderr, "Couldn't install filter '%s': %s\n", filter, pcap_geterr(handle));
    exit(EXIT_FAILURE);
  }

  pcap_loop(handle, -1, got_packet, NULL);

  pcap_freecode(&bpf);
  pcap_close(handle);

  return(0);
}
Пример #18
0
int
main(int argc, char **argv)
{
	int ch, np, ret, Xflag = 0;
	pcap_handler phandler = dump_packet;
	const char *errstr = NULL;
	char *pidf = NULL;

	ret = 0;

	closefrom(STDERR_FILENO + 1);

	while ((ch = getopt(argc, argv, "Dxd:f:i:p:s:")) != -1) {
		switch (ch) {
		case 'D':
			Debug = 1;
			break;
		case 'd':
			delay = strtonum(optarg, 5, 60*60, &errstr);
			if (errstr)
				usage();
			break;
		case 'f':
			filename = optarg;
			break;
		case 'i':
			interface = optarg;
			break;
		case 'p':
			pidf = optarg;
			break;
		case 's':
			snaplen = strtonum(optarg, 0, PFLOGD_MAXSNAPLEN,
			    &errstr);
			if (snaplen <= 0)
				snaplen = DEF_SNAPLEN;
			if (errstr)
				snaplen = PFLOGD_MAXSNAPLEN;
			break;
		case 'x':
			Xflag++;
			break;
		default:
			usage();
		}

	}

	log_debug = Debug;
	argc -= optind;
	argv += optind;

	/* does interface exist */
	if (!if_exists(interface)) {
		warn("Failed to initialize: %s", interface);
		logmsg(LOG_ERR, "Failed to initialize: %s", interface);
		logmsg(LOG_ERR, "Exiting, init failure");
		exit(1);
	}

	if (!Debug) {
		openlog("pflogd", LOG_PID | LOG_CONS, LOG_DAEMON);
		if (daemon(0, 0)) {
			logmsg(LOG_WARNING, "Failed to become daemon: %s",
			    strerror(errno));
		}
		pidfile(pidf);
	}

	tzset();
	(void)umask(S_IRWXG | S_IRWXO);

	/* filter will be used by the privileged process */
	if (argc) {
		filter = copy_argv(argv);
		if (filter == NULL)
			logmsg(LOG_NOTICE, "Failed to form filter expression");
	}

	/* initialize pcap before dropping privileges */
	if (init_pcap()) {
		logmsg(LOG_ERR, "Exiting, init failure");
		exit(1);
	}

	/* Privilege separation begins here */
	if (priv_init()) {
		logmsg(LOG_ERR, "unable to privsep");
		exit(1);
	}

	setproctitle("[initializing]");
	/* Process is now unprivileged and inside a chroot */
	signal(SIGTERM, sig_close);
	signal(SIGINT, sig_close);
	signal(SIGQUIT, sig_close);
	signal(SIGALRM, sig_alrm);
	signal(SIGUSR1, sig_usr1);
	signal(SIGHUP, sig_hup);
	alarm(delay);

	buffer = malloc(PFLOGD_BUFSIZE);

	if (buffer == NULL) {
		logmsg(LOG_WARNING, "Failed to allocate output buffer");
		phandler = dump_packet_nobuf;
	} else {
		bufleft = buflen = PFLOGD_BUFSIZE;
		bufpos = buffer;
		bufpkt = 0;
	}

	if (reset_dump(Xflag) < 0) {
		if (Xflag)
			return (1);

		logmsg(LOG_ERR, "Logging suspended: open error");
		set_suspended(1);
	} else if (Xflag)
		return (0);

	while (1) {
		np = pcap_dispatch(hpcap, PCAP_NUM_PKTS,
		    phandler, (u_char *)dpcap);
		if (np < 0) {
			if (!if_exists(interface) == -1) {
				logmsg(LOG_NOTICE, "interface %s went away",
				    interface);
				ret = -1;
				break;
			}
			logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap));
		}

		if (gotsig_close)
			break;
		if (gotsig_hup) {
			if (reset_dump(0)) {
				logmsg(LOG_ERR,
				    "Logging suspended: open error");
				set_suspended(1);
			}
			gotsig_hup = 0;
		}

		if (gotsig_alrm) {
			if (dpcap)
				flush_buffer(dpcap);
			else 
				gotsig_hup = 1;
			gotsig_alrm = 0;
			alarm(delay);
		}

		if (gotsig_usr1) {
			log_pcap_stats();
			gotsig_usr1 = 0;
		}
	}

	logmsg(LOG_NOTICE, "Exiting");
	if (dpcap) {
		flush_buffer(dpcap);
		fclose(dpcap);
	}
	purge_buffer();

	log_pcap_stats();
	pcap_close(hpcap);
	if (!Debug)
		closelog();
	return (ret);
}
Пример #19
0
int
main(int argc, char **argv)
{
	int cnt, op, i, done = 0;
	bpf_u_int32 localnet, netmask;
	char *cp, *cmdbuf, *device;
	struct bpf_program fcode;
	 void (*oldhandler)(int);
	u_char *pcap_userdata;
	char ebuf[PCAP_ERRBUF_SIZE];

	cnt = -1;
	device = NULL;

	if ((cp = strrchr(argv[0], '/')) != NULL)
		program_name = cp + 1;
	else
		program_name = argv[0];

	opterr = 0;
	while ((i = getopt(argc, argv, "pa")) != -1)
	{
		switch (i)
		{
		case 'p':
			pflag = 1;
		break;
		case 'a':
			aflag = 1;
		break;
		case '?':
		default:
			done = 1;
		break;
		}
		if (done) break;
	}
	if (argc > (optind)) cmdbuf = copy_argv(&argv[optind]);
		else cmdbuf = "";

	if (device == NULL) {
		device = pcap_lookupdev(ebuf);
		if (device == NULL)
			error("%s", ebuf);
	}
	pd = pcap_open_live(device, snaplen,  1, 1000, ebuf);
	if (pd == NULL)
		error("%s", ebuf);
	i = pcap_snapshot(pd);
	if (snaplen < i) {
		warning("snaplen raised from %d to %d", snaplen, i);
		snaplen = i;
	}
	if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
		localnet = 0;
		netmask = 0;
		warning("%s", ebuf);
	}
	/*
	 * Let user own process after socket has been opened.
	 */
	setuid(getuid());

	if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
		error("%s", pcap_geterr(pd));

	(void)setsignal(SIGTERM, program_ending);
	(void)setsignal(SIGINT, program_ending);
	/* Cooperate with nohup(1) */
	if ((oldhandler = setsignal(SIGHUP, program_ending)) != SIG_DFL)
		(void)setsignal(SIGHUP, oldhandler);

	if (pcap_setfilter(pd, &fcode) < 0)
		error("%s", pcap_geterr(pd));
	pcap_userdata = 0;
	(void)fprintf(stderr, "%s: listening on %s\n", program_name, device);
	if (pcap_loop(pd, cnt, raw_print, pcap_userdata) < 0) {
		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
		    program_name, pcap_geterr(pd));
		exit(1);
	}
	pcap_close(pd);
	exit(0);
}
Пример #20
0
//------------------------------------------------------------------- 
int main(int argc, char **argv) 
{ 
unsigned int pkt_counter=0;  
struct ether_header *eptr;
struct pcap_pkthdr hdr;
struct arphdr * arp;
u_char *ptr;
int i;
  
  struct pcap_pkthdr header; // The header that pcap gives us 
  const u_char *packet; // The actual packet 
  int fnum;
  
  if (argc != 2) { 
    fprintf(stderr, "Usage: %s [input pcaps]\n", argv[0]); 
    exit(1); 
  }  		
    pcap_t *handle; 
    char errbuf[PCAP_ERRBUF_SIZE]; 
    handle = pcap_open_offline(argv[1], errbuf);   

    // ethernet header
            eptr = (struct ether_header *) packet; 
	    if (handle == NULL) { 
	      fprintf(stderr,"Couldn't open pcap file %s: %s\n", argv[fnum], errbuf); 
	      return(2); 
	    } 
	 
 while (packet = pcap_next(handle,&header))
 { 
		      
	 u_char *pkt_ptr = (u_char *)packet; 
		      

		      int ether_type = ((int)(pkt_ptr[12]) << 8) | (int)pkt_ptr[13]; 
		      int ether_offset = 0; 
	 
			
			printf("\nRecieved at ..... %s",ctime((const time_t*)&hdr.ts.tv_sec));
			printf("Ethernet address length is %d\n",ETHER_HDR_LEN);



	      if (ether_type == ETHER_TYPE_IP) 
		{ether_offset = 14; 
		printf("Ethernet type hex:%x dec:%d is an IP packet\n",
		ntohs(eptr->ether_type),
		ntohs(eptr->ether_type));
		}
	     
	      else if(ether_type == ETHER_TYPE_ARP)
	 	printf("Ethernet type hex:%x dec:%d is an ARP packet\n",ntohs(eptr->ether_type),ntohs(eptr->ether_type));
		 
	// printing details from ethernet header

		ptr = eptr->ether_dhost;
		i = ETHER_ADDR_LEN;
		printf("Destination Address: ");
		do{
		printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
		}while(--i>0);
		printf("\t");

		ptr = eptr->ether_shost;
		i = ETHER_ADDR_LEN;
		printf(" Source Address: ");
		do{
		printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++);
		}while(--i>0);
		printf("\n");



// IP packet
	 if (ether_type == ETHER_TYPE_IP)
      {
	 //parse the IP header 
	      pkt_ptr += ether_offset;  
	      struct ip *ip_hdr = (struct ip *)pkt_ptr;  
	      int size_ip= IP_HL(ip_hdr)*4;
	      int packet_length = ntohs(ip_hdr->ip_len); 
	      printf("packet length %d:\n",packet_length);
	      printf("Internet Protocol version 4: From: %s\t", inet_ntoa(ip_hdr->ip_src));
	      printf(" To: %s\n", inet_ntoa(ip_hdr->ip_dst));
	
	/* determine protocol */
	 switch(ip_hdr->ip_p) {
	  case IPPROTO_TCP:
	   printf("Protocol: TCP\n");
	   break;
	  case IPPROTO_UDP:
	   printf("Protocol: UDP\n");
	   break;
	  case IPPROTO_ICMP:
	   printf("Protocol: ICMP\n");
	   break;
	  case IPPROTO_IP:
	   printf("Protocol: IP\n");
	   break;
	  default:
	   printf("Protocol: unknown\n");
	   break;
	 }
	      


	//parse tcp header
		pkt_ptr += size_ip; 
		struct tcphdr *tcp_hdr;
		tcp_hdr = (struct tcphdr*)pkt_ptr;
	 printf("TCP header: Src port: %d\t", ntohs(tcp_hdr->th_sport));
	 printf(" Dst port: %d\n", ntohs(tcp_hdr->th_dport));
	  
	}


//ARP packet

if(ether_type == ETHER_TYPE_ARP)
{

arp=(struct arphdr *)(pkt_ptr+ sizeof(struct ether_header));

if (1==htons(arp->ar_op))
	printf("ARP Opcode: ARP Request\n");
else
	printf("ARP Opcode: ARP Reply\n");


}
	      pkt_counter++;  
	 
	    }  
 
    pcap_close(handle);  
 
 
  printf("Processed %d packets ", pkt_counter);
  return 0; 
} 
Пример #21
0
/*
	\param plen: the length of the current message (needed in order to be able
	to discard excess data in the message, if present)
*/
int daemon_opensource(SOCKET sockctrl, char *source, int srclen, uint32 plen, char *errbuf)
{
pcap_t *fp= NULL;					// pcap_t main variable
unsigned int nread;					// number of bytes of the payload read from the socket
char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
int sendbufidx= 0;					// index which keeps the number of bytes currently buffered
struct rpcap_openreply *openreply;	// open reply message


	strcpy(source, PCAP_SRC_IF_STRING);

	if (srclen <= (int) (strlen(PCAP_SRC_IF_STRING) + plen) )
	{
		rpcap_senderror(sockctrl, "Source string too long", PCAP_ERR_OPEN, NULL);
		return -1;
	}

	if ( (nread= sock_recv(sockctrl, &source[strlen(PCAP_SRC_IF_STRING)], plen, SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE)) == -1)
		return -1;

	// Check if all the data has been read; if not, discard the data in excess
	if (nread != plen)
		sock_discard(sockctrl, plen - nread, NULL, 0);

	// Puts a '0' to terminate the source string
	source[strlen(PCAP_SRC_IF_STRING) + plen]= 0;

	// Open the selected device
	// This is a fake open, since we do that only to get the needed parameters, then we close the device again
	if ( (fp= pcap_open(source, 
			1500 /* fake snaplen */,
			0 /* no promis */, 
			1000 /* fake timeout */,
			NULL /* local device, so no auth */,
			errbuf)) == NULL)
	{
		rpcap_senderror(sockctrl, errbuf, PCAP_ERR_OPEN, NULL);
		return -1;
	}


	// Now, I can send a RPCAP open reply message
	if ( sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
		RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	rpcap_createhdr( (struct rpcap_header *) sendbuf, RPCAP_MSG_OPEN_REPLY, 0, sizeof(struct rpcap_openreply) );

	openreply= (struct rpcap_openreply *) &sendbuf[sendbufidx];
	
	if ( sock_bufferize(NULL, sizeof(struct rpcap_openreply), NULL, &sendbufidx, 
		RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	memset(openreply, 0, sizeof(struct rpcap_openreply) );
	openreply->linktype= htonl(fp->linktype);
	openreply->tzoff= htonl(fp->tzoff);

	if ( sock_send(sockctrl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
		goto error;

	// I have to close the device again, since it has been opened with wrong parameters
	pcap_close(fp);
	fp= NULL;

	return 0;

error:
	if (fp)
	{
		pcap_close(fp);
		fp= NULL;
	}

	return -1;
}
Пример #22
0
int us_rawnet_socket( us_rawnet_context_t *self,
                      uint16_t ethertype,
                      const char *interface_name,
                      const uint8_t join_multicast[6] )
{
    int r = -1;
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_t *p;

    self->m_ethertype = ethertype;
    if ( join_multicast )
    {
        memcpy( self->m_default_dest_mac, join_multicast, 6 );
    }

    p = pcap_open_live( interface_name, 65536, 1, 1, errbuf );
    self->m_pcap = (void *)p;

    if ( !p )
    {
        us_log_error( "pcap open error on interface '%s': %s", interface_name, errbuf );
    }
    else
    {
        int dl = pcap_datalink( p );

        if ( dl != DLT_EN10MB && dl != DLT_IEEE802_11 )
        {
            us_log_error( "Interface %s is not an Ethernet or wireless interface", interface_name );
        }
        else
        {
            pcap_if_t *d = 0;
            self->m_interface_id = -1;
            if ( us_rawnet_alldevs == 0 )
            {
                if ( pcap_findalldevs( &us_rawnet_alldevs, errbuf ) != 0 || us_rawnet_alldevs == 0 )
                {
                    us_log_error( "pcap_findalldevs failed" );
                    pcap_close( p );
                    return -1;
                }
                atexit( us_rawnet_cleanup );
            }
            {
                for ( d = us_rawnet_alldevs; d != NULL; d = d->next )
                {
                    self->m_interface_id++;

                    /* find the interface by name */
                    if ( strcmp( interface_name, d->name ) == 0 )
                    {
/* now find the MAC address associated with it */
#if defined( _WIN32 )
                        PIP_ADAPTER_INFO info = NULL, ninfo;
                        ULONG ulOutBufLen = 0;
                        DWORD dwRetVal = 0;
                        if ( GetAdaptersInfo( info, &ulOutBufLen ) == ERROR_BUFFER_OVERFLOW )
                        {
                            info = (PIP_ADAPTER_INFO)malloc( ulOutBufLen );
                            if ( info != NULL )
                            {
                                if ( ( dwRetVal = GetAdaptersInfo( info, &ulOutBufLen ) ) == NO_ERROR )
                                {
                                    ninfo = info;
                                    while ( ninfo != NULL )
                                    {
                                        if ( strstr( d->name, ninfo->AdapterName ) > 0 )
                                        {
                                            if ( ninfo->AddressLength == 6 )
                                                memcpy( self->m_my_mac, ninfo->Address, 6 );
                                            break;
                                        }
                                        ninfo = ninfo->Next;
                                    }
                                }
                                else
                                    us_log_error( "Error in GetAdaptersInfo" );
                                free( info );
                            }
                            else
                            {
                                us_log_error( "Error in malloc for GetAdaptersInfo" );
                            }
                        }
#else
                        pcap_addr_t *alladdrs;
                        pcap_addr_t *a;
                        alladdrs = d->addresses;
                        for ( a = alladdrs; a != NULL; a = a->next )
                        {
                            if ( a->addr->sa_family == US_AF_LINK )
                            {
                                memcpy( self->m_my_mac, us_sockaddr_dl_get_mac( a->addr ), 6 );
                            }
                        }
#endif
                        break;
                    }
                }

                if ( self->m_interface_id == -1 )
                {
                    us_log_error( "unable to get MAC address for interface '%s'", interface_name );
                }
                else
                {
                    /* enable ether protocol filter */
                    us_rawnet_join_multicast( self, join_multicast );
                    self->m_fd = pcap_fileno( p );
                    if ( self->m_fd == -1 )
                    {
                        us_log_error( "Unable to get pcap fd" );
                    }
                    else
                    {
                        r = self->m_fd;
                    }
                }
            }
        }
    }

    if ( r == -1 )
    {
        if ( p )
        {
            pcap_close( p );
            self->m_pcap = 0;
        }
    }
    else
    {
        us_net_set_socket_nonblocking( r );
    }
    return r;
}
Пример #23
0
/*!
	\brief Main serving funtion
	This function is the one which does the job. It is the main() of the child
	thread, which is created as soon as a new connection is accepted.

	\param ptr: a void pointer that keeps the reference of the 'pthread_chain'
	value corrisponding to this thread. This variable is casted into a 'pthread_chain'
	value in order to retrieve the socket we're currently using, the therad ID, and 
	some pointers to the previous and next elements into this struct.

	\return None.
*/
void daemon_serviceloop( void *ptr )
{
char errbuf[PCAP_ERRBUF_SIZE + 1];		// keeps the error string, prior to be printed
char source[PCAP_BUF_SIZE];				// keeps the string that contains the interface to open
struct rpcap_header header;				// RPCAP message general header
pcap_t *fp= NULL;						// pcap_t main variable
struct daemon_slpars *pars;				// parameters related to the present daemon loop

pthread_t threaddata= 0;				// handle to the 'read from daemon and send to client' thread

unsigned int ifdrops, ifrecv, krnldrop, svrcapt;	// needed to save the values of the statistics

struct rpcap_sampling samp_param;		// in case sampling has been requested

// Structures needed for the select() call
fd_set rfds;						// set of socket descriptors we have to check
struct timeval tv;					// maximum time the select() can block waiting for data
int retval;							// select() return value


	pars= (struct daemon_slpars *) ptr;
	
	*errbuf= 0;	// Initialize errbuf

	// If we're in active mode, this is not a separate thread
	if (! pars->isactive)
	{
		// Modify thread params so that it can be killed at any time
		if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) )
			goto end;
		if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) )
			goto end;
	}

auth_again:
	// If we're in active mode, we have to check for the initial timeout
	if (!pars->isactive)
	{
		FD_ZERO(&rfds);
		// We do not have to block here
		tv.tv_sec = RPCAP_TIMEOUT_INIT;
		tv.tv_usec = 0;
		
		FD_SET(pars->sockctrl, &rfds);

		retval = select(pars->sockctrl + 1, &rfds, NULL, NULL, &tv);
		if (retval == -1)
		{
			sock_geterror("select(): ", errbuf, PCAP_ERRBUF_SIZE);
			rpcap_senderror(pars->sockctrl, errbuf, PCAP_ERR_NETW, NULL);
			goto end;
		}

		// The timeout has expired
		// So, this was a fake connection. Drop it down
		if (retval == 0)
		{
			rpcap_senderror(pars->sockctrl, "The RPCAP initial timeout has expired", PCAP_ERR_INITTIMEOUT, NULL);
			goto end;
		}
	}


	retval= daemon_checkauth(pars->sockctrl, pars->nullAuthAllowed, errbuf);

	if (retval)
	{
		// the other user requested to close the connection
		// It can be also the case of 'active mode', in which this host is not
		// allowed to connect to the other peer; in that case, it drops down the connection
		if (retval == -3) 
			goto end;

		// It can be an authentication failure or an unrecoverable error
		rpcap_senderror(pars->sockctrl, errbuf, PCAP_ERR_AUTH, NULL);

		// authentication error
		if (retval == -2)
		{
			// suspend for 1 sec
			// WARNING: this day is inserted only in this point; if the user drops down the connection
			// and it connects again, this suspension time does not have any effects.
			pthread_suspend(RPCAP_SUSPEND_WRONGAUTH*1000);
			goto auth_again;
		}

		 // Unrecoverable error
		if (retval == -1)
			goto end;
	}

	while (1)
	{
	int retval;

		errbuf[0]= 0;	// clear errbuf

		// Avoid zombies connections; check if the connection is opens but no commands are performed
		// from more than RPCAP_TIMEOUT_RUNTIME
		// Conditions:
		// - I have to be in normal mode (no active mode)
		// - if the device is open, I don't have to be in the middle of a capture (fp->rmt_sockdata)
		// - if the device is closed, I have always to check if a new command arrives
		//
		// Be carefully: the capture can have been started, but an error occurred (so fp != NULL, but
		//  rmt_sockdata is 0
		if ( (!pars->isactive) &&  ( (fp == NULL) || ( (fp != NULL) && (fp->rmt_sockdata == 0) ) ))
		{
			// Check for the initial timeout
			FD_ZERO(&rfds);
			// We do not have to block here
			tv.tv_sec = RPCAP_TIMEOUT_RUNTIME;
			tv.tv_usec = 0;
			
			FD_SET(pars->sockctrl, &rfds);

			retval = select(pars->sockctrl + 1, &rfds, NULL, NULL, &tv);
			if (retval == -1)
			{
				sock_geterror("select(): ", errbuf, PCAP_ERRBUF_SIZE);
				rpcap_senderror(pars->sockctrl, errbuf, PCAP_ERR_NETW, NULL);
				goto end;
			}

			// The timeout has expired
			// So, this was a fake connection. Drop it down
			if (retval == 0)
			{
				SOCK_ASSERT("The RPCAP runtime timeout has expired", 1);
				rpcap_senderror(pars->sockctrl, "The RPCAP runtime timeout has expired", PCAP_ERR_RUNTIMETIMEOUT, NULL);
				goto end;
			}
		}

		if (sock_recv(pars->sockctrl, (char *) &header, sizeof(struct rpcap_header), SOCK_RECEIVEALL_YES, errbuf, PCAP_ERRBUF_SIZE) == -1)
			goto end;

		// Checks if the message is correct
		// In case it is wrong, it discard the data
		retval= rpcap_checkmsg(errbuf, pars->sockctrl, &header,
			RPCAP_MSG_FINDALLIF_REQ,
			RPCAP_MSG_OPEN_REQ,
			RPCAP_MSG_STARTCAP_REQ,
			RPCAP_MSG_UPDATEFILTER_REQ,
			RPCAP_MSG_STATS_REQ,
			RPCAP_MSG_ENDCAP_REQ,
			RPCAP_MSG_SETSAMPLING_REQ,
			RPCAP_MSG_CLOSE,
			RPCAP_MSG_ERROR,
			0);

		switch (retval)
		{
			case -3:	// Unrecoverable network error
				goto end;	// Do nothing; just exit from findalldevs; the error code is already into the errbuf

			case -2:	// The other endpoint send a message that is not allowed here
			{
				rpcap_senderror(pars->sockctrl, "The RPCAP daemon received a message that is not valid", PCAP_ERR_WRONGMSG, errbuf);
			}
			case -1:	// The other endpoint has a version number that is not compatible with our
			{
				rpcap_senderror(pars->sockctrl, "RPCAP version number mismatch", PCAP_ERR_WRONGVER, errbuf);
			}
			break;

			case RPCAP_MSG_FINDALLIF_REQ:
			{
				// Checks that the header does not contain other data; if so, discard it
				if (ntohl(header.plen))
					sock_discard(pars->sockctrl, ntohl(header.plen), errbuf, PCAP_ERRBUF_SIZE);

				if (daemon_findalldevs(pars->sockctrl, errbuf) )
					SOCK_ASSERT(errbuf, 1);

				break;
			};

			case RPCAP_MSG_OPEN_REQ:
			{
				retval= daemon_opensource(pars->sockctrl, source, sizeof(source), ntohl(header.plen), errbuf);

				if (retval == -1)
					SOCK_ASSERT(errbuf, 1);

				break;
			};

			case RPCAP_MSG_SETSAMPLING_REQ:
			{
				retval= daemon_setsampling(pars->sockctrl, &samp_param, ntohl(header.plen), errbuf);

				if (retval == -1)
					SOCK_ASSERT(errbuf, 1);

				break;
			};

			case RPCAP_MSG_STARTCAP_REQ:
			{
				fp= daemon_startcapture(pars->sockctrl, &threaddata, source, pars->isactive, &samp_param, ntohl(header.plen), errbuf);

				if (fp == NULL)
					SOCK_ASSERT(errbuf, 1);

				break;
			};

			case RPCAP_MSG_UPDATEFILTER_REQ:
			{
				if (fp)
				{
					if (daemon_updatefilter(fp, ntohl(header.plen)) )
						SOCK_ASSERT(fp->errbuf, 1);
				}
				else
				{
					rpcap_senderror(pars->sockctrl, "Device not opened. Cannot update filter", PCAP_ERR_UPDATEFILTER, errbuf);
				}

				break;
			};

			case RPCAP_MSG_STATS_REQ:
			{
				// Checks that the header does not contain other data; if so, discard it
				if (ntohl(header.plen))
					sock_discard(pars->sockctrl, ntohl(header.plen), errbuf, PCAP_ERRBUF_SIZE);

				if (fp)
				{
					if (daemon_getstats(fp) )
						SOCK_ASSERT(fp->errbuf, 1);
				}
				else
				{
					SOCK_ASSERT("GetStats: this call should't be allowed here", 1);

					if (daemon_getstatsnopcap(pars->sockctrl, ifdrops, ifrecv, krnldrop, svrcapt, errbuf) )
						SOCK_ASSERT(errbuf, 1);
					// we have to keep compatibility with old applications, which ask for statistics
					// also when the capture has already stopped

//					rpcap_senderror(pars->sockctrl, "Device not opened. Cannot get statistics", PCAP_ERR_GETSTATS, errbuf);
				}

				break;
			};

			case RPCAP_MSG_ENDCAP_REQ:		// The other endpoint close the current capture session
			{
				if (fp)
				{
				struct pcap_stat stats;

					// Save statistics (we can need them in the future)
					if (pcap_stats(fp, &stats) )
					{
						ifdrops= stats.ps_ifdrop;
						ifrecv= stats.ps_recv;
						krnldrop= stats.ps_drop;
						svrcapt= fp->md.TotCapt;
					}
					else
						ifdrops= ifrecv= krnldrop= svrcapt= 0;

					if ( daemon_endcapture(fp, &threaddata, errbuf) )
						SOCK_ASSERT(errbuf, 1);
					fp= NULL;
				}
				else
				{
					rpcap_senderror(pars->sockctrl, "Device not opened. Cannot close the capture", PCAP_ERR_ENDCAPTURE, errbuf);
				}
				break;
			};

			case RPCAP_MSG_CLOSE:		// The other endpoint close the pcap session
			{
				// signal to the main that the user closed the control connection
				// This is used only in case of active mode
				pars->activeclose= 1;	
				SOCK_ASSERT("The other end system asked to close the connection.", 1);
				goto end;
				break;
			};

			case RPCAP_MSG_ERROR:		// The other endpoint reported an error
			{
				// Do nothing; just exit; the error code is already into the errbuf
				SOCK_ASSERT(errbuf, 1);
				break;
			};

			default:
			{
				SOCK_ASSERT("Internal error.", 1);
				break;
			};
		}
	}

end:
	// The child thread is about to end

	// perform pcap_t cleanup, in case it has not been done
	if (fp)
	{
		if (threaddata)
		{
			pthread_cancel(threaddata);
			threaddata= 0;
		}
		if (fp->rmt_sockdata)
		{
			sock_close(fp->rmt_sockdata, NULL, 0);
			fp->rmt_sockdata= 0;
		}
		pcap_close(fp);
		fp= NULL;
	}

	// Print message and exit
	SOCK_ASSERT("I'm exiting from the child loop", 1);
	SOCK_ASSERT(errbuf, 1);

	if (!pars->isactive)
	{
		if (pars->sockctrl)
			sock_close(pars->sockctrl, NULL, 0);
		
		free(pars);
#ifdef WIN32
		pthread_exit(0);
#endif
	}
}
Пример #24
0
struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR *name)
{
	static int32_t done;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_if_t *alldevs, *d;
	int32_t cnt;
// REMOVEME: Win32 specific
#if 0
	HMODULE hm;
	LPADAPTER lpAdapter = 0;
	PPACKET_OID_DATA OidData;
	struct netdriverdata *tc, *tcp;
#endif // 0
	pcap_t *fp;
	int32_t val;
	TCHAR *ss;

	if (enumerated) {
		if (out)
			*out = tds;
		return enumit (name);
	}
// REMOVEME: win32 specific
#if 0
	tcp = tds;
	hm = LoadLibrary ("wpcap.dll");
	if (hm == NULL) {
		write_log ("uaenet: winpcap not installed (wpcap.dll)\n");
		return NULL;
	}
	FreeLibrary (hm);
	hm = LoadLibrary ("packet.dll");
	if (hm == NULL) {
		write_log ("uaenet: winpcap not installed (packet.dll)\n");
		return NULL;
	}
	FreeLibrary (hm);
	if (!isdllversion ("wpcap.dll", 4, 0, 0, 0)) {
		write_log ("uaenet: too old winpcap, v4 or newer required\n");
		return NULL;
	}

	ss = au (pcap_lib_version ());
	if (!done)
		write_log ("uaenet: %s\n", ss);
	xfree (ss);
#endif // 0

	if (pcap_findalldevs (&alldevs, errbuf) == -1) {
		ss = au (errbuf);
		write_log ("uaenet: failed to get interfaces: %s\n", ss);
		xfree (ss);
		return NULL;
	}

	if (!done)
		write_log ("uaenet: detecting interfaces\n");
	for(cnt = 0, d = alldevs; d != NULL; d = d->next) {
		char *n2;
		TCHAR *ss2;
// REMOVEME:
//		tc = tcp + cnt;
		if (cnt >= MAX_TOTAL_NET_DEVICES) {
			write_log ("buffer overflow\n");
			break;
		}
		ss = au (d->name);
		ss2 = d->description ? au (d->description) : "(no description)";
		write_log ("%s\n- %s\n", ss, ss2);
		xfree (ss2);
		xfree (ss);
		n2 = d->name;
		if (!strlen (n2)) {
			write_log ("- corrupt name\n");
			continue;
		}
		fp = pcap_open_live (d->name, 65536, 0, 0, errbuf);
		if (!fp) {
			ss = au (errbuf);
			write_log ("- pcap_open() failed: %s\n", ss);
			xfree (ss);
			continue;
		}
		val = pcap_datalink (fp);
		pcap_close (fp);
		if (val != DLT_EN10MB) {
			if (!done)
				write_log ("- not an ethernet adapter (%d)\n", val);
			continue;
		}

// REMOVEME: win32 specific
#if 0
		lpAdapter = PacketOpenAdapter (n2 + strlen (PCAP_SRC_IF_STRING));
		if (lpAdapter == NULL) {
			if (!done)
				write_log ("- PacketOpenAdapter() failed\n");
			continue;
		}
		OidData = (PPACKET_OID_DATA)xcalloc (uint8_t, 6 + sizeof(PACKET_OID_DATA));
		if (OidData) {
			OidData->Length = 6;
			OidData->Oid = OID_802_3_CURRENT_ADDRESS;
			if (PacketRequest (lpAdapter, false, OidData)) {
				memcpy (tc->mac, OidData->Data, 6);
				if (!done)
					write_log ("- MAC %02X:%02X:%02X:%02X:%02X:%02X (%d)\n",
					tc->mac[0], tc->mac[1], tc->mac[2],
					tc->mac[3], tc->mac[4], tc->mac[5], cnt++);
				tc->active = 1;
				tc->mtu = 1522;
				tc->name = au (d->name);
				tc->desc = au (d->description);
			} else {
				write_log (" - failed to get MAC\n");
			}
			xfree (OidData);
		}
		PacketCloseAdapter (lpAdapter);
#endif // 0
	}
	if (!done)
		write_log ("uaenet: end of detection\n");
	done = 1;
	pcap_freealldevs (alldevs);
	enumerated = 1;
	if (out)
		*out = tds;
	return enumit (name);
}
Пример #25
0
int main ( int argc , char *argv[] )
{
	/* parameters parsing */
	int c;

	/* pcap */
	char 				errbuf[PCAP_ERRBUF_SIZE];
	struct bpf_program 		fp;
	char 				filter_exp[] = "ip6";
	char 				*source = 0;
	char 				*filter = filter_exp;
	const unsigned char		*packet = 0;
	struct pcap_pkthdr		header;

	/* packet dissection */
	struct ip6_hdr	*ip;
	unsigned int	error;

	/* extra */
	unsigned int ipf;

	fprintf( stderr, "\n###########################" );
	fprintf( stderr, "\n#     libntoh Example     #" );
	fprintf( stderr, "\n# ----------------------- #" );
	fprintf( stderr, "\n# Written by Chema Garcia #" );
	fprintf( stderr, "\n# ----------------------- #" );
	fprintf( stderr, "\n#  http://safetybits.net  #" );
	fprintf( stderr, "\n#   [email protected]  #" );
	fprintf( stderr, "\n###########################\n" );

	fprintf( stderr, "\n[i] libntoh version: %s\n", ntoh_version() );

	if ( argc < 3 )
	{
		fprintf( stderr, "\n[+] Usage: %s <options>\n", argv[0] );
		fprintf( stderr, "\n+ Options:" );
		fprintf( stderr, "\n\t-i | --iface <val> -----> Interface to read packets from" );
		fprintf( stderr, "\n\t-f | --file <val> ------> File path to read packets from" );
		fprintf( stderr, "\n\t-F | --filter <val> ----> Capture filter (default \"ipv6\")" );
		fprintf( stderr, "\n\t-c | --client ----------> Receive client data");
		fprintf( stderr, "\n\t-s | --server ----------> Receive server data\n\n");
		exit( 1 );
	}

	/* check parameters */
	while ( 1 )
	{
		int option_index = 0;
		static struct option long_options[] =
		{
		{ "iface" , 1 , 0 , 'i' } ,
		{ "file" , 1 , 0 , 'f' } ,
		{ "filter" , 1 , 0 , 'F' } ,
		{ "client" , 0 , 0 , 'c' },
		{ "server" , 0 , 0 , 's' },
		{ 0 , 0 , 0 , 0 } };

		if ( ( c = getopt_long( argc, argv, "i:f:F:cs", long_options, &option_index ) ) < 0 )
			break;

		switch ( c )
		{
			case 'i':
				source = optarg;
				handle = pcap_open_live( optarg, 65535, 1, 0, errbuf );
				break;

			case 'f':
				source = optarg;
				handle = pcap_open_offline( optarg, errbuf );
				break;

			case 'F':
				filter = optarg;
				break;

			case 'c':
				receive |= RECV_CLIENT;
				break;

			case 's':
				receive |= RECV_SERVER;
				break;
		}
	}

	if ( !receive )
		receive = (RECV_CLIENT | RECV_SERVER);

	if ( !handle )
	{
		fprintf( stderr, "\n[e] Error loading %s: %s\n", source, errbuf );
		exit( -1 );
	}

	if ( pcap_compile( handle, &fp, filter, 0, 0 ) < 0 )
	{
		fprintf( stderr, "\n[e] Error compiling filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) );
		pcap_close( handle );
		exit( -2 );
	}

	if ( pcap_setfilter( handle, &fp ) < 0 )
	{
		fprintf( stderr, "\n[e] Cannot set filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) );
		pcap_close( handle );
		exit( -3 );
	}
	pcap_freecode( &fp );

	/* verify datalink */
	if ( pcap_datalink( handle ) != DLT_EN10MB )
	{
		fprintf ( stderr , "\n[e] libntoh is independent from link layer, but this example only works with ethernet link layer\n");
		pcap_close ( handle );
		exit ( -4 );
	}

	fprintf( stderr, "\n[i] Source: %s / %s", source, pcap_datalink_val_to_description( pcap_datalink( handle ) ) );
	fprintf( stderr, "\n[i] Filter: %s", filter );

	fprintf( stderr, "\n[i] Receive data from client: ");
	if ( receive & RECV_CLIENT )
		fprintf( stderr , "Yes");
	else
		fprintf( stderr , "No");

	fprintf( stderr, "\n[i] Receive data from server: ");
	if ( receive & RECV_SERVER )
		fprintf( stderr , "Yes");
	else
		fprintf( stderr , "No");

	signal( SIGINT, &shandler );
	signal( SIGTERM, &shandler );

	/*******************************************/
	/** libntoh initialization process starts **/
	/*******************************************/

	ntoh_ipv6_init ();

	if ( ! (ipv6_session = ntoh_ipv6_new_session ( 0 , 0 , &error )) )
	{
		fprintf ( stderr , "\n[e] Error %d creating IPv6 session: %s" , error , ntoh_get_errdesc ( error ) );
		exit ( -6 );
	}

	fprintf ( stderr , "\n[i] Max. IPv6 flows allowed: %d\n\n" , ntoh_ipv6_get_size ( ipv6_session ) );

	/* capture starts */
	while ( ( packet = pcap_next( handle, &header ) ) != 0 )
	{
		/* get packet headers */
		ip = (struct ip6_hdr*) ( packet + sizeof ( struct ether_header ) );

		/* it is an IPv6 fragment */
		if ( NTOH_IPV6_IS_FRAGMENT(ip) )
			send_ipv6_fragment ( ip , &ipv6_callback );
	}

	ipf = ntoh_ipv6_count_flows ( ipv6_session );

	/* no streams left */
	if ( ipf > 0 )
	{
		fprintf( stderr, "\n\n[+] There are currently %i IPv6 flow(s). You can wait them to get closed or press CTRL+C\n" , ipf );
		pause();
	}

	shandler( 0 );

	//dummy return
	return 0;
}
Пример #26
0
int
main(int argc, char **argv)
{
	register int op;
	register char *cp, *device;
	int dorfmon, dopromisc, snaplen, useactivate, bufsize;
	char ebuf[PCAP_ERRBUF_SIZE];
	pcap_t *pd;
	int status = 0;

	device = NULL;
	dorfmon = 0;
	dopromisc = 0;
	snaplen = MAXIMUM_SNAPLEN;
	bufsize = 0;
	useactivate = 0;
	if ((cp = strrchr(argv[0], '/')) != NULL)
		program_name = cp + 1;
	else
		program_name = argv[0];

	opterr = 0;
	while ((op = getopt(argc, argv, "i:Ips:aB:")) != -1) {
		switch (op) {

		case 'i':
			device = optarg;
			break;

		case 'I':
			dorfmon = 1;
			useactivate = 1;	/* required for rfmon */
			break;

		case 'p':
			dopromisc = 1;
			break;

		case 's': {
			char *end;

			snaplen = strtol(optarg, &end, 0);
			if (optarg == end || *end != '\0'
			    || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN)
				error("invalid snaplen %s", optarg);
			else if (snaplen == 0)
				snaplen = MAXIMUM_SNAPLEN;
			break;
		}

		case 'B':
			bufsize = atoi(optarg)*1024;
			if (bufsize <= 0)
				error("invalid packet buffer size %s", optarg);
			useactivate = 1;	/* required for bufsize */
			break;

		case 'a':
			useactivate = 1;
			break;

		default:
			usage();
			/* NOTREACHED */
		}
	}

	if (device == NULL) {
		device = pcap_lookupdev(ebuf);
		if (device == NULL)
			error("pcap_lookupdev failed: %s", ebuf);
	}
	if (useactivate) {
		pd = pcap_create(device, ebuf);
		if (pd == NULL)
			error("%s: pcap_create failed: %s", device, ebuf);
		status = pcap_set_snaplen(pd, snaplen);
		if (status != 0)
			error("%s: pcap_set_snaplen failed: %s",
			    device, pcap_statustostr(status));
		if (dopromisc) {
			status = pcap_set_promisc(pd, 1);
			if (status != 0)
				error("%s: pcap_set_promisc failed: %s",
				    device, pcap_statustostr(status));
		}
		if (dorfmon) {
			status = pcap_set_rfmon(pd, 1);
			if (status != 0)
				error("%s: pcap_set_rfmon failed: %s",
				    device, pcap_statustostr(status));
		}
		status = pcap_set_timeout(pd, 1000);
		if (status != 0)
			error("%s: pcap_set_timeout failed: %s",
			    device, pcap_statustostr(status));
		if (bufsize != 0) {
			status = pcap_set_buffer_size(pd, bufsize);
			if (status != 0)
				error("%s: pcap_set_buffer_size failed: %s",
				    device, pcap_statustostr(status));
		}
		status = pcap_activate(pd);
		if (status < 0) {
			/*
			 * pcap_activate() failed.
			 */
			error("%s: %s\n(%s)", device,
			    pcap_statustostr(status), pcap_geterr(pd));
		} else if (status > 0) {
			/*
			 * pcap_activate() succeeded, but it's warning us
			 * of a problem it had.
			 */
			warning("%s: %s\n(%s)", device,
			    pcap_statustostr(status), pcap_geterr(pd));
		} else
			printf("%s opened successfully\n", device);
	} else {
		*ebuf = '\0';
		pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
		if (pd == NULL)
			error("%s", ebuf);
		else if (*ebuf)
			warning("%s", ebuf);
		else
			printf("%s opened successfully\n", device);
	}
	pcap_close(pd);
	exit(status < 0 ? 1 : 0);
}
Пример #27
0
void packetcapture_close(void)
{
	if (pc != NULL)
		pcap_close(pc);
}
Пример #28
0
void CMyListView::Cappacket()
{
	
	int m_count=1;               //申明自己用的变量
	CString m_count1;
	CString m_packetlen;
	CString m_protocol;
    //以下是网络变量
	pcap_if_t *alldevs;//指向设备的链表
	pcap_if_t *d;//临时变量,指向设备的链表
	char error_content[PCAP_ERRBUF_SIZE];
    /* 存储错误信息 */
    pcap_t *pcap_handle;
    /* winpcap句柄 */
//    const unsigned char *packet_content;
    /* 数据包内容 */
//    unsigned char *mac_string;
    /* 以太网地址 */
//    unsigned short int ethernet_type;
    /* 以太网类型 */
    bpf_u_int32 net_mask;
    /* 掩码地址 */
    bpf_u_int32 net_ip;
    /* 网络地址 */
//    char *net_interface;
    /* 网络接口 */
//    struct pcap_pkthdr * protocol_header;
    /* 数据包头部信息 */
//    struct ether_header *ethernet_protocol;
    /* 以太网协议变量 */
    struct bpf_program bpf_filter;
    /* BPF过滤规则 */
    char* bpf_filter_string= "";
    /* 过滤规则字符串 */
    
//	bpf_filter_string=(LPSTR)(LPCTSTR)m_filter;
//    struct ip_header* ip_protocol;//ip头
//    struct tcp_header* tcp_protocol;//tcp头
//    struct udp_header* udp_protocol;//UDP头
//    struct icmp_header* icmp_protocol;//icmp头
//	struct arp_header* arp_protocol;//arp头
//	struct ether_header* ether_protocol;//以太网头
//    u_int data_len;
//    u_int tcp_len;
//	const u_char* pkt_data;//数据
//    const u_char* pkt_data_temp;//数据备份
	pcap_dumper_t *dumpfile;//open_dump指针
	if(pcap_findalldevs(&alldevs,error_content)==-1)
	{
		AfxMessageBox("Error in pcap_findalldevs");
		AfxMessageBox(error_content);
	} 
	else
	{
		d=alldevs;
		while(m_count<m_mystruct.m_devindex_num)//获得网络接口
		{
			d=d->next;
			m_count++;
		} 
	} 
      
    pcap_lookupnet(d->name, &net_ip, &net_mask, error_content);// 获得网络地址和网络掩码 
	if(d->addresses != NULL)
		net_mask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
	else
		net_mask=0xffffff;

    pcap_handle = pcap_open_live(d->name,65536,m_mystruct.m_ipm,1000, error_content);//打开网路接口 
	pcap_freealldevs(alldevs);
    if(pcap_compile(pcap_handle,&bpf_filter,bpf_filter_string,1,net_mask)<0)// 编译过滤规则
	{ 
		AfxMessageBox("过滤规则出错!");
	} 
	if(pcap_setfilter(pcap_handle, &bpf_filter)<0)// 设置过滤规则 
	{ 
		AfxMessageBox("过滤规则出错!将使用默认方式捕获数据包");
	} 
	if (pcap_datalink(pcap_handle) != DLT_EN10MB)
        AfxMessageBox("不在局域网内");
	dumpfile=pcap_dump_open(pcap_handle,m_mystruct.m_file_path);
	if(dumpfile==NULL)
	{ 
		AfxMessageBox("不能打开文件!将使用默认文件default.DAT进行保存");
		CFile m_file;
		if (m_file.Open("default.DAT",CFile::modeRead,NULL))
		{ 
			m_file.Close();
			m_file.Remove("default.DAT");
		} 
	    m_mystruct.m_file_path="default.DAT";
		dumpfile=pcap_dump_open(pcap_handle,m_mystruct.m_file_path);
	}  
	
		m_mystruct.pcap_handle=pcap_handle;
//		m_mystruct.protocol_header=protocol_header;
//		m_mystruct.pkt_data=pkt_data;
		m_mystruct.dumpfile=dumpfile;
		CDlgStat m_dlgstat;
		AfxBeginThread(Cappacketlivethread,GetSafeHwnd());
		m_dlgstat.DoModal();
		WaitForSingleObject(m_eventEnd.m_hObject,INFINITE);
		Capoffline(m_mystruct.m_file_path);
		UpdateData(true);
		pcap_close(pcap_handle);
}
Пример #29
0
/* The pcap capture routine.
*/
int
pcap_capture(fko_srv_options_t *opts)
{
    pcap_t              *pcap;
    char                errstr[PCAP_ERRBUF_SIZE] = {0};
    struct bpf_program  fp;
    int                 res;
    int                 pcap_errcnt = 0;
    int                 pending_break = 0;
    int                 promisc = 0;
    int                 set_direction = 1;
    int                 pcap_file_mode = 0;
    int                 status;
    int                 useconds;
    int                 pcap_dispatch_count;
    int                 max_sniff_bytes;
    int                 is_err;
    pid_t               child_pid;

#if FIREWALL_IPFW
    time_t              now;
#endif

    useconds = strtol_wrapper(opts->config[CONF_PCAP_LOOP_SLEEP],
            0, RCHK_MAX_PCAP_LOOP_SLEEP, NO_EXIT_UPON_ERR, &is_err);
    if(is_err != FKO_SUCCESS)
    {
        log_msg(LOG_ERR, "[*] invalid PCAP_LOOP_SLEEP_value");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    max_sniff_bytes = strtol_wrapper(opts->config[CONF_MAX_SNIFF_BYTES],
            0, RCHK_MAX_SNIFF_BYTES, NO_EXIT_UPON_ERR, &is_err);
    if(is_err != FKO_SUCCESS)
    {
        log_msg(LOG_ERR, "[*] invalid MAX_SNIFF_BYTES");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Set promiscuous mode if ENABLE_PCAP_PROMISC is set to 'Y'.
    */
    if(strncasecmp(opts->config[CONF_ENABLE_PCAP_PROMISC], "Y", 1) == 0)
        promisc = 1;

    if(opts->config[CONF_PCAP_FILE] != NULL
            && opts->config[CONF_PCAP_FILE][0] != '\0')
        pcap_file_mode = 1;

    if(pcap_file_mode == 1) {
        log_msg(LOG_INFO, "Reading pcap file: %s",
            opts->config[CONF_PCAP_FILE]);

        pcap = pcap_open_offline(opts->config[CONF_PCAP_FILE], errstr);

        if(pcap == NULL)
        {
            log_msg(LOG_ERR, "[*] pcap_open_offline() error: %s",
                    errstr);
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }
    }
    else
    {
        log_msg(LOG_INFO, "Sniffing interface: %s",
            opts->config[CONF_PCAP_INTF]);

        pcap = pcap_open_live(opts->config[CONF_PCAP_INTF],
            max_sniff_bytes, promisc, 100, errstr
        );

        if(pcap == NULL)
        {
            log_msg(LOG_ERR, "[*] pcap_open_live() error: %s", errstr);
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }
    }

    /* Set pcap filters, if any.
    */
    if (opts->config[CONF_PCAP_FILTER][0] != '\0')
    {
        if(pcap_compile(pcap, &fp, opts->config[CONF_PCAP_FILTER], 1, 0) == -1)
        {
            log_msg(LOG_ERR, "[*] Error compiling pcap filter: %s",
                pcap_geterr(pcap)
            );
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }

        if(pcap_setfilter(pcap, &fp) == -1)
        {
            log_msg(LOG_ERR, "[*] Error setting pcap filter: %s",
                pcap_geterr(pcap)
            );
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }

        log_msg(LOG_INFO, "PCAP filter is: '%s'", opts->config[CONF_PCAP_FILTER]);

        pcap_freecode(&fp);
    }

    /* Determine and set the data link encapsulation offset.
    */
    switch(pcap_datalink(pcap)) {
        case DLT_EN10MB:
            opts->data_link_offset = 14;
            break;
#if defined(__linux__)
        case DLT_LINUX_SLL:
            opts->data_link_offset = 16;
            break;
#elif defined(__OpenBSD__)
        case DLT_LOOP:
            set_direction = 0;
            opts->data_link_offset = 4;
            break;
#endif
        case DLT_NULL:
            opts->data_link_offset = 4;
            break;
        default:
            opts->data_link_offset = 0;
            break;
    }

    /* We are only interested on seeing packets coming into the interface.
    */
    if ((opts->pcap_any_direction == 0)
            && (set_direction == 1) && (pcap_file_mode == 0)
            && (pcap_setdirection(pcap, PCAP_D_IN) < 0))
        if(opts->verbose)
            log_msg(LOG_WARNING, "[*] Warning: pcap error on setdirection: %s.",
                pcap_geterr(pcap));

    /* Set our pcap handle nonblocking mode.
     *
     * NOTE: This is simply set to 0 for now until we find a need
     *       to actually use this mode (which when set on a FreeBSD
     *       system, it silently breaks the packet capture).
    */
    if((pcap_file_mode == 0)
            && (pcap_setnonblock(pcap, DEF_PCAP_NONBLOCK, errstr)) == -1)
    {
        log_msg(LOG_ERR, "[*] Error setting pcap nonblocking to %i: %s",
            0, errstr
        );
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    pcap_dispatch_count = strtol_wrapper(opts->config[CONF_PCAP_DISPATCH_COUNT],
            0, RCHK_MAX_PCAP_DISPATCH_COUNT, NO_EXIT_UPON_ERR, &is_err);
    if(is_err != FKO_SUCCESS)
    {
        log_msg(LOG_ERR, "[*] invalid PCAP_DISPATCH_COUNT");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Initialize our signal handlers. You can check the return value for
     * the number of signals that were *not* set.  Those that were not set
     * will be listed in the log/stderr output.
    */
    if(set_sig_handlers() > 0)
        log_msg(LOG_ERR, "Errors encountered when setting signal handlers.");

    log_msg(LOG_INFO, "Starting fwknopd main event loop.");

    /* Jump into our home-grown packet cature loop.
    */
    while(1)
    {
        /* If we got a SIGCHLD and it was the tcp server, then handle it here.
        */
        if(got_sigchld)
        {
            if(opts->tcp_server_pid > 0)
            {
                child_pid = waitpid(0, &status, WNOHANG);

                if(child_pid == opts->tcp_server_pid)
                {
                    if(WIFSIGNALED(status))
                        log_msg(LOG_WARNING, "TCP server got signal: %i",  WTERMSIG(status));

                    log_msg(LOG_WARNING,
                        "TCP server exited with status of %i. Attempting restart.",
                        WEXITSTATUS(status)
                    );

                    opts->tcp_server_pid = 0;

                    /* Attempt to restart tcp server ? */
                    usleep(1000000);
                    run_tcp_server(opts);
                }
            }

            got_sigchld = 0;
        }

        /* Any signal except USR1, USR2, and SIGCHLD mean break the loop.
        */
        if(got_signal != 0)
        {
            if(got_sigint || got_sigterm || got_sighup)
            {
                pcap_breakloop(pcap);
                pending_break = 1;
            }
            else if(got_sigusr1 || got_sigusr2)
            {
                /* Not doing anything with these yet.
                */
                got_sigusr1 = got_sigusr2 = 0;
                got_signal = 0;
            }
            else
                got_signal = 0;
        }

        res = pcap_dispatch(pcap, pcap_dispatch_count,
            (pcap_handler)&process_packet, (unsigned char *)opts);

        /* Count processed packets
        */
        if(res > 0)
        {
            if(opts->foreground == 1 && opts->verbose > 2)
                log_msg(LOG_DEBUG, "pcap_dispatch() processed: %d packets", res);

            /* Count the set of processed packets (pcap_dispatch() return
             * value) - we use this as a comparison for --packet-limit regardless
             * of SPA packet validity at this point.
            */
            opts->packet_ctr += res;
            if (opts->packet_ctr_limit && opts->packet_ctr >= opts->packet_ctr_limit)
            {
                log_msg(LOG_WARNING,
                    "* Incoming packet count limit of %i reached",
                    opts->packet_ctr_limit
                );

                pcap_breakloop(pcap);
                pending_break = 1;
            }
        }
        /* If there was an error, complain and go on (to an extent before
         * giving up).
        */
        else if(res == -1)
        {
            log_msg(LOG_ERR, "[*] Error from pcap_dispatch: %s",
                pcap_geterr(pcap)
            );

            if(pcap_errcnt++ > MAX_PCAP_ERRORS_BEFORE_BAIL)
            {
                log_msg(LOG_ERR, "[*] %i consecutive pcap errors.  Giving up",
                    pcap_errcnt
                );
                clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
            }
        }
        else if(pending_break == 1 || res == -2)
        {
            /* pcap_breakloop was called, so we bail. */
            log_msg(LOG_INFO, "Gracefully leaving the fwknopd event loop.");
            break;
        }
        else
            pcap_errcnt = 0;

        /* Check for any expired firewall rules and deal with them.
        */
        check_firewall_rules(opts);

#if FIREWALL_IPFW
        /* Purge expired rules that no longer have any corresponding
         * dynamic rules.
        */
        if(opts->fw_config->total_rules > 0)
        {
            time(&now);
            if(opts->fw_config->last_purge < (now - opts->fw_config->purge_interval))
            {
                ipfw_purge_expired_rules(opts);
                opts->fw_config->last_purge = now;
            }
        }
#endif

        usleep(useconds);
    }

    pcap_close(pcap);

    return(0);
}
Пример #30
0
int main (int argc , char *argv[])
{
        signal( SIGINT, &shandler );
        signal( SIGTERM, &shandler );
        signal( SIGSEGV, &shandler );

        write(2, "\n\t\t######################################", 41);
        write(2, "\n\t\t#           Dump HTTP Sigs           #", 41);
        write(2, "\n\t\t# ---------------------------------- #", 41);
        write(2, "\n\t\t#     Written by Ernest Richards     #", 41);
        write(2, "\n\t\t#  Based on code from Chema Garcia   #", 41);
        write(2, "\n\t\t# ---------------------------------- #", 41);
        write(2, "\n\t\t# Github.com/ernesto341/ais-research #", 41);
        write(2, "\n\t\t######################################\n", 42);
        write(2, "\n\t\tX      -----    Active    -----      X\n\n", 43);

        if (DEBUG)
        {
                sprintf(buf, "\n[i] libntoh version: %s\n", ntoh_version());
                write(2, buf, strlen(buf));
        }

        if ( argc < 3 )
        {
                sprintf(buf, "\n[+] Usage: %s <options>\n", argv[0]);
                write(2, buf, strlen(buf));
                write(2, "\n+ Options:", 11);      // 28
                write(2, "\n\t-i | --iface <val> -----> Interface to read packets from", 58);
                write(2, "\n\t-f | --file <val> ------> File path to read packets from", 58);
                write(2, "\n\t-F | --filter <val> ----> Capture filter (must contain \"tcp\" or \"ip\")", 71);
                write(2, "\n\t-c | --client ----------> Receive client data only", 52);
                write(2, "\n\t-s | --server ----------> Receive server data only\n\n", 54);
                exit(1);
        }

        /* parameters parsing */
        int32_t c = 0;

        /* pcap */
        char errbuf[PCAP_ERRBUF_SIZE];
        struct bpf_program fp;
        char filter_exp[] = "ip";
        char *source = 0;
        char *filter = filter_exp;
        const unsigned char *packet = 0;
        struct pcap_pkthdr header;

        /* packet dissection */
        struct ip	*ip;
        uint32_t error = 0;

        /* extra */
        uint32_t ipf, tcps;

        /* check parameters */
        while ( c >= 0 )
        {
                int32_t option_index = 0;
                static struct option long_options[] =
                {
                        { "iface" , 1 , 0 , 'i' },
                        { "file" , 1 , 0 , 'f' },
                        { "filter" , 1 , 0 , 'F' },
                        { "client" , 0 , 0 , 'c' },
                        { "server" , 0 , 0 , 's' },
                        { 0 , 0 , 0 , 0 }
                };

                c = getopt_long( argc, argv, "i:f:F:cs", long_options, &option_index );

                if (c >= 0)
                {

                        switch ( c )
                        {
                                case 'i':
                                        source = optarg;
                                        handle = pcap_open_live( optarg, 65535, 1, 0, errbuf );
                                        break;

                                case 'f':
                                        source = optarg;
                                        handle = pcap_open_offline( optarg, errbuf );
                                        break;

                                case 'F':
                                        filter = optarg;
                                        break;

                                case 'c':
                                        receive |= RECV_CLIENT;
                                        break;

                                case 's':
                                        receive |= RECV_SERVER;
                                        break;
                        }
                }
        }

        if ( !receive )
        {
                receive = (RECV_CLIENT | RECV_SERVER);
        }

        if ( !handle )
        {
                if (DEBUG)
                {
                        fprintf( stderr, "\n[e] Error loading %s: %s\n", source, errbuf );
                }
                exit( -1 );
        }

        if ( pcap_compile( handle, &fp, filter, 0, 0 ) < 0 )
        {
                if (DEBUG)
                {
                        fprintf( stderr, "\n[e] Error compiling filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) );
                }
                pcap_close( handle );
                exit( -2 );
        }

        if ( pcap_setfilter( handle, &fp ) < 0 )
        {
                if (DEBUG)
                {
                        fprintf( stderr, "\n[e] Cannot set filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) );
                }
                pcap_close( handle );
                exit( -3 );
        }
        pcap_freecode( &fp );

        /* verify datalink */
        if ( pcap_datalink( handle ) != DLT_EN10MB )
        {
                if (DEBUG)
                {
                        fprintf ( stderr , "\n[e] libntoh is independent from link layer, but this code only works with ethernet link layer\n");
                }
                pcap_close ( handle );
                exit ( -4 );
        }

        if (DEBUG)
        {
                fprintf( stderr, "\n[i] Source: %s / %s", source, pcap_datalink_val_to_description( pcap_datalink( handle ) ) );
                fprintf( stderr, "\n[i] Filter: %s", filter );

                fprintf( stderr, "\n[i] Receive data from client: ");
                if ( receive & RECV_CLIENT )
                {
                        fprintf( stderr , "Yes");
                }
                else
                {
                        fprintf( stderr , "No");
                }

                fprintf( stderr, "\n[i] Receive data from server: ");
                if ( receive & RECV_SERVER )
                {
                        fprintf( stderr , "Yes");
                }
                else
                {
                        fprintf( stderr , "No");
                }
        }

        /*******************************************/
        /** libntoh initialization process starts **/
        /*******************************************/

        initMem(&snc);

        /* fork and exec retrieve in retdir */

        char *null_args[] = {NULL};
        char *null_envp[] = {NULL};
        
        if ((ret_pid = fork()) == 0) /* child */
        {
                if (execve((char *)"./retdir/retrieve\0", null_args, null_envp) < 0)
                {
                        perror("execve()");
                        shandler(-1);
                }
        }
        else
        {

                if ((t5Convert = (sig_atomic_t *)malloc(sizeof(sig_atomic_t) * t5TplLen)) < (sig_atomic_t *)0)
                {
                        write(2, "\n\t[e] --- Unable to allocate sufficient memory\n", 47);
                        fflush(stderr);
                        _exit(-1);
                }

                ntoh_init ();

                if ( ! (tcp_session = ntoh_tcp_new_session ( 0 , 0 , &error ) ) )
                {
                        if (DEBUG)
                        {
                                fprintf ( stderr , "\n[e] Error %d creating TCP session: %s" , error , ntoh_get_errdesc ( error ) );
                        }
                        exit ( -5 );
                }

                if (DEBUG)
                {
                        fprintf ( stderr , "\n[i] Max. TCP streams allowed: %d" , ntoh_tcp_get_size ( tcp_session ) );
                }

                if ( ! (ipv4_session = ntoh_ipv4_new_session ( 0 , 0 , &error )) )
                {
                        ntoh_tcp_free_session ( tcp_session );
                        if (DEBUG)
                        {
                                fprintf ( stderr , "\n[e] Error %d creating IPv4 session: %s" , error , ntoh_get_errdesc ( error ) );
                        }
                        exit ( -6 );
                }

                if (DEBUG)
                {
                        fprintf ( stderr , "\n[i] Max. IPv4 flows allowed: %d\n\n" , ntoh_ipv4_get_size ( ipv4_session ) );

                        fflush(stderr);
                }

                /* capture starts */
                /* accept signal from consumer to quit */
                while ( ( packet = pcap_next( handle, &header ) ) != 0 && snc.smem.shm[CTL][FLAGS] != CDONE)
                {
                        static int pc = 0;
                        fprintf(stdout, "Packet %d\n", ++pc);
                        fflush(stdout);
                        /* get packet headers */
                        ip = (struct ip*) ( packet + sizeof ( struct ether_header ) );
                        if ( (ip->ip_hl * 4 ) < (int)sizeof(struct ip) )
                        {
                                continue;
                        }

                        /* it is an IPv4 fragment */
                        if ( NTOH_IPV4_IS_FRAGMENT(ip->ip_off) )
                        {
                                send_ipv4_fragment ( ip , &ipv4_callback );
                        }
                        /* or a TCP segment */
                        else if ( ip->ip_p == IPPROTO_TCP )
                        {
                                send_tcp_segment ( ip , &tcp_callback );
                        }
                }
                if (snc.smem.shm[CTL][FLAGS] == CDONE)
                {
                        shandler( 0 );
                }

                tcps = ntoh_tcp_count_streams( tcp_session );
                ipf = ntoh_ipv4_count_flows ( ipv4_session );

                /* no streams left */
                if ( ipf + tcps > 0 )
                {
                        if (DEBUG)
                        {
                                fprintf( stderr, "\n\n[+] There are currently %i stored TCP stream(s) and %i IPv4 flow(s). You can wait for them to get closed or press CTRL+C\n" , tcps , ipf );
                                pause();
                        }
                }

                shandler( 0 );

        }
        //dummy return, should never be called
        return (0);
}