亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? pcap-linux.c

?? 用來監視網絡通信數據的源代碼和應用程序,方便網絡程序底層開發.
?? C
?? 第 1 頁 / 共 5 頁
字號:
	 */
	return pcap_read_packet(handle, callback, user);
}

/*
 *  Read a packet from the socket calling the handler provided by
 *  the user. Returns the number of packets received or -1 if an
 *  error occured.
 */
static int
pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
{
	u_char			*bp;
	int			offset;
#ifdef HAVE_PF_PACKET_SOCKETS
	struct sockaddr_ll	from;
	struct sll_header	*hdrp;
#else
	struct sockaddr		from;
#endif
	socklen_t		fromlen;
	int			packet_len, caplen;
	struct pcap_pkthdr	pcap_header;

#ifdef HAVE_PF_PACKET_SOCKETS
	/*
	 * If this is a cooked device, leave extra room for a
	 * fake packet header.
	 */
	if (handle->md.cooked)
		offset = SLL_HDR_LEN;
	else
		offset = 0;
#else
	/*
	 * This system doesn't have PF_PACKET sockets, so it doesn't
	 * support cooked devices.
	 */
	offset = 0;
#endif

	/* Receive a single packet from the kernel */

	bp = handle->buffer + handle->offset;
	do {
		fromlen = sizeof(from);
		packet_len = recvfrom(
			handle->fd, bp + offset,
			handle->bufsize - offset, MSG_TRUNC,
			(struct sockaddr *) &from, &fromlen);
	} while (packet_len == -1 && errno == EINTR);

	/* Check if an error occured */

	if (packet_len == -1) {
		if (errno == EAGAIN)
			return 0;	/* no packet there */
		else {
			snprintf(handle->errbuf, sizeof(handle->errbuf),
				 "recvfrom: %s", pcap_strerror(errno));
			return -1;
		}
	}

#ifdef HAVE_PF_PACKET_SOCKETS
	/*
	 * If this is from the loopback device, reject outgoing packets;
	 * we'll see the packet as an incoming packet as well, and
	 * we don't want to see it twice.
	 *
	 * We can only do this if we're using PF_PACKET; the address
	 * returned for SOCK_PACKET is a "sockaddr_pkt" which lacks
	 * the relevant packet type information.
	 */
	if (!handle->md.sock_packet &&
	    from.sll_ifindex == handle->md.lo_ifindex &&
	    from.sll_pkttype == PACKET_OUTGOING)
		return 0;
#endif

#ifdef HAVE_PF_PACKET_SOCKETS
	/*
	 * If this is a cooked device, fill in the fake packet header.
	 */
	if (handle->md.cooked) {
		/*
		 * Add the length of the fake header to the length
		 * of packet data we read.
		 */
		packet_len += SLL_HDR_LEN;

		hdrp = (struct sll_header *)bp;

		/*
		 * Map the PACKET_ value to a LINUX_SLL_ value; we
		 * want the same numerical value to be used in
		 * the link-layer header even if the numerical values
		 * for the PACKET_ #defines change, so that programs
		 * that look at the packet type field will always be
		 * able to handle DLT_LINUX_SLL captures.
		 */
		switch (from.sll_pkttype) {

		case PACKET_HOST:
			hdrp->sll_pkttype = htons(LINUX_SLL_HOST);
			break;

		case PACKET_BROADCAST:
			hdrp->sll_pkttype = htons(LINUX_SLL_BROADCAST);
			break;

		case PACKET_MULTICAST:
			hdrp->sll_pkttype = htons(LINUX_SLL_MULTICAST);
			break;

		case PACKET_OTHERHOST:
			hdrp->sll_pkttype = htons(LINUX_SLL_OTHERHOST);
			break;

		case PACKET_OUTGOING:
			hdrp->sll_pkttype = htons(LINUX_SLL_OUTGOING);
			break;

		default:
			hdrp->sll_pkttype = -1;
			break;
		}

		hdrp->sll_hatype = htons(from.sll_hatype);
		hdrp->sll_halen = htons(from.sll_halen);
		memcpy(hdrp->sll_addr, from.sll_addr,
		    (from.sll_halen > SLL_ADDRLEN) ?
		      SLL_ADDRLEN :
		      from.sll_halen);
		hdrp->sll_protocol = from.sll_protocol;
	}
#endif

	/*
	 * XXX: According to the kernel source we should get the real
	 * packet len if calling recvfrom with MSG_TRUNC set. It does
	 * not seem to work here :(, but it is supported by this code
	 * anyway.
	 * To be honest the code RELIES on that feature so this is really
	 * broken with 2.2.x kernels.
	 * I spend a day to figure out what's going on and I found out
	 * that the following is happening:
	 *
	 * The packet comes from a random interface and the packet_rcv
	 * hook is called with a clone of the packet. That code inserts
	 * the packet into the receive queue of the packet socket.
	 * If a filter is attached to that socket that filter is run
	 * first - and there lies the problem. The default filter always
	 * cuts the packet at the snaplen:
	 *
	 * # tcpdump -d
	 * (000) ret      #68
	 *
	 * So the packet filter cuts down the packet. The recvfrom call
	 * says "hey, it's only 68 bytes, it fits into the buffer" with
	 * the result that we don't get the real packet length. This
	 * is valid at least until kernel 2.2.17pre6.
	 *
	 * We currently handle this by making a copy of the filter
	 * program, fixing all "ret" instructions with non-zero
	 * operands to have an operand of 65535 so that the filter
	 * doesn't truncate the packet, and supplying that modified
	 * filter to the kernel.
	 */

	caplen = packet_len;
	if (caplen > handle->snapshot)
		caplen = handle->snapshot;

	/* Run the packet filter if not using kernel filter */
	if (!handle->md.use_bpf && handle->fcode.bf_insns) {
		if (bpf_filter(handle->fcode.bf_insns, bp,
		                packet_len, caplen) == 0)
		{
			/* rejected by filter */
			return 0;
		}
	}

	/* Fill in our own header data */

	if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) {
		snprintf(handle->errbuf, sizeof(handle->errbuf),
			 "ioctl: %s", pcap_strerror(errno));
		return -1;
	}
	pcap_header.caplen	= caplen;
	pcap_header.len		= packet_len;

	/*
	 * Count the packet.
	 *
	 * Arguably, we should count them before we check the filter,
	 * as on many other platforms "ps_recv" counts packets
	 * handed to the filter rather than packets that passed
	 * the filter, but if filtering is done in the kernel, we
	 * can't get a count of packets that passed the filter,
	 * and that would mean the meaning of "ps_recv" wouldn't
	 * be the same on all Linux systems.
	 *
	 * XXX - it's not the same on all systems in any case;
	 * ideally, we should have a "get the statistics" call
	 * that supplies more counts and indicates which of them
	 * it supplies, so that we supply a count of packets
	 * handed to the filter only on platforms where that
	 * information is available.
	 *
	 * We count them here even if we can get the packet count
	 * from the kernel, as we can only determine at run time
	 * whether we'll be able to get it from the kernel (if
	 * HAVE_TPACKET_STATS isn't defined, we can't get it from
	 * the kernel, but if it is defined, the library might
	 * have been built with a 2.4 or later kernel, but we
	 * might be running on a 2.2[.x] kernel without Alexey
	 * Kuznetzov's turbopacket patches, and thus the kernel
	 * might not be able to supply those statistics).  We
	 * could, I guess, try, when opening the socket, to get
	 * the statistics, and if we can not increment the count
	 * here, but it's not clear that always incrementing
	 * the count is more expensive than always testing a flag
	 * in memory.
	 */
	handle->md.stat.ps_recv++;

	/* Call the user supplied callback function */
	callback(userdata, &pcap_header, bp);

	return 1;
}



