[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-bridge
Subject:    Re: [Bridge] Bridging between user processes - TAP question
From:       Stephen Hemminger <shemminger () osdl ! org>
Date:       2004-06-17 22:52:05
Message-ID: 20040617155205.38b9dbff () dell_ss3 ! pdx ! osdl ! net
[Download RAW message or body]

Do either of these help?  I used them about a year ago when updating
tun and tap to new netdevice model.


["taptest.c" (text/plain)]

/* Simple program to listen to /dev/tap0 and reply to pings. */
#include <fcntl.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#if defined(__GLIBC__) && (__GLIBC__ == 2)
#include <netinet/tcp.h>
#include <netinet/udp.h>
#else
#include <linux/tcp.h>
#include <linux/udp.h>
#endif
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>

u_int16_t csum_partial(void *buffer, unsigned int len, u_int16_t prevsum)
{
	u_int32_t sum = 0;
	u_int16_t *ptr = buffer;

	while (len > 1)  {
		sum += *ptr++;
		len -= 2;
	}
	if (len) {
		union {
			u_int8_t byte;
			u_int16_t wyde;
		} odd;
		odd.wyde = 0;
		odd.byte = *((u_int8_t *)ptr);
		sum += odd.wyde;
	}
	sum = (sum >> 16) + (sum & 0xFFFF);
	sum += prevsum;
	return (sum + (sum >> 16));
}

int main()
{
	int fd, len;
	union {
		struct {
			char etherhdr[16];
			struct iphdr ip;
		} fmt;
		unsigned char raw[65536];
	} u;

	fd = open("/dev/tap0", O_RDWR);
	if (fd < 0) {
		perror("Opening `/dev/tap0'");
		return 1;
	}

	/* u.fmt.ip.ihl in host order!  Film at 11. */
	while ((len = read(fd, &u, sizeof(u))) > 0) {
		u_int32_t tmp;
 		struct icmphdr *icmp
			= (void *)((u_int32_t *)&u.fmt.ip + u.fmt.ip.ihl );
		struct tcphdr *tcp = (void *)icmp;
		struct udphdr *udp = (void *)icmp;
		
		fprintf(stderr, "SRC = %u.%u.%u.%u DST = %u.%u.%u.%u\n",
			(ntohl(u.fmt.ip.saddr) >> 24) & 0xFF,
			(ntohl(u.fmt.ip.saddr) >> 16) & 0xFF,
			(ntohl(u.fmt.ip.saddr) >> 8) & 0xFF,
			(ntohl(u.fmt.ip.saddr) >> 0) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 24) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 16) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 8) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 0) & 0xFF);

		switch (u.fmt.ip.protocol) {
		case IPPROTO_ICMP:
			if (icmp->type == ICMP_ECHO) {
				fprintf(stderr, "PONG! (iphdr = %u bytes)\n",
					(unsigned int)((char *)icmp
						       - (char *)&u.fmt.ip));

				/* Turn it around */
				tmp = u.fmt.ip.saddr;
				u.fmt.ip.saddr = u.fmt.ip.daddr;
				u.fmt.ip.daddr = tmp;

				icmp->type = ICMP_ECHOREPLY;
				icmp->checksum = 0;
				icmp->checksum
					= ~csum_partial(icmp,
							ntohs(u.fmt.ip.tot_len)
							- u.fmt.ip.ihl*4, 0);

				{
					unsigned int i;
					for (i = 44;
					     i < ntohs(u.fmt.ip.tot_len); i++){
						printf("%u:0x%02X ", i,
						       ((unsigned char *)
							&u.fmt.ip)[i]);
					}
					printf("\n");
				}
				write(fd, &u, len);
			}
			break;
		case IPPROTO_TCP:
			fprintf(stderr, "TCP: %u -> %u\n", ntohs(tcp->source),
				ntohs(tcp->dest));
			break;

		case IPPROTO_UDP:
			fprintf(stderr, "UDP: %u -> %u\n", ntohs(udp->source),
				ntohs(udp->dest));
			break;
		}
	}
	if (len < 0)
		perror("Reading from `/dev/tap0'");
	else fprintf(stderr, "Empty read from `/dev/tap0'");
	return len < 0 ? 1 : 0;
}
			

