]> git.sur5r.net Git - freertos/blob - Demo/uIP_Demo_Rowley_ARM7/uip/tapdev.c
First version under SVN is V4.0.1
[freertos] / Demo / uIP_Demo_Rowley_ARM7 / uip / tapdev.c
1 /*\r
2  * Copyright (c) 2001, Swedish Institute of Computer Science.\r
3  * All rights reserved. \r
4  *\r
5  * Redistribution and use in source and binary forms, with or without \r
6  * modification, are permitted provided that the following conditions \r
7  * are met: \r
8  *\r
9  * 1. Redistributions of source code must retain the above copyright \r
10  *    notice, this list of conditions and the following disclaimer. \r
11  *\r
12  * 2. Redistributions in binary form must reproduce the above copyright \r
13  *    notice, this list of conditions and the following disclaimer in the \r
14  *    documentation and/or other materials provided with the distribution. \r
15  *\r
16  * 3. Neither the name of the Institute nor the names of its contributors \r
17  *    may be used to endorse or promote products derived from this software \r
18  *    without specific prior written permission. \r
19  *\r
20  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND \r
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE \r
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \r
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS \r
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) \r
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY \r
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \r
30  * SUCH DAMAGE. \r
31  *\r
32  * Author: Adam Dunkels <adam@sics.se>\r
33  *\r
34  * $Id: tapdev.c,v 1.7.2.1 2003/10/07 13:23:19 adam Exp $\r
35  */\r
36 \r
37 \r
38 #include <fcntl.h>\r
39 #include <stdlib.h>\r
40 #include <stdio.h>\r
41 #include <unistd.h>\r
42 #include <string.h>\r
43 #include <sys/ioctl.h>\r
44 #include <sys/socket.h>\r
45 #include <sys/types.h>\r
46 #include <sys/time.h>\r
47 #include <sys/uio.h>\r
48 #include <sys/socket.h>\r
49 \r
50 #ifdef linux\r
51 #include <sys/ioctl.h>\r
52 #include <linux/if.h>\r
53 #include <linux/if_tun.h>\r
54 #define DEVTAP "/dev/net/tun"\r
55 #else  /* linux */\r
56 #define DEVTAP "/dev/tap0"\r
57 #endif /* linux */\r
58 \r
59 #include "uip.h"\r
60 \r
61 static int fd;\r
62 \r
63 static unsigned long lasttime;\r
64 static struct timezone tz;\r
65 \r
66 /*-----------------------------------------------------------------------------------*/\r
67 void\r
68 tapdev_init(void)\r
69 {\r
70   char buf[1024];\r
71   \r
72   fd = open(DEVTAP, O_RDWR);\r
73   if(fd == -1) {\r
74     perror("tapdev: tapdev_init: open");\r
75     exit(1);\r
76   }\r
77 \r
78 #ifdef linux\r
79   {\r
80     struct ifreq ifr;\r
81     memset(&ifr, 0, sizeof(ifr));\r
82     ifr.ifr_flags = IFF_TAP|IFF_NO_PI;\r
83     if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {\r
84       perror(buf);\r
85       exit(1);\r
86     }\r
87   }\r
88 #endif /* Linux */\r
89 \r
90   snprintf(buf, sizeof(buf), "ifconfig tap0 inet %d.%d.%d.%d",\r
91            UIP_DRIPADDR0, UIP_DRIPADDR1, UIP_DRIPADDR2, UIP_DRIPADDR3);\r
92   system(buf);\r
93 \r
94   lasttime = 0;\r
95 }\r
96 /*-----------------------------------------------------------------------------------*/\r
97 unsigned int\r
98 tapdev_read(void)\r
99 {\r
100   fd_set fdset;\r
101   struct timeval tv, now;\r
102   int ret;\r
103   \r
104   if(lasttime >= 500000) {\r
105     lasttime = 0;\r
106     return 0;\r
107   }\r
108   \r
109   tv.tv_sec = 0;\r
110   tv.tv_usec = 500000 - lasttime;\r
111 \r
112 \r
113   FD_ZERO(&fdset);\r
114   FD_SET(fd, &fdset);\r
115 \r
116   gettimeofday(&now, &tz);  \r
117   ret = select(fd + 1, &fdset, NULL, NULL, &tv);\r
118   if(ret == 0) {\r
119     lasttime = 0;    \r
120     return 0;\r
121   } \r
122   ret = read(fd, uip_buf, UIP_BUFSIZE);  \r
123   if(ret == -1) {\r
124     perror("tap_dev: tapdev_read: read");\r
125   }\r
126   gettimeofday(&tv, &tz);\r
127   lasttime += (tv.tv_sec - now.tv_sec) * 1000000 + (tv.tv_usec - now.tv_usec);\r
128 \r
129   return ret;\r
130 }\r
131 /*-----------------------------------------------------------------------------------*/\r
132 void\r
133 tapdev_send(void)\r
134 {\r
135   int ret;\r
136   struct iovec iov[2];\r
137   \r
138 #ifdef linux\r
139   {\r
140     char tmpbuf[UIP_BUFSIZE];\r
141     int i;\r
142 \r
143     for(i = 0; i < 40 + UIP_LLH_LEN; i++) {\r
144       tmpbuf[i] = uip_buf[i];\r
145     }\r
146     \r
147     for(; i < uip_len; i++) {\r
148       tmpbuf[i] = uip_appdata[i - 40 - UIP_LLH_LEN];\r
149     }\r
150     \r
151     ret = write(fd, tmpbuf, uip_len);\r
152   }  \r
153 #else \r
154 \r
155   if(uip_len < 40 + UIP_LLH_LEN) {\r
156     ret = write(fd, uip_buf, uip_len + UIP_LLH_LEN);\r
157   } else {\r
158     iov[0].iov_base = uip_buf;\r
159     iov[0].iov_len = 40 + UIP_LLH_LEN;\r
160     iov[1].iov_base = (char *)uip_appdata;\r
161     iov[1].iov_len = uip_len - (40 + UIP_LLH_LEN);  \r
162     \r
163     ret = writev(fd, iov, 2);\r
164   }\r
165 #endif\r
166   if(ret == -1) {\r
167     perror("tap_dev: tapdev_send: writev");\r
168     exit(1);\r
169   }\r
170 }  \r
171 /*-----------------------------------------------------------------------------------*/\r