#ifdef HAVE_PCAPREADEX
int 
pcap_read_ex(pcap_t *handle, struct pcap_pkthdr **pkt_header, u_char **pkt_data)
{
	/* Check the capture type */
#ifdef REMOTE
	if (handle->rmt_clientside)
	{
		/* We are on an remote capture */
		if (!handle->rmt_capstarted)
		{
			// if the capture has not started yet, please start it
			if (pcap_startcapture_remote(handle) )
				return -1;
			handle->rmt_capstarted= 1;
		}
		return pcap_read_ex_remote(handle, pkt_header, pkt_data);
	}
#endif

	if (handle->sf.rfile==NULL)
	{
		u_char			*bp;
		int			offset;
#ifdef HAVE_PF_PACKET_SOCKETS
		struct sockaddr_ll	from;
		struct sll_header	*hdrp;
#else
		struct sockaddr		from;
#endif
		socklen_t		fromlen;
		int			packet_len, caplen;

#ifdef HAVE_PF_PACKET_SOCKETS
		/*
		 * If this is a cooked device, leave extra room for a
		 * fake packet header.
		 */
		if (handle->md.cooked)
			offset = SLL_HDR_LEN;
		else
			offset = 0;
#else
		/*
		 * This system doesn't have PF_PACKET sockets, so it doesn't
		 * support cooked devices.
		 */
		offset = 0;
#endif

		/* Receive a single packet from the kernel */

		bp = handle->buffer + handle->offset;
		do {
			fromlen = sizeof(from);
			packet_len = recvfrom(
				handle->fd, bp + offset,
				handle->bufsize - offset, MSG_TRUNC,
				(struct sockaddr *) &from, &fromlen);
		} while (packet_len == -1 && errno == EINTR);

		/* Check if an error occured */

		if (packet_len == -1) {
			if (errno == EAGAIN)
				return 0;	/* no packet there */
			else {
				snprintf(handle->errbuf, sizeof(handle->errbuf),
					 "recvfrom: %s", pcap_strerror(errno));
				return -1;
			}
		}

#ifdef HAVE_PF_PACKET_SOCKETS
		/*
		 * If this is from the loopback device, reject outgoing packets;
		 * we'll see the packet as an incoming packet as well, and
		 * we don't want to see it twice.
		 *
		 * We can only do this if we're using PF_PACKET; the address
		 * returned for SOCK_PACKET is a "sockaddr_pkt" which lacks
		 * the relevant packet type information.
		 */
		if (!handle->md.sock_packet &&
			from.sll_ifindex == handle->md.lo_ifindex &&
			from.sll_pkttype == PACKET_OUTGOING)
			return 0;
#endif

#ifdef HAVE_PF_PACKET_SOCKETS
		/*
		 * If this is a cooked device, fill in the fake packet header.
		 */
		if (handle->md.cooked) {
			/*
			 * Add the length of the fake header to the length
			 * of packet data we read.
			 */
			packet_len += SLL_HDR_LEN;

			hdrp = (struct sll_header *)bp;

			/*
			 * Map the PACKET_ value to a LINUX_SLL_ value; we
			 * want the same numerical value to be used in
			 * the link-layer header even if the numerical values
			 * for the PACKET_ #defines change, so that programs
			 * that look at the packet type field will always be
			 * able to handle DLT_LINUX_SLL captures.
			 */
			switch (from.sll_pkttype) {

			case PACKET_HOST:
				hdrp->sll_pkttype = htons(LINUX_SLL_HOST);
				break;

			case PACKET_BROADCAST:
				hdrp->sll_pkttype = htons(LINUX_SLL_BROADCAST);
				break;

			case PACKET_MULTICAST:
				hdrp->sll_pkttype = htons(LINUX_SLL_MULTICAST);
				break;

			case PACKET_OTHERHOST:
				hdrp->sll_pkttype = htons(LINUX_SLL_OTHERHOST);
				break;

			case PACKET_OUTGOING:
				hdrp->sll_pkttype = htons(LINUX_SLL_OUTGOING);
				break;

			default:
				hdrp->sll_pkttype = -1;
				break;
			}

			hdrp->sll_hatype = htons(from.sll_hatype);
			hdrp->sll_halen = htons(from.sll_halen);
			memcpy(hdrp->sll_addr, from.sll_addr,
				(from.sll_halen > SLL_ADDRLEN) ?
				  SLL_ADDRLEN :
				  from.sll_halen);
			hdrp->sll_protocol = from.sll_protocol;
		}
#endif

		/*
		 * XXX: According to the kernel source we should get the real
		 * packet len if calling recvfrom with MSG_TRUNC set. It does
		 * not seem to work here :(, but it is supported by this code
		 * anyway.
		 * To be honest the code RELIES on that feature so this is really
		 * broken with 2.2.x kernels.
		 * I spend a day to figure out what's going on and I found out
		 * that the following is happening:
		 *
		 * The packet comes from a random interface and the packet_rcv
		 * hook is called with a clone of the packet. That code inserts
		 * the packet into the receive queue of the packet socket.
		 * If a filter is attached to that socket that filter is run
		 * first - and there lies the problem. The default filter always
		 * cuts the packet at the snaplen:
		 *
		 * # tcpdump -d
		 * (000) ret      #68
		 *
		 * So the packet filter cuts down the packet. The recvfrom call
		 * says "hey, it's only 68 bytes, it fits into the buffer" with
		 * the result that we don't get the real packet length. This
		 * is valid at least until kernel 2.2.17pre6.
		 *
		 * We currently handle this by making a copy of the filter
		 * program, fixing all "ret" instructions with non-zero
		 * operands to have an operand of 65535 so that the filter
		 * doesn't truncate the packet, and supplying that modified
		 * filter to the kernel.
		 */

		caplen = packet_len;
		if (caplen > handle->snapshot)
			caplen = handle->snapshot;

		/* Run the packet filter if not using kernel filter */
		if (!handle->md.use_bpf && handle->fcode.bf_insns) {
			if (bpf_filter(handle->fcode.bf_insns, bp,
							packet_len, caplen) == 0)
			{
				/* rejected by filter */
				return 0;
			}
		}

		/* Fill in our own header data */

		if (ioctl(handle->fd, SIOCGSTAMP, &(handle->pcap_header.ts)) == -1) {
			snprintf(handle->errbuf, sizeof(handle->errbuf),
				 "ioctl: %s", pcap_strerror(errno));
			return -1;
		}
		handle->pcap_header.caplen	= caplen;
		handle->pcap_header.len		= packet_len;

		/*
		 * Count the packet.
		 *
		 * Arguably, we should count them before we check the filter,
		 * as on many other platforms "ps_recv" counts packets
		 * handed to the filter rather than packets that passed
		 * the filter, but if filtering is done in the kernel, we
		 * can't get a count of packets that passed the filter,
		 * and that would mean the meaning of "ps_recv" wouldn't
		 * be the same on all Linux systems.
		 *
		 * XXX - it's not the same on all systems in any case;
		 * ideally, we should have a "get the statistics" call
		 * that supplies more counts and indicates which of them
		 * it supplies, so that we supply a count of packets
		 * handed to the filter only on platforms where that
		 * information is available.

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
激情伊人五月天久久综合| 亚洲第一综合色| 日韩视频一区二区三区| 欧美日韩国产综合一区二区| 色婷婷av一区| 欧美日韩免费一区二区三区视频| 91网站在线播放| 91久久精品网| 欧美日韩国产在线观看| 欧美乱熟臀69xxxxxx| 91精品国产欧美一区二区| 6080亚洲精品一区二区| 日韩视频一区在线观看| 久久综合九色综合欧美98 | 91色porny| 欧美性视频一区二区三区| 欧美亚洲一区二区在线| 91精品国产综合久久久蜜臀图片| 欧美大片在线观看| 欧美极品aⅴ影院| 一区二区三区小说| 日韩精品免费专区| 国产一区二区在线影院| 成人av网站免费观看| 在线观看一区不卡| 日韩一区二区三区精品视频| 欧美精品一区二区三区四区 | 国产一区二区三区在线看麻豆| 国产一区二区三区蝌蚪| 91看片淫黄大片一级在线观看| 欧美亚洲丝袜传媒另类| 久久婷婷国产综合精品青草| 亚洲欧美另类久久久精品| 亚洲国产毛片aaaaa无费看 | 欧美草草影院在线视频| 中文字幕乱码一区二区免费| 亚洲午夜电影在线观看| 国产一区欧美二区| 欧洲av在线精品| 久久蜜臀精品av| 午夜av区久久| 99久久久免费精品国产一区二区| 日韩一区二区影院| 一区二区三区四区在线播放| 另类欧美日韩国产在线| 日本伦理一区二区| 久久午夜色播影院免费高清 | 久久综合狠狠综合| 亚洲动漫第一页| 成人激情开心网| 日韩一区二区在线观看视频 | 日韩二区在线观看| 成人av电影在线观看| 精品国产乱码久久久久久闺蜜 | 国产一二精品视频| 欧美剧情片在线观看| 亚洲人成人一区二区在线观看| 久久福利资源站| 欧美久久久久免费| 亚洲在线观看免费| 91丨九色porny丨蝌蚪| 久久久99久久| 久久97超碰国产精品超碰| 欧美丝袜丝交足nylons图片| 18欧美亚洲精品| 成人黄色一级视频| 中文字幕欧美日韩一区| 国产成人精品影院| 国产亚洲欧美激情| 国内精品伊人久久久久av一坑| 欧美一区二区三区播放老司机| 亚洲午夜精品网| 欧美探花视频资源| 午夜精品福利视频网站| 欧美性做爰猛烈叫床潮| 一片黄亚洲嫩模| 色老汉一区二区三区| 一区二区三区四区乱视频| 色丁香久综合在线久综合在线观看| 国产精品美女久久久久久2018 | 亚洲精品欧美激情| 久久久精品免费网站| 日韩电影在线观看网站| 91在线国内视频| 91丨九色丨蝌蚪富婆spa| 精品在线一区二区| 国产成人av电影在线观看| 亚洲一本大道在线| 中文在线资源观看网站视频免费不卡| 欧美私人免费视频| 91视频观看视频| 国产高清久久久| 久久99蜜桃精品| 日本一不卡视频| 一区二区三区美女视频| 国产精品午夜电影| 26uuu另类欧美| 日韩午夜电影在线观看| 欧美日本一区二区在线观看| 色天天综合色天天久久| caoporn国产一区二区| 国产久卡久卡久卡久卡视频精品| 日韩成人一区二区三区在线观看| 一区二区三区在线视频观看58| 国产精品视频观看| 国产欧美日韩三级| 久久女同性恋中文字幕| 欧美精品一区二区三区蜜桃 | 五月天亚洲精品| 亚洲国产日日夜夜| 亚洲一区二区三区影院| 一级日本不卡的影视| 亚洲精品日韩一| 一区二区三区日韩欧美| 一级日本不卡的影视| 一区二区成人在线| 亚洲成人免费在线| 青青国产91久久久久久| 日本少妇一区二区| 蜜桃精品在线观看| 激情综合色综合久久| 激情深爱一区二区| 国产激情一区二区三区| 成人美女视频在线观看| 成人精品一区二区三区四区| 99国产欧美另类久久久精品| 91色视频在线| 欧美精品一二三区| 欧美大尺度电影在线| 久久精品日产第一区二区三区高清版| 久久久久久久久久久电影| 中文字幕久久午夜不卡| 亚洲精品视频免费观看| 亚洲成va人在线观看| 麻豆精品一区二区三区| 国产一区二区精品久久| caoporen国产精品视频| 欧洲精品在线观看| 欧美一卡二卡在线| 国产精品美女一区二区三区| 亚洲综合色网站| 美女任你摸久久| 不卡欧美aaaaa| 欧美伦理视频网站| 久久综合色综合88| 亚洲日本护士毛茸茸| 日韩精品免费专区| 懂色av一区二区三区免费观看| 91免费国产在线| 日韩亚洲欧美高清| 国产精品国产精品国产专区不片| 亚洲国产一二三| 国产一区二区免费在线| 色噜噜狠狠色综合欧洲selulu| 欧美成人a在线| 亚洲精品videosex极品| 国内精品久久久久影院色| 99精品视频在线观看| 欧美本精品男人aⅴ天堂| 成人欧美一区二区三区白人 | 日韩午夜激情av| 中文字幕日韩一区二区| 日本成人在线看| 91亚洲精品久久久蜜桃网站| 欧美大片一区二区三区| 亚洲黄色片在线观看| 国产精品一卡二| 8v天堂国产在线一区二区| 综合精品久久久| 国产在线视频一区二区| 欧美色老头old∨ideo| 国产精品久久久久三级| 蜜臀久久久99精品久久久久久| 色综合色综合色综合| 国产亚洲精品aa| 免费观看在线色综合| 欧美日韩精品综合在线| 成人欧美一区二区三区白人| 国产一区二区福利视频| 在线播放中文一区| 玉米视频成人免费看| 成人午夜精品一区二区三区| 欧美成人性福生活免费看| 天堂va蜜桃一区二区三区| 色老汉av一区二区三区| 中文字幕一区二区三区在线观看| 国产乱淫av一区二区三区| 精品少妇一区二区三区在线视频| 亚洲国产一二三| 欧美视频中文字幕| 亚洲激情av在线| 欧美性xxxxxxxx| 亚洲综合免费观看高清完整版 | 欧美一区三区二区| 丝袜美腿高跟呻吟高潮一区| 在线精品亚洲一区二区不卡| 一区二区三区中文在线观看| 日本韩国欧美在线| 亚洲一区二区在线免费观看视频| 91国内精品野花午夜精品|