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

📄 test.c

📁 实现一个网卡到内存空间的零拷贝程序
💻 C
字号:
/*  *  Test application for the 'rawtx' device driver. *  Joris van Rantwijk, May 2001. * *  Transmit a series of UDP datagrams. *  The first datagram and the last four datagrams have length 4, *  to be compatible with the ttcp performance measurement tool. */#include <stdio.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <netinet/in.h>#include <arpa/inet.h>#include <net/ethernet.h>#include "rawtx.h"/* Payload length in bytes */#define DATA_LEN	1400/* Number of datagrams to transmit */#define COUNT		10000#define ETHER_ADDR_FORMAT "%02X:%02X:%02X:%02X:%02X:%02X"#define ETHER_ADDR_DATA(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]#define TO_PORT		5001#define FROM_PORT	5000#define QLEN		4#ifdef cllf#define TO_IP		"192.168.2.1"#define FROM_IP		"192.168.2.2"#define TO_ETHER	{ 0x00, 0x50, 0x04, 0xD0, 0x03, 0x40 }#define	NET_DEVICE	"eth1"#define RAWTX_DEVICE	"/tmp/rawtx"#else#define TO_IP		"192.16.199.38"#define FROM_IP		"192.16.199.42"#define TO_ETHER	{ 0x00, 0x50, 0x04, 0x63, 0xDB, 0xEF }#define NET_DEVICE	"eth0"#define RAWTX_DEVICE	"/user/jorisvr/jstage/rawtx"#endif// #define FROM_ETHER	{ 0x00, 0x01, 0x02, 0x08, 0xA6, 0xF2 }static int rawtx_fd;void init_rawtx(void){//	unsigned char sether[6] = FROM_ETHER;	unsigned char dether[6] = TO_ETHER;	struct sockaddr_in addr;	printf("Opening rawtx device...\n");	rawtx_fd = open(RAWTX_DEVICE, O_RDWR);	if (rawtx_fd < 0) {		perror("open");		exit(1);	}	printf("Setting device %s...\n", NET_DEVICE);	if (ioctl(rawtx_fd, RAWTX_IOCTL_SETDEVICE, NET_DEVICE) < 0) {		perror("ioctl setdevice");		exit(1);	}	printf("Setting protocol to UDP/IP-NOSUM...\n");	if (ioctl(rawtx_fd, RAWTX_IOCTL_SETPROTO, RAWTX_PROTO_UDPIP_NOSUM) < 0) {		perror("ioctl setproto");		exit(1);	}	printf("Setting destination address " ETHER_ADDR_FORMAT "...\n",	       ETHER_ADDR_DATA(dether));	if (ioctl(rawtx_fd, RAWTX_IOCTL_SETDADDR, &dether) < 0) {		perror("ioctl setdaddr");		exit(1);	}	printf("Setting source address %s:%d...\n", FROM_IP, FROM_PORT);	addr.sin_family = AF_INET;	addr.sin_port = htons(FROM_PORT);	inet_aton(FROM_IP, &addr.sin_addr);	if (ioctl(rawtx_fd, RAWTX_IOCTL_SETSRCADDR, &addr) < 0) {		perror("ioctl setsrcaddr");		exit(1);	}	printf("Setting destination address %s:%d...\n", TO_IP, TO_PORT);	addr.sin_family = AF_INET;	addr.sin_port = htons(TO_PORT);	inet_aton(TO_IP, &addr.sin_addr);	if (ioctl(rawtx_fd, RAWTX_IOCTL_SETDSTADDR, &addr) < 0) {		perror("ioctl setdstaddr");		exit(1);	}	printf("Setting queue length %d...\n", QLEN);	if (ioctl(rawtx_fd, RAWTX_IOCTL_SETQUEUELEN, QLEN) < 0) {		perror("ioctl setqueuelen");		exit(1);	}}/* *  Test the mmap mechanism of the rawtx driver. */void test_mmap_method(void){#undef NEXTBUF#define NEXTBUF ((void) ( bufofs = 2048 * bufidx, \                          bufidx = (bufidx+1) % 8, \                          buf = (struct rawtx_buffer *) (dbuffer + bufofs), \                          buf->header_len = ETH_HLEN + RAWTX_UDP_IP_HEADER_LEN ))	unsigned char *dbuffer;		/* Buffer pool */	static int bufidx = 0;		/* Which buffer to use next */	unsigned int bufofs;		/* Current buffer offset */	struct rawtx_buffer *buf;	/* Current buffer */	int i, err;	printf("Testing mmap method...\n");	printf("Mapping buffer pool...\n");	dbuffer = mmap(NULL, RAWTX_DBUFFER_MAX_SIZE, PROT_READ|PROT_WRITE,	               MAP_SHARED, rawtx_fd, 0);	if (dbuffer == MAP_FAILED) {		perror("mmap");		exit(1);	}	printf("Sending %d (+ 5) packets ...\n", COUNT);	/* Tell ttcp to start the timer. */	NEXTBUF;	buf->data_len = 4;	err = ioctl(rawtx_fd, RAWTX_IOCTL_SENDBUFFER, bufofs);	if (err > 0) fprintf(stderr, "Packet drop!!\n");	else if (err < 0) perror("ioctl sendbuffer");	for (i = 0; i < COUNT; i++) {		NEXTBUF;		*(unsigned int *)(buf->buffer + buf->header_len) = i;		strcpy(buf->buffer + buf->header_len + 8, "...Hallo allemaal hier");		buf->data_len = DATA_LEN;		err = ioctl(rawtx_fd, RAWTX_IOCTL_SENDBUFFER, bufofs);		if (err > 0) fprintf(stderr, "Packet drop!!\n");		else if (err < 0) perror("write");	}	/* Tell ttcp that we're done. */	for (i = 0; i < 4; i++) {		NEXTBUF;		buf->data_len = 4;		err = ioctl(rawtx_fd, RAWTX_IOCTL_SENDBUFFER, bufofs);		if (err > 0) fprintf(stderr, "Packet drop!!\n");		else if (err < 0) perror("ioctl sendbuffer");	}}/* *  Test the kiobuf mechanism of the rawtx driver. */void test_kiobuf_method(void){#undef NEXTBUF#define NEXTBUF ((void) (buf = bufpool[bufidx], bufidx = (bufidx+1) % 8))	unsigned char bufpool[8][10240];	/* 8 buffers of 10k each */	static int bufidx = 0;			/* Which buffer to use next */	unsigned char *buf;			/* Current buffer */	int i, err;	printf("Testing kiobuf method...\n");	printf("Sending %d (+ 5) packets...\n", COUNT);	/* Tell ttcp to start the timer. */	NEXTBUF;	err = write(rawtx_fd, buf, 4);	if (err == 0) fprintf(stderr, "Packet drop!!\n");	else if (err < 0) perror("write");	for (i = 0; i < COUNT; i++) {		NEXTBUF;		*(unsigned int *)buf = i;		strcpy(buf + 8, "...Hallo allemaal hier");		err = write(rawtx_fd, buf, DATA_LEN);		if (err == 0) fprintf(stderr, "Packet drop!!\n");		else if (err < 0) perror("write");	}	/* Tell ttcp that we're done. */	for (i = 0; i < 4; i++) {		NEXTBUF;		err = write(rawtx_fd, buf, 4);		if (err == 0) fprintf(stderr, "Packet drop!!\n");		else if (err < 0) perror("write");	}}int main(void){	init_rawtx();//	test_mmap_method();	test_kiobuf_method();	close(rawtx_fd);	return 0;}

⌨️ 快捷键说明

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