LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Networking
User Name
Password
Linux - Networking This forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.

Notices


Reply
  Search this Thread
Old 12-02-2009, 03:53 PM   #1
duesp
LQ Newbie
 
Registered: Nov 2009
Posts: 2

Rep: Reputation: 0
userapp for ethertap


Hi,

I am trying to write user-app that utilizes TAP driver in linux to send/receive Ethernet packets from TAP interfaces.
I don’t find a good example of this anywhere on the internet. I am having difficulty in receiving packets.
I am kind of struck. If you could share some thoughts or sample program I would appreciate it.

Here is what I have done.
1) TAP driver is installed with “sudo insmod tun.ko”
2) tap0 interface is created with tunctl program and assigned an ip address, interface link is set to up
3) Userapp sends the data to tap0 by opening the device, write an Ethernet frame and waiting for the written frame from the device
4) User program does not receive the data

User program is provided below.

As far as TAP driver goes, tun_get_user receives the packet from iovect, allocates skbuff. But, the packet does not go out of the device.
1) tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL)): success with 1510 bytes
as 4 bytes are stripped
2) skb_copy_datagram_from_iovec(skb, 0, iv, len): copies data from iovect to skbuffer
I verified the data in the trace logs. It is the same data that send_ethernet_frame
sends the data
3) switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TAP_DEV:
skb->protocol = eth_type_trans(skb, tun->dev);
pdata = skb->data;
for (i = 0; i < 20; i++)
printk ("%02x ", (*(pdata+i) & 0xff));
printk ("\n");
skb->dev = tun->dev;
wake_up_interruptible(&tun->read_wait);
}

Wake_up_interruptable does not wake up the read wait queue. Even if I use dev_queue_xmit, linux kernel crashes. I have the problem here.

I understand that this code has been tested. Unfortunately, I could not find any sample user-app that writes Ethernet frames to TAP device
And reads the frames.

I appreciate if you could help me with this. I have not got response from linux forums also.

Thanks in advance,

David

UserApp


int
main(int argc, char **argv)
{
struct ifreq ifr;
int tap_fd, option;
uint16_t nread;
char buffer[BUFSIZE];
int sent_fr_sz;

char *tun = "", *file = "/dev/net/tun";

while ((option = getopt(argc, argv, "h:i:")) > 0) {
switch (option)
{
case 'i':
tun = optarg;
break;
case 'h':
default:
usage(argv[0]);
}
}

argv += optind;
argc -= optind;

if (argc > 0)
usage(argv[0]);

if ((tap_fd = open(file, O_RDWR)) < 0) {
perror(file);
exit(1);
}

memset(&ifr, 0, sizeof(ifr));

ifr.ifr_flags = IFF_TAP | TUN_NO_PI;
strncpy(ifr.ifr_name, tun, sizeof(ifr.ifr_name) - 1);
if (ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0) {
perror(ifr.ifr_name);
exit(1);
}

for (; {

/* send ethernet frame to the tap device */
sent_fr_sz = send_ethernet_frame(tap_fd);

/* read the packet from tap device */
nread = cread(tap_fd, buffer, ETH_FRAME_LEN);
printf ("Read %d bytes\n", nread);
}
}

/*************************************************************/
/* send_ethernet_frame: sends an ether frame with prepended */
/* DSA tag (marvel portid0 to the tap device. */
/*************************************************************/
int send_ethernet_frame(int fd)
{
int j;
int sent_frame_sz = 0;
int mrvl_portid = 0;

/*buffer for ethernet frame*/
void* buffer = (void*) malloc(sizeof (mrvl_portid) + ETH_FRAME_LEN);

/* pointer to ethernet header*/
unsigned char* etherhead = buffer ;

/*userdata in ethernet frame*/
unsigned char* data = buffer + 14;

/*another pointer to ethernet header*/
struct ethhdr *eh = (struct ethhdr *) etherhead;

/*our MAC address*/
unsigned char src_mac[6] = {0x00, 0x01, 0x02, 0xFA, 0x70, 0xAA};

/*other host MAC address*/
unsigned char dest_mac[6] = {0x00, 0x08, 0x75, 0xC8, 0x28, 0xE5};

/* set the frame header*/
memcpy((void*)buffer, (void*)dest_mac, ETH_ALEN);
memcpy((void*)(buffer+ ETH_ALEN ), (void*)src_mac, ETH_ALEN);

eh->h_proto = 0x0800;

/* fill the frame with some data */
for (j = 0; j < 1500; j++) {
data[j] = (unsigned char)(j);
}

/* send the frame */
sent_frame_sz = write (fd, buffer, ETH_FRAME_LEN);

if (sent_frame_sz < 0)
{
perror("ethernet frame write error\n");
exit(1);
}

printf ("ethernet frame sent %d successfully\n", sent_frame_sz);
return sent_frame_sz;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
documentation for newbie on ethertap fundoos4me Linux - Software 0 04-07-2007 04:33 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Networking

All times are GMT -5. The time now is 08:27 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration