nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * Copyright (c) 2007, 2008, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
3 *
4 * OS dependent API for NetBSD. TAP routines
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20  
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <sys/ioctl.h>
24 #include <sys/time.h>
25 #include <sys/socket.h>
26 #include <net/if.h>
27 #include <fcntl.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <string.h>
32  
33 #include "osdep.h"
34  
35 struct tip_nbsd {
36 int tn_fd;
37 int tn_ioctls;
38 struct ifreq tn_ifr;
39 char tn_name[MAX_IFACE_NAME];
40 int tn_destroy;
41 };
42  
43 static int ti_do_open_nbsd(struct tif *ti, char *name)
44 {
45 int fd;
46 char *iface = "/dev/tap";
47 struct stat st;
48 struct tip_nbsd *priv = ti_priv(ti);
49 int s;
50 unsigned int flags;
51 struct ifreq *ifr;
52  
53 /* open tap */
54 if (name)
55 iface = name;
56 else
57 priv->tn_destroy = 1; /* we create, we destroy */
58  
59 fd = open(iface, O_RDWR);
60 if (fd == -1)
61 return -1;
62  
63 /* get name */
64 if(fstat(fd, &st) == -1)
65 goto err;
66 snprintf(priv->tn_name, sizeof(priv->tn_name)-1, "%s",
67 devname(st.st_rdev, S_IFCHR));
68  
69 /* bring iface up */
70 s = socket(PF_INET, SOCK_DGRAM, 0);
71 if (s == -1)
72 goto err;
73 priv->tn_ioctls = s;
74  
75 /* get flags */
76 ifr = &priv->tn_ifr;
77 memset(ifr, 0, sizeof(*ifr));
78 snprintf(ifr->ifr_name, sizeof(ifr->ifr_name)-1, "%s", priv->tn_name);
79 if (ioctl(s, SIOCGIFFLAGS, ifr) == -1)
80 goto err2;
81 flags = ifr->ifr_flags;
82  
83 /* set flags */
84 flags |= IFF_UP;
85 ifr->ifr_flags = flags & 0xffff;
86 if (ioctl(s, SIOCSIFFLAGS, ifr) == -1)
87 goto err2;
88  
89 return fd;
90 err:
91 /* XXX destroy */
92 close(fd);
93 return -1;
94 err2:
95 close(s);
96 goto err;
97 }
98  
99 static void ti_do_free(struct tif *ti)
100 {
101 struct tip_nbsd *priv = ti_priv(ti);
102  
103 free(priv);
104 free(ti);
105 }
106  
107 static void ti_destroy(struct tip_nbsd *priv)
108 {
109 ioctl(priv->tn_ioctls, SIOCIFDESTROY, &priv->tn_ifr);
110 }
111  
112 static void ti_close_nbsd(struct tif *ti)
113 {
114 struct tip_nbsd *priv = ti_priv(ti);
115  
116 if (priv->tn_destroy)
117 ti_destroy(priv);
118  
119 close(priv->tn_fd);
120 close(priv->tn_ioctls);
121 ti_do_free(ti);
122 }
123  
124 static char *ti_name_nbsd(struct tif *ti)
125 {
126 struct tip_nbsd *priv = ti_priv(ti);
127  
128 return priv->tn_name;
129 }
130  
131 static int ti_set_mtu_nbsd(struct tif *ti, int mtu)
132 {
133 struct tip_nbsd *priv = ti_priv(ti);
134  
135 priv->tn_ifr.ifr_mtu = mtu;
136  
137 return ioctl(priv->tn_ioctls, SIOCSIFMTU, &priv->tn_ifr);
138 }
139  
140 static int ti_set_mac_nbsd(struct tif *ti, unsigned char *mac)
141 {
142 struct tip_nbsd *priv = ti_priv(ti);
143 struct ifreq *ifr = &priv->tn_ifr;
144  
145 ifr->ifr_addr.sa_family = AF_LINK;
146 ifr->ifr_addr.sa_len = 6;
147 memcpy(ifr->ifr_addr.sa_data, mac, 6);
148  
149 return ioctl(priv->tn_ioctls, SIOCSIFADDR, ifr);
150 }
151  
152 static int ti_set_ip_nbsd(struct tif *ti, struct in_addr *ip)
153 {
154 struct tip_nbsd *priv = ti_priv(ti);
155 struct ifaliasreq ifra;
156 struct sockaddr_in *s_in;
157  
158 /* assume same size */
159 memset(&ifra, 0, sizeof(ifra));
160 strncpy(ifra.ifra_name, priv->tn_ifr.ifr_name, IFNAMSIZ);
161  
162 s_in = (struct sockaddr_in *) &ifra.ifra_addr;
163 s_in->sin_family = PF_INET;
164 s_in->sin_addr = *ip;
165 s_in->sin_len = sizeof(*s_in);
166  
167 return ioctl(priv->tn_ioctls, SIOCAIFADDR, &ifra);
168 }
169  
170 static int ti_fd_nbsd(struct tif *ti)
171 {
172 struct tip_nbsd *priv = ti_priv(ti);
173  
174 return priv->tn_fd;
175 }
176  
177 static int ti_read_nbsd(struct tif *ti, void *buf, int len)
178 {
179 return read(ti_fd(ti), buf, len);
180 }
181  
182 static int ti_write_nbsd(struct tif *ti, void *buf, int len)
183 {
184 return write(ti_fd(ti), buf, len);
185 }
186  
187 static struct tif *ti_open_nbsd(char *iface)
188 {
189 struct tif *ti;
190 struct tip_nbsd *priv;
191 int fd;
192  
193 /* setup ti struct */
194 ti = ti_alloc(sizeof(*priv));
195 if (!ti)
196 return NULL;
197 ti->ti_name = ti_name_nbsd;
198 ti->ti_set_mtu = ti_set_mtu_nbsd;
199 ti->ti_close = ti_close_nbsd;
200 ti->ti_fd = ti_fd_nbsd;
201 ti->ti_read = ti_read_nbsd;
202 ti->ti_write = ti_write_nbsd;
203 ti->ti_set_mac = ti_set_mac_nbsd;
204 ti->ti_set_ip = ti_set_ip_nbsd;
205  
206 /* setup iface */
207 fd = ti_do_open_nbsd(ti, iface);
208 if (fd == -1) {
209 ti_do_free(ti);
210 return NULL;
211 }
212  
213 /* setup private state */
214 priv = ti_priv(ti);
215 priv->tn_fd = fd;
216  
217 return ti;
218 }
219  
220 struct tif *ti_open(char *iface)
221 {
222 return ti_open_nbsd(iface);
223 }