Hi Jeff,
Last year, I had exactly the same situation. (every single bit of it!).
I'd almost tried everywhere, TUN/TAP Author (Maxim K.), VTun mailing
list and also here, OpenVPN-devel list, But no chance. :(
In my case, this problem wasn't vital and I could carry on without
having it solved, But I still have no idea why in the earth those ping
requests should be replied to, while my select() even doesn't know about
it!
This time, I hope we can find a proper answer here and sorry for a
useless reply. :)
Regards,
Arash
On Thu, 2007-09-13 at 19:52 -0700, Jeff Wiegley wrote:
> I know this is off-topic, sorry. The email address for
> Max K. the creator of the tun/tap driver, simply bounces
> and I'm beating my head against the wall. Since OpenVPN
> uses tap devices in a raw state I hoped that maybe
> somebody here would be able to help.
Yeah, That address is abandoned for years!
>
> I want a very simply program that opens a tap device
> and then displays all the Ethernet frames that come
> through it. Basically I want something that delivers
> Ethernet frames up to a userspace program.
>
> Basically...
>
> # tunctl -u jeffw
> # ifconfig tap0 10.10.0.1 netmask 255.255.255.0
> $ ./tapwatcher tap0
>
> Then from another window I want to be able to do
> "ping 10.10.0.1" and tapwatcher should spew the
> raw Ethernet frames that would be generated on
> tap0.
>
> To that end I have written the program appended
> here but it doesn't do anything. It starts up, it
> reports it opened the tap and I get a decent
> file descriptor value but the select hangs.
> there is never anything present to read.
> The weird thing that does happen is the pings are
> responded to! Shouldn't the kernel be simply passing
> the frames on to my tapwatcher program and not
> processing them itself??? I can even SSH to the
> stupid tap0 and I get logged into localhost.
> Why is the kernel attached to tap0 and not my
> tapwatcher program?
>
> Am I missing something fundamental? I would be happy
> to contribute my result back to the kernel sources
> to replace/augment the tuntap.txt Documentation that
> is weak and doesn't really give a new tun/tap user
> what he needs to get something working. (the examples
> in vtun are also both broken and don't compile/run
> on my 64-bit machine.)
>
> Thanks, here's the program I wrote.
>
> - Jeff
> -------------------------------------------------------
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
>
> #include <string.h>
>
> #include <sys/ioctl.h>
> #include <net/if.h>
> #include <netinet/if_ether.h>
> #include <linux/if_tun.h>
>
> #include <errno.h>
> #include <signal.h>
>
> #include <sys/select.h>
>
> int tun_alloc(char *dev)
> {
> struct ifreq ifr;
> int result = -1;
> int err;
>
> if( (result = open("/dev/net/tun", O_RDWR)) >= 0 )
> return result;
>
> memset(&ifr, 0, sizeof(ifr));
>
> ifr.ifr_flags = IFF_TAP;
> if( *dev )
> strncpy(ifr.ifr_name, dev, IFNAMSIZ);
>
> if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 )
> {
> close(result);
> return err;
> }
>
> strcpy(dev, ifr.ifr_name);
>
> return result;
> }
>
> int continue_running;
>
> void handler(int num, siginfo_t *info, void *context)
> {
> continue_running = 0;
> }
>
> int main(int argc, char *argv[])
> {
> continue_running = 0;
>
> struct sigaction action;
>
> action.sa_sigaction = handler;
> sigemptyset (&action.sa_mask);
> action.sa_flags = SA_SIGINFO;
>
> sigaction(SIGINT, &action, NULL);
>
> char name[128];
> strcpy(name,argv[1]);
> int tap = tun_alloc(name);
>
> if (tap < 0)
> perror("TAP failed: ");
> else
> {
> continue_running = 1;
> fprintf(stderr,"tap = %d, name = \"%s\"\n",tap,name);
> while (continue_running)
> {
> fd_set watch;
> FD_ZERO(&watch);
> FD_SET(tap,&watch);
> errno = 0;
> select(tap+1,&watch, NULL, NULL, NULL);
> fprintf(stderr,"ready\n");
> if (errno && (errno != EINTR))
> break;
> }
> close(tap);
> }
> }
> -------------------------------------------------------------
>