OpenCoverage

port-net.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/openbsd-compat/port-net.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright (c) 2005 Reyk Floeter <reyk@openbsd.org>-
3 *-
4 * Permission to use, copy, modify, and distribute this software for any-
5 * purpose with or without fee is hereby granted, provided that the above-
6 * copyright notice and this permission notice appear in all copies.-
7 *-
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES-
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF-
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR-
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES-
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN-
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF-
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.-
15 */-
16-
17#include "includes.h"-
18-
19#include <sys/types.h>-
20#include <sys/ioctl.h>-
21-
22#include <netinet/in.h>-
23#include <arpa/inet.h>-
24#include <netinet/ip.h>-
25-
26#include <errno.h>-
27#include <fcntl.h>-
28#include <stdarg.h>-
29#include <string.h>-
30#include <unistd.h>-
31-
32#include "openbsd-compat/sys-queue.h"-
33#include "log.h"-
34#include "misc.h"-
35#include "sshbuf.h"-
36#include "channels.h"-
37#include "ssherr.h"-
38-
39/*-
40 * This file contains various portability code for network support,-
41 * including tun/tap forwarding and routing domains.-
42 */-
43-
44#if defined(SYS_RDOMAIN_LINUX) || defined(SSH_TUN_LINUX)-
45#include <linux/if.h>-
46#endif-
47-
48#if defined(SYS_RDOMAIN_LINUX)-
49char *-
50sys_get_rdomain(int fd)-
51{-
52 char dev[IFNAMSIZ + 1];-
53 socklen_t len = sizeof(dev) - 1;-
54-
55 if (getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, dev, &len) == -1) {-
56 error("%s: cannot determine VRF for fd=%d : %s",-
57 __func__, fd, strerror(errno));-
58 return NULL;-
59 }-
60 dev[len] = '\0';-
61 return strdup(dev);-
62}-
63-
64int-
65sys_set_rdomain(int fd, const char *name)-
66{-
67 if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,-
68 name, strlen(name)) == -1) {-
69 error("%s: setsockopt(%d, SO_BINDTODEVICE, %s): %s",-
70 __func__, fd, name, strerror(errno));-
71 return -1;-
72 }-
73 return 0;-
74}-
75-
76int-
77sys_valid_rdomain(const char *name)-
78{-
79 int fd;-
80-
81 /*-
82 * This is a pretty crappy way to test. It would be better to-
83 * check whether "name" represents a VRF device, but apparently-
84 * that requires an rtnetlink transaction.-
85 */-
86 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)-
87 return 0;-
88 if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,-
89 name, strlen(name)) == -1) {-
90 close(fd);-
91 return 0;-
92 }-
93 close(fd);-
94 return 1;-
95}-
96#elif defined(SYS_RDOMAIN_XXX)-
97/* XXX examples */-
98char *-
99sys_get_rdomain(int fd)-
100{-
101 return NULL;-
102}-
103-
104int-
105sys_set_rdomain(int fd, const char *name)-
106{-
107 return -1;-
108}-
109-
110int-
111valid_rdomain(const char *name)-
112{-
113 return 0;-
114}-
115-
116void-
117sys_set_process_rdomain(const char *name)-
118{-
119 fatal("%s: not supported", __func__);-
120}-
121#endif /* defined(SYS_RDOMAIN_XXX) */-
122-
123/*-
124 * This is the portable version of the SSH tunnel forwarding, it-
125 * uses some preprocessor definitions for various platform-specific-
126 * settings.-
127 *-
128 * SSH_TUN_LINUX Use the (newer) Linux tun/tap device-
129 * SSH_TUN_FREEBSD Use the FreeBSD tun/tap device-
130 * SSH_TUN_COMPAT_AF Translate the OpenBSD address family-
131 * SSH_TUN_PREPEND_AF Prepend/remove the address family-
132 */-
133-
134/*-
135 * System-specific tunnel open function-
136 */-
137-
138#if defined(SSH_TUN_LINUX)-
139#include <linux/if_tun.h>-
140-
141int-
142sys_tun_open(int tun, int mode, char **ifname)-
143{-
144 struct ifreq ifr;-
145 int fd = -1;-
146 const char *name = NULL;-
147-
148 if (ifname != NULL)
ifname != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
149 *ifname = NULL;
never executed: *ifname = ((void *)0) ;
0
150-
151 if ((fd = open("/dev/net/tun", O_RDWR)) == -1) {
(fd = open("/d...", 02 )) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
152 debug("%s: failed to open tunnel control interface: %s",-
153 __func__, strerror(errno));-
154 return (-1);
never executed: return (-1);
0
155 }-
156-
157 bzero(&ifr, sizeof(ifr));-
158-
159 if (mode == SSH_TUNMODE_ETHERNET) {
mode == 0x02Description
TRUEnever evaluated
FALSEnever evaluated
0
160 ifr.ifr_flags = IFF_TAP;-
161 name = "tap%d";-
162 } else {
never executed: end of block
0
163 ifr.ifr_flags = IFF_TUN;-
164 name = "tun%d";-
165 }
never executed: end of block
0
166 ifr.ifr_flags |= IFF_NO_PI;-
167-
168 if (tun != SSH_TUNID_ANY) {
tun != 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
169 if (tun > SSH_TUNID_MAX) {
tun > (0x7fffffff - 2)Description
TRUEnever evaluated
FALSEnever evaluated
0
170 debug("%s: invalid tunnel id %x: %s", __func__,-
171 tun, strerror(errno));-
172 goto failed;
never executed: goto failed;
0
173 }-
174 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), name, tun);-
175 }
never executed: end of block
0
176-
177 if (ioctl(fd, TUNSETIFF, &ifr) == -1) {
ioctl(fd, (((1... , &ifr) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
178 debug("%s: failed to configure tunnel (mode %d): %s", __func__,-
179 mode, strerror(errno));-
180 goto failed;
never executed: goto failed;
0
181 }-
182-
183 if (tun == SSH_TUNID_ANY)
tun == 0x7fffffffDescription
TRUEnever evaluated
FALSEnever evaluated
0
184 debug("%s: tunnel mode %d fd %d", __func__, mode, fd);
never executed: debug("%s: tunnel mode %d fd %d", __func__, mode, fd);
0
185 else-
186 debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd);
never executed: debug("%s: %s mode %d fd %d", __func__, ifr. ifr_ifrn.ifrn_name , mode, fd);
0
187-
188 if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL)
never executed: __retval = (char *) memcpy (__retval, ifr. ifr_ifrn.ifrn_name, __len);
__retval != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
((const char *...e))[0] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
ifname != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
(*ifname = (__...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons...frn.ifrn_name)Description
TRUEnever evaluated
FALSEnever evaluated
((size_t)(cons...rn_name) == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
189 goto failed;
never executed: goto failed;
0
190-
191 return (fd);
never executed: return (fd);
0
192-
193 failed:-
194 close(fd);-
195 return (-1);
never executed: return (-1);
0
196}-
197#endif /* SSH_TUN_LINUX */-
198-
199#ifdef SSH_TUN_FREEBSD-
200#include <sys/socket.h>-
201#include <net/if.h>-
202-
203#ifdef HAVE_NET_IF_TUN_H-
204#include <net/if_tun.h>-
205#endif-
206-
207int-
208sys_tun_open(int tun, int mode, char **ifname)-
209{-
210 struct ifreq ifr;-
211 char name[100];-
212 int fd = -1, sock, flag;-
213 const char *tunbase = "tun";-
214-
215 if (ifname != NULL)-
216 *ifname = NULL;-
217-
218 if (mode == SSH_TUNMODE_ETHERNET) {-
219#ifdef SSH_TUN_NO_L2-
220 debug("%s: no layer 2 tunnelling support", __func__);-
221 return (-1);-
222#else-
223 tunbase = "tap";-
224#endif-
225 }-
226-
227 /* Open the tunnel device */-
228 if (tun <= SSH_TUNID_MAX) {-
229 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);-
230 fd = open(name, O_RDWR);-
231 } else if (tun == SSH_TUNID_ANY) {-
232 for (tun = 100; tun >= 0; tun--) {-
233 snprintf(name, sizeof(name), "/dev/%s%d",-
234 tunbase, tun);-
235 if ((fd = open(name, O_RDWR)) >= 0)-
236 break;-
237 }-
238 } else {-
239 debug("%s: invalid tunnel %u\n", __func__, tun);-
240 return (-1);-
241 }-
242-
243 if (fd < 0) {-
244 debug("%s: %s open failed: %s", __func__, name,-
245 strerror(errno));-
246 return (-1);-
247 }-
248-
249 /* Turn on tunnel headers */-
250 flag = 1;-
251#if defined(TUNSIFHEAD) && !defined(SSH_TUN_PREPEND_AF)-
252 if (mode != SSH_TUNMODE_ETHERNET &&-
253 ioctl(fd, TUNSIFHEAD, &flag) == -1) {-
254 debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd,-
255 strerror(errno));-
256 close(fd);-
257 }-
258#endif-
259-
260 debug("%s: %s mode %d fd %d", __func__, name, mode, fd);-
261-
262 /* Set the tunnel device operation mode */-
263 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);-
264 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)-
265 goto failed;-
266-
267 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)-
268 goto failed;-
269 if ((ifr.ifr_flags & IFF_UP) == 0) {-
270 ifr.ifr_flags |= IFF_UP;-
271 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)-
272 goto failed;-
273 }-
274-
275 if (ifname != NULL && (*ifname = strdup(ifr.ifr_name)) == NULL)-
276 goto failed;-
277-
278 close(sock);-
279 return (fd);-
280-
281 failed:-
282 if (fd >= 0)-
283 close(fd);-
284 if (sock >= 0)-
285 close(sock);-
286 debug("%s: failed to set %s mode %d: %s", __func__, name,-
287 mode, strerror(errno));-
288 return (-1);-
289}-
290#endif /* SSH_TUN_FREEBSD */-
291-
292/*-
293 * System-specific channel filters-
294 */-
295-
296#if defined(SSH_TUN_FILTER)-
297/*-
298 * The tunnel forwarding protocol prepends the address family of forwarded-
299 * IP packets using OpenBSD's numbers.-
300 */-
301#define OPENBSD_AF_INET 2-
302#define OPENBSD_AF_INET6 24-
303-
304int-
305sys_tun_infilter(struct ssh *ssh, struct Channel *c, char *buf, int _len)-
306{-
307 int r;-
308 size_t len;-
309 char *ptr = buf;-
310#if defined(SSH_TUN_PREPEND_AF)-
311 char rbuf[CHAN_RBUF];-
312 struct ip iph;-
313#endif-
314#if defined(SSH_TUN_PREPEND_AF) || defined(SSH_TUN_COMPAT_AF)-
315 u_int32_t af;-
316#endif-
317-
318 /* XXX update channel input filter API to use unsigned length */-
319 if (_len < 0)
_len < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
320 return -1;
never executed: return -1;
0
321 len = _len;-
322-
323#if defined(SSH_TUN_PREPEND_AF)-
324 if (len <= sizeof(iph) || len > sizeof(rbuf) - 4)
len <= sizeof(iph)Description
TRUEnever evaluated
FALSEnever evaluated
len > sizeof(rbuf) - 4Description
TRUEnever evaluated
FALSEnever evaluated
0
325 return -1;
never executed: return -1;
0
326 /* Determine address family from packet IP header. */-
327 memcpy(&iph, buf, sizeof(iph));-
328 af = iph.ip_v == 6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET;
iph.ip_v == 6Description
TRUEnever evaluated
FALSEnever evaluated
0
329 /* Prepend address family to packet using OpenBSD constants */-
330 memcpy(rbuf + 4, buf, len);-
331 len += 4;-
332 POKE_U32(rbuf, af);-
333 ptr = rbuf;-
334#elif defined(SSH_TUN_COMPAT_AF)-
335 /* Convert existing address family header to OpenBSD value */-
336 if (len <= 4)-
337 return -1;-
338 af = PEEK_U32(buf);-
339 /* Put it back */-
340 POKE_U32(buf, af == AF_INET6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET);-
341#endif-
342-
343 if ((r = sshbuf_put_string(c->input, ptr, len)) != 0)
(r = sshbuf_pu...tr, len)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
344 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
345 return (0);
never executed: return (0);
0
346}-
347-
348u_char *-
349sys_tun_outfilter(struct ssh *ssh, struct Channel *c,-
350 u_char **data, size_t *dlen)-
351{-
352 u_char *buf;-
353 u_int32_t af;-
354 int r;-
355-
356 /* XXX new API is incompatible with this signature. */-
357 if ((r = sshbuf_get_string(c->output, data, dlen)) != 0)
(r = sshbuf_ge...a, dlen)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
358 fatal("%s: buffer error: %s", __func__, ssh_err(r));
never executed: fatal("%s: buffer error: %s", __func__, ssh_err(r));
0
359 if (*dlen < sizeof(af))
*dlen < sizeof(af)Description
TRUEnever evaluated
FALSEnever evaluated
0
360 return (NULL);
never executed: return ( ((void *)0) );
0
361 buf = *data;-
362-
363#if defined(SSH_TUN_PREPEND_AF)-
364 /* skip address family */-
365 *dlen -= sizeof(af);-
366 buf = *data + sizeof(af);-
367#elif defined(SSH_TUN_COMPAT_AF)-
368 /* translate address family */-
369 af = (PEEK_U32(buf) == OPENBSD_AF_INET6) ? AF_INET6 : AF_INET;-
370 POKE_U32(buf, af);-
371#endif-
372 return (buf);
never executed: return (buf);
0
373}-
374#endif /* SSH_TUN_FILTER */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2