⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sniff.c

📁 实现linux平台下零拷贝技术的软件包。
💻 C
字号:
/* * 	sniff.c *  * 2006 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> * All rights reserved. *  * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <sys/poll.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <fcntl.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <ctype.h>#include <net/ethernet.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <arpa/inet.h>#include "include/linux/types.h"#include "net/core/alloc/avl.h"#include "control.h"static void zc_usage(char *p){	fprintf(stderr, "Usage: %s -f sniffer_file -c nr_cpus -h\n", p);}static void zc_analyze_write(int out_fd, void *ptr, unsigned int size){	int err;	err = write(out_fd, ptr, size);	if (err != (signed)size) {		fprintf(stderr, "Failed to write %u bytes: %s [%d].\n",				size, strerror(errno), errno);		return;	}}#define NIPE(eth) \	(eth)->ether_shost[0], \	(eth)->ether_shost[1], \	(eth)->ether_shost[2], \	(eth)->ether_shost[3], \	(eth)->ether_shost[4], \	(eth)->ether_shost[5], \	(eth)->ether_dhost[0], \	(eth)->ether_dhost[1], \	(eth)->ether_dhost[2], \	(eth)->ether_dhost[3], \	(eth)->ether_dhost[4], \	(eth)->ether_dhost[5]#define NIPQUAD(addr) \	((unsigned char *)&addr)[0], \	((unsigned char *)&addr)[1], \	((unsigned char *)&addr)[2], \	((unsigned char *)&addr)[3]static void zc_analyze(int out_fd, void *ptr, unsigned int size){	struct ether_header *eth;	struct iphdr *iph;	struct tcphdr *th;	unsigned char *p = ptr;	__u16 sport, dport;	eth = ptr + 18;#if 0	printf("%02x:%02x:%02x:%02x:%02x:%02x -> %02x:%02x:%02x:%02x:%02x:%02x, type: %04x, ",			NIPE(eth), ntohs(eth->ether_type));#endif	if (eth->ether_type == 0xabab) {		eth = ptr + 190;#if 0		unsigned int i;		p = ptr + 180;		for (i=0; i<32; ++i)			printf("%02x ", p[i]);		printf("\n");		goto out_exit;#endif	}	if (eth->ether_type != ntohs(ETHERTYPE_IP))		goto out_exit;	iph = (struct iphdr *)(eth + 1);	sport = ((__u16 *)(((void *)iph) + (iph->ihl<<2)))[0];	dport = ((__u16 *)(((void *)iph) + (iph->ihl<<2)))[1];		if (iph->protocol != IPPROTO_TCP)		goto out_exit;#if 1	printf("%u.%u.%u.%u:%u -> %u.%u.%u.%u:%u, proto: %u, ",			NIPQUAD(iph->saddr), ntohs(sport), 			NIPQUAD(iph->daddr), ntohs(dport), iph->protocol);#endif	th = (struct tcphdr *)(((void *)iph) + (iph->ihl<<2));	printf("seq: %u, ack: %u, ", ntohl(th->seq), ntohl(th->ack_seq));	printf("\n");out_exit:	return;}int main(int argc, char *argv[]){	int ch, err, out_fd;	unsigned int i, num, nr_cpus;	char *ctl_file, *out_file;	struct zc_data zcb[1024];	struct pollfd *pfd;	struct zc_control *zc_ctl, *ctl;	ctl_file = out_file = NULL;	nr_cpus = 2;	while ((ch = getopt(argc, argv, "f:o:c:h")) != -1) {		switch (ch) {			case 'c':				nr_cpus = atoi(optarg);				break;			case 'o':				out_file = optarg;				break;			case 'f':				ctl_file = optarg;				break;			case 'h':			default:				zc_usage(argv[0]);				return 0;		}	}	if (nr_cpus > 1024) {		fprintf(stderr, "Wrong number of CPUs %d.\n", nr_cpus);		zc_usage(argv[0]);		return -1;	}	if (!ctl_file || !out_file) {		fprintf(stderr, "You must call %s with -f and -o parameters.\n", argv[0]);		zc_usage(argv[0]);		return -1;	}	out_fd = open(out_file, O_RDWR | O_CREAT | O_TRUNC, 0644);	if (!out_fd) {		fprintf(stderr, "Failed to open output file %s: %s [%d].\n", out_file, strerror(errno), errno);		return -1;	}	pfd = malloc(sizeof(struct pollfd) * nr_cpus);	if (!pfd) {		fprintf(stderr, "Failed to allocate polling structures for %d cpus.\n", nr_cpus);		return -ENOMEM;	}	memset(pfd, 0, sizeof(struct pollfd) * nr_cpus);	zc_ctl = zc_ctl_init(nr_cpus, ctl_file);	if (!zc_ctl)		return -1;		for (i=0; i<nr_cpus; ++i) {		pfd[i].fd = zc_ctl[i].fd;		pfd[i].events = POLLIN;		pfd[i].revents = 0;	}	while (1) {		int poll_ready, j;		poll_ready = poll(pfd, nr_cpus, 1000);		if (poll_ready == 0)			continue;		if (poll_ready < 0)			break;		for (j=0; j<poll_ready; ++j) {			if ((!pfd[j].revents & POLLIN))				continue;			pfd[j].events = POLLIN;			pfd[j].revents = 0;			err = read(zc_ctl[0].fd, zcb, sizeof(zcb));			if (err <= 0) {				fprintf(stderr, "Failed to read data from control file %s: %s [%d].\n", 						ctl_file, strerror(errno), errno);				break;			}			num = err/sizeof(struct zc_data);			for (i=0; i<num; ++i) {				struct zc_data *z;				void *ptr;				struct zc_data *e;				z = &zcb[i];				if (z->entry >= ZC_MAX_ENTRY_NUM || z->cpu >= nr_cpus)					continue;				ctl = &zc_ctl[z->cpu];				if (zc_prepare(ctl, z->entry))					continue;				e = &ctl->e[z->entry];#if 0				printf("dump %4d.%4d: ptr: %p, start: %p, size: %u, off: %u: entry: %u, cpu: %d: ", 					i, num, z->data.ptr, z->start.ptr, z->size, z->off, z->entry, z->cpu);#endif				ptr = e->data.ptr + z->off;				zc_analyze_write(out_fd, ptr, z->size);				//zc_analyze(out_fd, ptr, z->size);			}						err = write(zc_ctl[0].fd, zcb, num*sizeof(struct zc_data));			if (err < 0) {				fprintf(stderr, "Failed to write data to control file %s: %s [%d].\n", 						ctl_file, strerror(errno), errno);				break;			} else if (err == 0) {				write(zc_ctl[0].fd, zcb, num*sizeof(struct zc_data));			}		}	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -