All of lore.kernel.org
 help / color / mirror / Atom feed
* [Bridge] Bridging between user processes
@ 2004-06-16  4:04 Derek Smalls
  0 siblings, 0 replies; 6+ messages in thread
From: Derek Smalls @ 2004-06-16  4:04 UTC (permalink / raw)
  To: bridge

Hi, 

What is the easiest way to bridge between two
user-space processes that talk directly to Ethernet
interfaces? 

I have two applications that write/read Ethernet
frames to/from Linux Ethernet ports (e.g. eth0). The
applications can successfully talk to each other when
they run on two machines connected over Ethernet. I
would like to be able to test them on a single machine
without employing the physical network. Would TAP +
bridging do the job? 

If so, what am I doing wrong?  Linux 2.4.20, root
user. I set up tap interfaces like this: 

>tunctl tap4 
>ifconfig tap4 4.4.4.4 promisc up 
>tunctl tap5 
>ifconfig tap5 5.5.5.5 promisc up 

I then set up the bridge and add the tap interfaces to
it: 

>brctl addbr tapbr 
>brctl setfd tapbr 0 
>brctl sethello tapbr 0 
>brctl stp tapbr off 
>ifconfig tapbr 7.7.7.7 netmask 255.255.255.0 up
>brctl addif tapbr tap4 
>brctl addif tapbr tap5 

I then do a ping over tap4: 
>ping -I tap4 8.8.8.8 

and tcpdump on tap5: 
>tcpdump -i tap5 

and see nothing. Shouldn't I see the ping requests on
tap5 now? 

BTW, if I enable STP on the bridge I start seeing the
STP frames on tap5. 

Thanks! 

Derek 




		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bridge] Bridging between user processes
       [not found] <40D08A26.1040907@tuxdriver.com>
@ 2004-06-16 22:12 ` Derek Smalls
  0 siblings, 0 replies; 6+ messages in thread
From: Derek Smalls @ 2004-06-16 22:12 UTC (permalink / raw)
  To: bridge

Thanks for the response!

Running the application produces the same result (no
result actually) as ping -I. Looks like tcpdump can
see the tap  interfaces: tcpdump on tap4 can see
outgoing pings sent out on tap4. Moreover, I can send
pings through the bridge and tcpdump on tap4 picks
them up. 

I guess in order to bridge between taps I really do
need a separate utility that would copy frames between
/dev/tap4 and /dev/tap5 .  

--- "John W. Linville" <linville@tuxdriver.com> wrote:
> Derek Smalls wrote:
> 
> > I then do a ping over tap4: 
> > 
> >>ping -I tap4 8.8.8.8 
> 
> > and tcpdump on tap5: 
> > 
> >>tcpdump -i tap5 
> 
> > and see nothing. Shouldn't I see the ping requests
> on
> > tap5 now? 
> 
> My guess is that your `ping -I` is completely
> bypassing the bridging 
> code.  I haven't looked at it lately, but I'd guess
> that the bridging 
> functionality is geared toward receiving frames on
> the "slave" interface 
> and transmitting frames through the "master"
> interface.  You example is 
> transmitting on the "slave" interface (to use my
> terminology).
> 
> A better test would be to setup your bridge, then
> start the application 
> you mentioned on the transmitting side and monitor
> the other side for 
> traffic (probably with another instance of your
> application).
> 
> BTW, I don't think tcpdump will be useful.  You'll
> need something that 
> is "tap-aware".
> 
> Good luck!
> 
> John
> 



		
__________________________________
Do you Yahoo!?
Take Yahoo! Mail with you! Get it on your mobile phone.
http://mobile.yahoo.com/maildemo 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [Bridge] Bridging between user processes
       [not found] <C060DFCD9697A842B3189B458524FDC205D2D3@AIMAIL1.ai.aiinet.com>
@ 2004-06-16 22:17 ` Derek Smalls
  2004-06-17  4:34   ` Michael Renzmann
  0 siblings, 1 reply; 6+ messages in thread
From: Derek Smalls @ 2004-06-16 22:17 UTC (permalink / raw)
  To: bridge

Thanks! I was afraid this was the reason ... :(

I actually tried writing an application that would
open /dev/tap4 as a file and do a select() on it. The
select() timed out when I tried pinging over the
bridge, but I guess I'll have to go back and debug it,
I must have missed something. 


--- "Eble, Dan" <DanE@aiinet.com> wrote:
> The bridge is designed to do the opposite of what
> you are trying to do.  It
> takes incoming frames and copies them out other
> interfaces.  You want to
> take outgoing frames and copy them into other
> interfaces.
> 
> I have not played with tun/tap myself, but the
> kernel documentation in
> Documentation/networking/tuntap.txt seems to
> indicate that you need a
> program to listen on two opened /dev/net/tun devices
> and copy the frames
> from one to the other.
> 
> > -----Original Message-----
> > From: Derek Smalls [mailto:dsmalls321@yahoo.com] 
> > Sent: Wednesday, June 16, 2004 12:04 AM
> > To: bridge@lists.osdl.org
> > Subject: [Bridge] Bridging between user processes 
> > 
> > 
> > Hi, 
> > 
> > What is the easiest way to bridge between two
> > user-space processes that talk directly to
> Ethernet
> > interfaces? 
> > 
> > I have two applications that write/read Ethernet
> > frames to/from Linux Ethernet ports (e.g. eth0).
> The
> > applications can successfully talk to each other
> when
> > they run on two machines connected over Ethernet.
> I
> > would like to be able to test them on a single
> machine
> > without employing the physical network. Would TAP
> +
> > bridging do the job? 
> > 
> > If so, what am I doing wrong?  Linux 2.4.20, root
> > user. I set up tap interfaces like this: 
> > 
> > >tunctl tap4 
> > >ifconfig tap4 4.4.4.4 promisc up 
> > >tunctl tap5 
> > >ifconfig tap5 5.5.5.5 promisc up 
> > 
> > I then set up the bridge and add the tap
> interfaces to
> > it: 
> > 
> > >brctl addbr tapbr 
> > >brctl setfd tapbr 0 
> > >brctl sethello tapbr 0 
> > >brctl stp tapbr off 
> > >ifconfig tapbr 7.7.7.7 netmask 255.255.255.0 up
> > >brctl addif tapbr tap4 
> > >brctl addif tapbr tap5 
> > 
> > I then do a ping over tap4: 
> > >ping -I tap4 8.8.8.8 
> > 
> > and tcpdump on tap5: 
> > >tcpdump -i tap5 
> > 
> > and see nothing. Shouldn't I see the ping requests
> on
> > tap5 now? 
> > 
> > BTW, if I enable STP on the bridge I start seeing
> the
> > STP frames on tap5. 
> > 
> > Thanks! 
> > 
> > Derek 
> > 
> > 
> > 
> > 
> > 		
> > __________________________________
> > Do you Yahoo!?
> > New and Improved Yahoo! Mail - Send 10MB messages!
> > http://promotions.yahoo.com/new_mail 
> > 
> 


=====



		
__________________________________
Do you Yahoo!?
Yahoo! Mail is new and improved - Check it out!
http://promotions.yahoo.com/new_mail

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bridge] Bridging between user processes
  2004-06-16 22:17 ` [Bridge] Bridging between user processes Derek Smalls
@ 2004-06-17  4:34   ` Michael Renzmann
  2004-06-17 22:29     ` [Bridge] Bridging between user processes - TAP question Derek Smalls
  0 siblings, 1 reply; 6+ messages in thread
From: Michael Renzmann @ 2004-06-17  4:34 UTC (permalink / raw)
  To: Derek Smalls; +Cc: bridge

Hi.

Derek Smalls wrote:
 >>I have not played with tun/tap myself, but the
 >>kernel documentation in
 >>Documentation/networking/tuntap.txt seems to
 >>indicate that you need a program to listen on two
 >>opened /dev/net/tun devices and copy the frames
 >>from one to the other.
> Thanks! I was afraid this was the reason ... :(
> 
> I actually tried writing an application that would
> open /dev/tap4 as a file and do a select() on it. 

The standalone tun-package [1] contains two example applications that 
act as simple bridges, one using SIGIO, one using select(). I guess it 
could be helpful for you to take a look at these examples.

[1] http://vtun.sourceforge.net/tun/tun-1.1.tar.gz

Bye, Mike

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bridge] Bridging between user processes - TAP question
  2004-06-17  4:34   ` Michael Renzmann
@ 2004-06-17 22:29     ` Derek Smalls
  2004-06-17 22:52       ` Stephen Hemminger
  0 siblings, 1 reply; 6+ messages in thread
From: Derek Smalls @ 2004-06-17 22:29 UTC (permalink / raw)
  To: bridge

Thanks again to everybody who responded!

I've redone everything from scratch with no result, I
think I'm missing something with respect to tap
devices -- hopefully this is the forum to get help.

I'm trying to write a trivial application that would
do read/write between a pair of tap devices. For
starters I'm just trying to do a read on a single tap
device -- just to make sure that it works. On a
freshly booted 2.4.20 system I do:

>tunctl -u root -t tap0
>mknod /dev/tap0 c 36 16 
>ifconfig tap0 promisc up

BTW, "tunctl" does not create the /dev/tap0 file so I
am using "mknod" to do it -- is this correct? 

I then start a very simple program derived from the
example in tun-1.1 package to do a select on
"/dev/tap0":

int main(int argc, char *argv[]) 
{ 
   int f1, fm; 
   fd_set fds; 
  
   f1 = open("/dev/tap0", O_RDWR); 
   ioctl(f1, TUNSETNOCSUM, 1); 
   fm = f1 + 1; 
  
   FD_ZERO(&fds); 
   FD_SET(f1, &fds); 
  
   select(fm, &fds, NULL, NULL, NULL); 
  
   printf("Received data on tap0 \n"); 
   return 0; 
} 

I then do "ping -I tap0 6.6.6.6" , or start my own
application that talks to ethernet ports giving it
tap0 as the port to talk to... Nothing. The select()
never returns. BTW, tcpdump does show packets on tap0
in both cases.

I suspect that tap0 is not set up correctly, what am I
doing wrong?

Thank you,


--- Michael Renzmann <mrenzmann@web.de> wrote:
> Hi.
> 
> Derek Smalls wrote:
>  >>I have not played with tun/tap myself, but the
>  >>kernel documentation in
>  >>Documentation/networking/tuntap.txt seems to
>  >>indicate that you need a program to listen on two
>  >>opened /dev/net/tun devices and copy the frames
>  >>from one to the other.
> > Thanks! I was afraid this was the reason ... :(
> > 
> > I actually tried writing an application that would
> > open /dev/tap4 as a file and do a select() on it. 
> 
> The standalone tun-package [1] contains two example
> applications that 
> act as simple bridges, one using SIGIO, one using
> select(). I guess it 
> could be helpful for you to take a look at these
> examples.
> 
> [1] http://vtun.sourceforge.net/tun/tun-1.1.tar.gz
> 
> Bye, Mike
> 



		
__________________________________
Do you Yahoo!?
Yahoo! Mail - Helps protect you from nasty viruses.
http://promotions.yahoo.com/new_mail

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bridge] Bridging between user processes - TAP question
  2004-06-17 22:29     ` [Bridge] Bridging between user processes - TAP question Derek Smalls
@ 2004-06-17 22:52       ` Stephen Hemminger
  0 siblings, 0 replies; 6+ messages in thread
From: Stephen Hemminger @ 2004-06-17 22:52 UTC (permalink / raw)
  To: Derek Smalls; +Cc: bridge

[-- Attachment #1: Type: text/plain, Size: 106 bytes --]

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


[-- Attachment #2: taptest.c --]
[-- Type: text/plain, Size: 2871 bytes --]

/* 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;
}
			

[-- Attachment #3: taptest.c --]
[-- Type: application/octet-stream, Size: 2871 bytes --]

/* 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;
}
			

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-06-17 22:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <C060DFCD9697A842B3189B458524FDC205D2D3@AIMAIL1.ai.aiinet.com>
2004-06-16 22:17 ` [Bridge] Bridging between user processes Derek Smalls
2004-06-17  4:34   ` Michael Renzmann
2004-06-17 22:29     ` [Bridge] Bridging between user processes - TAP question Derek Smalls
2004-06-17 22:52       ` Stephen Hemminger
     [not found] <40D08A26.1040907@tuxdriver.com>
2004-06-16 22:12 ` [Bridge] Bridging between user processes Derek Smalls
2004-06-16  4:04 Derek Smalls

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.