["taptest.c" (application/octet-stream)]

/* Simple program to listen to /dev/tap0 and reply to pings. */
#include <fcntl.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#if defined(__GLIBC__) && (__GLIBC__ == 2)
#include <netinet/tcp.h>
#include <netinet/udp.h>
#else
#include <linux/tcp.h>
#include <linux/udp.h>
#endif
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>

u_int16_t csum_partial(void *buffer, unsigned int len, u_int16_t prevsum)
{
	u_int32_t sum = 0;
	u_int16_t *ptr = buffer;

	while (len > 1)  {
		sum += *ptr++;
		len -= 2;
	}
	if (len) {
		union {
			u_int8_t byte;
			u_int16_t wyde;
		} odd;
		odd.wyde = 0;
		odd.byte = *((u_int8_t *)ptr);
		sum += odd.wyde;
	}
	sum = (sum >> 16) + (sum & 0xFFFF);
	sum += prevsum;
	return (sum + (sum >> 16));
}

int main()
{
	int fd, len;
	union {
		struct {
			char etherhdr[16];
			struct iphdr ip;
		} fmt;
		unsigned char raw[65536];
	} u;

	fd = open("/dev/tap0", O_RDWR);
	if (fd < 0) {
		perror("Opening `/dev/tap0'");
		return 1;
	}

	/* u.fmt.ip.ihl in host order!  Film at 11. */
	while ((len = read(fd, &u, sizeof(u))) > 0) {
		u_int32_t tmp;
 		struct icmphdr *icmp
			= (void *)((u_int32_t *)&u.fmt.ip + u.fmt.ip.ihl );
		struct tcphdr *tcp = (void *)icmp;
		struct udphdr *udp = (void *)icmp;
		
		fprintf(stderr, "SRC = %u.%u.%u.%u DST = %u.%u.%u.%u\n",
			(ntohl(u.fmt.ip.saddr) >> 24) & 0xFF,
			(ntohl(u.fmt.ip.saddr) >> 16) & 0xFF,
			(ntohl(u.fmt.ip.saddr) >> 8) & 0xFF,
			(ntohl(u.fmt.ip.saddr) >> 0) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 24) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 16) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 8) & 0xFF,
			(ntohl(u.fmt.ip.daddr) >> 0) & 0xFF);

		switch (u.fmt.ip.protocol) {
		case IPPROTO_ICMP:
			if (icmp->type == ICMP_ECHO) {
				fprintf(stderr, "PONG! (iphdr = %u bytes)\n",
					(unsigned int)((char *)icmp
						       - (char *)&u.fmt.ip));

				/* Turn it around */
				tmp = u.fmt.ip.saddr;
				u.fmt.ip.saddr = u.fmt.ip.daddr;
				u.fmt.ip.daddr = tmp;

				icmp->type = ICMP_ECHOREPLY;
				icmp->checksum = 0;
				icmp->checksum
					= ~csum_partial(icmp,
							ntohs(u.fmt.ip.tot_len)
							- u.fmt.ip.ihl*4, 0);

				{
					unsigned int i;
					for (i = 44;
					     i < ntohs(u.fmt.ip.tot_len); i++){
						printf("%u:0x%02X ", i,
						       ((unsigned char *)
							&u.fmt.ip)[i]);
					}
					printf("\n");
				}
				write(fd, &u, len);
			}
			break;
		case IPPROTO_TCP:
			fprintf(stderr, "TCP: %u -> %u\n", ntohs(tcp->source),
				ntohs(tcp->dest));
			break;

		case IPPROTO_UDP:
			fprintf(stderr, "UDP: %u -> %u\n", ntohs(udp->source),
				ntohs(udp->dest));
			break;
		}
	}
	if (len < 0)
		perror("Reading from `/dev/tap0'");
	else fprintf(stderr, "Empty read from `/dev/tap0'");
	return len < 0 ? 1 : 0;
}
			


_______________________________________________
Bridge mailing list
Bridge@lists.osdl.org
http://lists.osdl.org/mailman/listinfo/bridge


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic