nexmon – Blame information for rev 1
?pathlinks?
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 OpenBSD. 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_obsd { |
||
36 | int to_fd; |
||
37 | int to_ioctls; |
||
38 | struct ifreq to_ifr; |
||
39 | char to_name[MAX_IFACE_NAME]; |
||
40 | int to_destroy; |
||
41 | }; |
||
42 | |||
43 | static int ti_do_open_obsd(struct tif *ti, char *name) |
||
44 | { |
||
45 | int fd; |
||
46 | char *iface = "/dev/tap"; |
||
47 | struct stat st; |
||
48 | struct tip_obsd *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->to_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->to_name, sizeof(priv->to_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->to_ioctls = s; |
||
74 | |||
75 | /* get flags */ |
||
76 | ifr = &priv->to_ifr; |
||
77 | memset(ifr, 0, sizeof(*ifr)); |
||
78 | snprintf(ifr->ifr_name, sizeof(ifr->ifr_name)-1, "%s", priv->to_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_obsd *priv = ti_priv(ti); |
||
102 | |||
103 | free(priv); |
||
104 | free(ti); |
||
105 | } |
||
106 | |||
107 | static void ti_destroy(struct tip_obsd *priv) |
||
108 | { |
||
109 | ioctl(priv->to_ioctls, SIOCIFDESTROY, &priv->to_ifr); |
||
110 | } |
||
111 | |||
112 | static void ti_close_obsd(struct tif *ti) |
||
113 | { |
||
114 | struct tip_obsd *priv = ti_priv(ti); |
||
115 | |||
116 | if (priv->to_destroy) |
||
117 | ti_destroy(priv); |
||
118 | |||
119 | close(priv->to_fd); |
||
120 | close(priv->to_ioctls); |
||
121 | ti_do_free(ti); |
||
122 | } |
||
123 | |||
124 | static char *ti_name_obsd(struct tif *ti) |
||
125 | { |
||
126 | struct tip_obsd *priv = ti_priv(ti); |
||
127 | |||
128 | return priv->to_name; |
||
129 | } |
||
130 | |||
131 | static int ti_set_mtu_obsd(struct tif *ti, int mtu) |
||
132 | { |
||
133 | struct tip_obsd *priv = ti_priv(ti); |
||
134 | |||
135 | priv->to_ifr.ifr_mtu = mtu; |
||
136 | |||
137 | return ioctl(priv->to_ioctls, SIOCSIFMTU, &priv->to_ifr); |
||
138 | } |
||
139 | |||
140 | static int ti_set_mac_obsd(struct tif *ti, unsigned char *mac) |
||
141 | { |
||
142 | struct tip_obsd *priv = ti_priv(ti); |
||
143 | struct ifreq *ifr = &priv->to_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->to_ioctls, SIOCSIFLLADDR, ifr); |
||
150 | } |
||
151 | |||
152 | static int ti_set_ip_obsd(struct tif *ti, struct in_addr *ip) |
||
153 | { |
||
154 | struct tip_obsd *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->to_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->to_ioctls, SIOCAIFADDR, &ifra); |
||
168 | } |
||
169 | |||
170 | static int ti_fd_obsd(struct tif *ti) |
||
171 | { |
||
172 | struct tip_obsd *priv = ti_priv(ti); |
||
173 | |||
174 | return priv->to_fd; |
||
175 | } |
||
176 | |||
177 | static int ti_read_obsd(struct tif *ti, void *buf, int len) |
||
178 | { |
||
179 | return read(ti_fd(ti), buf, len); |
||
180 | } |
||
181 | |||
182 | static int ti_write_obsd(struct tif *ti, void *buf, int len) |
||
183 | { |
||
184 | return write(ti_fd(ti), buf, len); |
||
185 | } |
||
186 | |||
187 | static struct tif *ti_open_obsd(char *iface) |
||
188 | { |
||
189 | struct tif *ti; |
||
190 | struct tip_obsd *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_obsd; |
||
198 | ti->ti_set_mtu = ti_set_mtu_obsd; |
||
199 | ti->ti_close = ti_close_obsd; |
||
200 | ti->ti_fd = ti_fd_obsd; |
||
201 | ti->ti_read = ti_read_obsd; |
||
202 | ti->ti_write = ti_write_obsd; |
||
203 | ti->ti_set_mac = ti_set_mac_obsd; |
||
204 | ti->ti_set_ip = ti_set_ip_obsd; |
||
205 | |||
206 | /* setup iface */ |
||
207 | fd = ti_do_open_obsd(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->to_fd = fd; |
||
216 | |||
217 | return ti; |
||
218 | } |
||
219 | |||
220 | struct tif *ti_open(char *iface) |
||
221 | { |
||
222 | return ti_open_obsd(iface); |
||
223 | } |