Conflicts:
Makefile.am
openvpn.8
options.c
socket.c
ssl.c
- feat_misc is missing a lot of bugfix2.1 changes
Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
| ... | ... |
@@ -417,6 +417,7 @@ init_proxy_dowork (struct context *c) |
| 417 | 417 |
{
|
| 418 | 418 |
c->c1.socks_proxy = socks_proxy_new (c->options.ce.socks_proxy_server, |
| 419 | 419 |
c->options.ce.socks_proxy_port, |
| 420 |
+ c->options.ce.socks_proxy_authfile, |
|
| 420 | 421 |
c->options.ce.socks_proxy_retry, |
| 421 | 422 |
c->options.auto_proxy_info); |
| 422 | 423 |
if (c->c1.socks_proxy) |
| ... | ... |
@@ -128,8 +128,11 @@ static const char usage_message[] = |
| 128 | 128 |
" AGENT user-agent\n" |
| 129 | 129 |
#endif |
| 130 | 130 |
#ifdef ENABLE_SOCKS |
| 131 |
- "--socks-proxy s [p]: Connect to remote host through a Socks5 proxy at address\n" |
|
| 132 |
- " s and port p (default port = 1080).\n" |
|
| 131 |
+ "--socks-proxy s [p] [up] : Connect to remote host through a Socks5 proxy at\n" |
|
| 132 |
+ " address s and port p (default port = 1080).\n" |
|
| 133 |
+ " If proxy authentication is required,\n" |
|
| 134 |
+ " up is a file containing username/password on 2 lines, or\n" |
|
| 135 |
+ " 'stdin' to prompt for console.\n" |
|
| 133 | 136 |
"--socks-proxy-retry : Retry indefinitely on Socks proxy errors.\n" |
| 134 | 137 |
#endif |
| 135 | 138 |
"--resolv-retry n: If hostname resolve fails for --remote, retry\n" |
| ... | ... |
@@ -4505,6 +4508,7 @@ add_option (struct options *options, |
| 4505 | 4505 |
options->ce.socks_proxy_port = 1080; |
| 4506 | 4506 |
} |
| 4507 | 4507 |
options->ce.socks_proxy_server = p[1]; |
| 4508 |
+ options->ce.socks_proxy_authfile = p[3]; /* might be NULL */ |
|
| 4508 | 4509 |
} |
| 4509 | 4510 |
else if (streq (p[0], "socks-proxy-retry")) |
| 4510 | 4511 |
{
|
| ... | ... |
@@ -952,16 +952,14 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s |
| 952 | 952 |
argv_printf (&argv, "%s add", |
| 953 | 953 |
ROUTE_PATH); |
| 954 | 954 |
|
| 955 |
-#if 0 |
|
| 956 |
- if (r->metric_defined) |
|
| 957 |
- argv_printf_cat (&argv, "-rtt %d", r->metric); |
|
| 958 |
-#endif |
|
| 959 |
- |
|
| 960 | 955 |
argv_printf_cat (&argv, "%s -netmask %s %s", |
| 961 | 956 |
network, |
| 962 | 957 |
netmask, |
| 963 | 958 |
gateway); |
| 964 | 959 |
|
| 960 |
+ if (r->metric_defined) |
|
| 961 |
+ argv_printf_cat (&argv, "%d", r->metric); |
|
| 962 |
+ |
|
| 965 | 963 |
argv_msg (D_ROUTE, &argv); |
| 966 | 964 |
status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add command failed"); |
| 967 | 965 |
|
| ... | ... |
@@ -23,10 +23,11 @@ |
| 23 | 23 |
*/ |
| 24 | 24 |
|
| 25 | 25 |
/* |
| 26 |
- * 2004-01-30: Added Socks5 proxy support |
|
| 26 |
+ * 2004-01-30: Added Socks5 proxy support, see RFC 1928 |
|
| 27 | 27 |
* (Christof Meerwald, http://cmeerw.org) |
| 28 | 28 |
* |
| 29 |
- * see RFC 1928, only supports "no authentication" |
|
| 29 |
+ * 2010-10-10: Added Socks5 plain text authentication support (RFC 1929) |
|
| 30 |
+ * (Pierre Bourdon <delroth@gmail.com>) |
|
| 30 | 31 |
*/ |
| 31 | 32 |
|
| 32 | 33 |
#include "syshead.h" |
| ... | ... |
@@ -38,10 +39,12 @@ |
| 38 | 38 |
#include "win32.h" |
| 39 | 39 |
#include "socket.h" |
| 40 | 40 |
#include "fdmisc.h" |
| 41 |
+#include "misc.h" |
|
| 41 | 42 |
#include "proxy.h" |
| 42 | 43 |
|
| 43 | 44 |
#include "memdbg.h" |
| 44 | 45 |
|
| 46 |
+#define UP_TYPE_SOCKS "SOCKS Proxy" |
|
| 45 | 47 |
|
| 46 | 48 |
void |
| 47 | 49 |
socks_adjust_frame_parameters (struct frame *frame, int proto) |
| ... | ... |
@@ -53,6 +56,7 @@ socks_adjust_frame_parameters (struct frame *frame, int proto) |
| 53 | 53 |
struct socks_proxy_info * |
| 54 | 54 |
socks_proxy_new (const char *server, |
| 55 | 55 |
int port, |
| 56 |
+ const char *authfile, |
|
| 56 | 57 |
bool retry, |
| 57 | 58 |
struct auto_proxy_info *auto_proxy_info) |
| 58 | 59 |
{
|
| ... | ... |
@@ -77,6 +81,12 @@ socks_proxy_new (const char *server, |
| 77 | 77 |
|
| 78 | 78 |
strncpynt (p->server, server, sizeof (p->server)); |
| 79 | 79 |
p->port = port; |
| 80 |
+ |
|
| 81 |
+ if (authfile) |
|
| 82 |
+ strncpynt (p->authfile, authfile, sizeof (p->authfile)); |
|
| 83 |
+ else |
|
| 84 |
+ p->authfile[0] = 0; |
|
| 85 |
+ |
|
| 80 | 86 |
p->retry = retry; |
| 81 | 87 |
p->defined = true; |
| 82 | 88 |
|
| ... | ... |
@@ -90,15 +100,99 @@ socks_proxy_close (struct socks_proxy_info *sp) |
| 90 | 90 |
} |
| 91 | 91 |
|
| 92 | 92 |
static bool |
| 93 |
-socks_handshake (socket_descriptor_t sd, volatile int *signal_received) |
|
| 93 |
+socks_username_password_auth (struct socks_proxy_info *p, |
|
| 94 |
+ socket_descriptor_t sd, |
|
| 95 |
+ volatile int *signal_received) |
|
| 96 |
+{
|
|
| 97 |
+ char to_send[516]; |
|
| 98 |
+ char buf[2]; |
|
| 99 |
+ int len = 0; |
|
| 100 |
+ const int timeout_sec = 5; |
|
| 101 |
+ struct user_pass creds; |
|
| 102 |
+ ssize_t size; |
|
| 103 |
+ |
|
| 104 |
+ creds.defined = 0; |
|
| 105 |
+ |
|
| 106 |
+ get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT); |
|
| 107 |
+ snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", strlen(creds.username), |
|
| 108 |
+ creds.username, strlen(creds.password), creds.password); |
|
| 109 |
+ size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL); |
|
| 110 |
+ |
|
| 111 |
+ if (size != strlen (to_send)) |
|
| 112 |
+ {
|
|
| 113 |
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port write failed on send()"); |
|
| 114 |
+ return false; |
|
| 115 |
+ } |
|
| 116 |
+ |
|
| 117 |
+ while (len < 2) |
|
| 118 |
+ {
|
|
| 119 |
+ int status; |
|
| 120 |
+ ssize_t size; |
|
| 121 |
+ fd_set reads; |
|
| 122 |
+ struct timeval tv; |
|
| 123 |
+ char c; |
|
| 124 |
+ |
|
| 125 |
+ FD_ZERO (&reads); |
|
| 126 |
+ FD_SET (sd, &reads); |
|
| 127 |
+ tv.tv_sec = timeout_sec; |
|
| 128 |
+ tv.tv_usec = 0; |
|
| 129 |
+ |
|
| 130 |
+ status = select (sd + 1, &reads, NULL, NULL, &tv); |
|
| 131 |
+ |
|
| 132 |
+ get_signal (signal_received); |
|
| 133 |
+ if (*signal_received) |
|
| 134 |
+ return false; |
|
| 135 |
+ |
|
| 136 |
+ /* timeout? */ |
|
| 137 |
+ if (status == 0) |
|
| 138 |
+ {
|
|
| 139 |
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read timeout expired"); |
|
| 140 |
+ return false; |
|
| 141 |
+ } |
|
| 142 |
+ |
|
| 143 |
+ /* error */ |
|
| 144 |
+ if (status < 0) |
|
| 145 |
+ {
|
|
| 146 |
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on select()"); |
|
| 147 |
+ return false; |
|
| 148 |
+ } |
|
| 149 |
+ |
|
| 150 |
+ /* read single char */ |
|
| 151 |
+ size = recv(sd, &c, 1, MSG_NOSIGNAL); |
|
| 152 |
+ |
|
| 153 |
+ /* error? */ |
|
| 154 |
+ if (size != 1) |
|
| 155 |
+ {
|
|
| 156 |
+ msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on recv()"); |
|
| 157 |
+ return false; |
|
| 158 |
+ } |
|
| 159 |
+ |
|
| 160 |
+ /* store char in buffer */ |
|
| 161 |
+ buf[len++] = c; |
|
| 162 |
+ } |
|
| 163 |
+ |
|
| 164 |
+ /* VER = 5, SUCCESS = 0 --> auth success */ |
|
| 165 |
+ if (buf[0] != 5 && buf[1] != 0) |
|
| 166 |
+ {
|
|
| 167 |
+ msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication"); |
|
| 168 |
+ return false; |
|
| 169 |
+ } |
|
| 170 |
+ |
|
| 171 |
+ return true; |
|
| 172 |
+} |
|
| 173 |
+ |
|
| 174 |
+static bool |
|
| 175 |
+socks_handshake (struct socks_proxy_info *p, |
|
| 176 |
+ socket_descriptor_t sd, |
|
| 177 |
+ volatile int *signal_received) |
|
| 94 | 178 |
{
|
| 95 | 179 |
char buf[2]; |
| 96 | 180 |
int len = 0; |
| 97 | 181 |
const int timeout_sec = 5; |
| 98 | 182 |
|
| 99 |
- /* VER = 5, NMETHODS = 1, METHODS = [0] */ |
|
| 100 |
- const ssize_t size = send (sd, "\x05\x01\x00", 3, MSG_NOSIGNAL); |
|
| 101 |
- if (size != 3) |
|
| 183 |
+ /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */ |
|
| 184 |
+ const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL); |
|
| 185 |
+ if (size != 4) |
|
| 102 | 186 |
{
|
| 103 | 187 |
msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port write failed on send()"); |
| 104 | 188 |
return false; |
| ... | ... |
@@ -151,13 +245,37 @@ socks_handshake (socket_descriptor_t sd, volatile int *signal_received) |
| 151 | 151 |
buf[len++] = c; |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 |
- /* VER == 5 && METHOD == 0 */ |
|
| 155 |
- if (buf[0] != '\x05' || buf[1] != '\x00') |
|
| 154 |
+ /* VER == 5 */ |
|
| 155 |
+ if (buf[0] != '\x05') |
|
| 156 | 156 |
{
|
| 157 | 157 |
msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status"); |
| 158 | 158 |
return false; |
| 159 | 159 |
} |
| 160 | 160 |
|
| 161 |
+ /* select the appropriate authentication method */ |
|
| 162 |
+ switch (buf[1]) |
|
| 163 |
+ {
|
|
| 164 |
+ case 0: /* no authentication */ |
|
| 165 |
+ break; |
|
| 166 |
+ |
|
| 167 |
+ case 2: /* login/password */ |
|
| 168 |
+ if (!p->authfile[0]) |
|
| 169 |
+ {
|
|
| 170 |
+ msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were " |
|
| 171 |
+ "not provided any credentials"); |
|
| 172 |
+ return false; |
|
| 173 |
+ } |
|
| 174 |
+ |
|
| 175 |
+ if (!socks_username_password_auth(p, sd, signal_received)) |
|
| 176 |
+ return false; |
|
| 177 |
+ |
|
| 178 |
+ break; |
|
| 179 |
+ |
|
| 180 |
+ default: /* unknown auth method */ |
|
| 181 |
+ msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method"); |
|
| 182 |
+ return false; |
|
| 183 |
+ } |
|
| 184 |
+ |
|
| 161 | 185 |
return true; |
| 162 | 186 |
} |
| 163 | 187 |
|
| ... | ... |
@@ -281,7 +399,7 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p, |
| 281 | 281 |
char buf[128]; |
| 282 | 282 |
size_t len; |
| 283 | 283 |
|
| 284 |
- if (!socks_handshake (sd, signal_received)) |
|
| 284 |
+ if (!socks_handshake (p, sd, signal_received)) |
|
| 285 | 285 |
goto error; |
| 286 | 286 |
|
| 287 | 287 |
/* format Socks CONNECT message */ |
| ... | ... |
@@ -328,7 +446,7 @@ establish_socks_proxy_udpassoc (struct socks_proxy_info *p, |
| 328 | 328 |
struct openvpn_sockaddr *relay_addr, |
| 329 | 329 |
volatile int *signal_received) |
| 330 | 330 |
{
|
| 331 |
- if (!socks_handshake (ctrl_sd, signal_received)) |
|
| 331 |
+ if (!socks_handshake (p, ctrl_sd, signal_received)) |
|
| 332 | 332 |
goto error; |
| 333 | 333 |
|
| 334 | 334 |
{
|
| ... | ... |
@@ -43,12 +43,14 @@ struct socks_proxy_info {
|
| 43 | 43 |
|
| 44 | 44 |
char server[128]; |
| 45 | 45 |
int port; |
| 46 |
+ char authfile[256]; |
|
| 46 | 47 |
}; |
| 47 | 48 |
|
| 48 | 49 |
void socks_adjust_frame_parameters (struct frame *frame, int proto); |
| 49 | 50 |
|
| 50 | 51 |
struct socks_proxy_info *socks_proxy_new (const char *server, |
| 51 | 52 |
int port, |
| 53 |
+ const char *authfile, |
|
| 52 | 54 |
bool retry, |
| 53 | 55 |
struct auto_proxy_info *auto_proxy_info); |
| 54 | 56 |
|
| ... | ... |
@@ -63,6 +63,7 @@ static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc); |
| 63 | 63 |
|
| 64 | 64 |
#ifdef TARGET_SOLARIS |
| 65 | 65 |
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual); |
| 66 |
+#include <stropts.h> |
|
| 66 | 67 |
#endif |
| 67 | 68 |
|
| 68 | 69 |
bool |
| ... | ... |
@@ -701,12 +702,45 @@ do_ifconfig (struct tuntap *tt, |
| 701 | 701 |
); |
| 702 | 702 |
} |
| 703 | 703 |
else |
| 704 |
- no_tap_ifconfig (); |
|
| 704 |
+ if (tt->topology == TOP_SUBNET) |
|
| 705 |
+ {
|
|
| 706 |
+ argv_printf (&argv, |
|
| 707 |
+ "%s %s %s %s netmask %s mtu %d up", |
|
| 708 |
+ IFCONFIG_PATH, |
|
| 709 |
+ actual, |
|
| 710 |
+ ifconfig_local, |
|
| 711 |
+ ifconfig_local, |
|
| 712 |
+ ifconfig_remote_netmask, |
|
| 713 |
+ tun_mtu |
|
| 714 |
+ ); |
|
| 715 |
+ } |
|
| 716 |
+ else |
|
| 717 |
+ argv_printf (&argv, |
|
| 718 |
+ " %s %s %s netmask %s broadcast + up", |
|
| 719 |
+ IFCONFIG_PATH, |
|
| 720 |
+ actual, |
|
| 721 |
+ ifconfig_local, |
|
| 722 |
+ ifconfig_remote_netmask |
|
| 723 |
+ ); |
|
| 705 | 724 |
|
| 706 | 725 |
argv_msg (M_INFO, &argv); |
| 707 | 726 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed")) |
| 708 | 727 |
solaris_error_close (tt, es, actual); |
| 709 | 728 |
|
| 729 |
+ if (!tun && tt->topology == TOP_SUBNET) |
|
| 730 |
+ {
|
|
| 731 |
+ /* Add a network route for the local tun interface */ |
|
| 732 |
+ struct route r; |
|
| 733 |
+ CLEAR (r); |
|
| 734 |
+ r.defined = true; |
|
| 735 |
+ r.network = tt->local & tt->remote_netmask; |
|
| 736 |
+ r.netmask = tt->remote_netmask; |
|
| 737 |
+ r.gateway = tt->local; |
|
| 738 |
+ r.metric_defined = true; |
|
| 739 |
+ r.metric = 0; |
|
| 740 |
+ add_route (&r, tt, 0, es); |
|
| 741 |
+ } |
|
| 742 |
+ |
|
| 710 | 743 |
tt->did_ifconfig = true; |
| 711 | 744 |
|
| 712 | 745 |
#elif defined(TARGET_OPENBSD) |
| ... | ... |
@@ -1372,15 +1406,17 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) |
| 1372 | 1372 |
void |
| 1373 | 1373 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
| 1374 | 1374 |
{
|
| 1375 |
- int if_fd, muxid, ppa = -1; |
|
| 1376 |
- struct ifreq ifr; |
|
| 1375 |
+ int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1; |
|
| 1376 |
+ struct lifreq ifr; |
|
| 1377 | 1377 |
const char *ptr; |
| 1378 |
- const char *ip_node; |
|
| 1378 |
+ const char *ip_node, *arp_node; |
|
| 1379 | 1379 |
const char *dev_tuntap_type; |
| 1380 | 1380 |
int link_type; |
| 1381 | 1381 |
bool is_tun; |
| 1382 |
+ struct strioctl strioc_if, strioc_ppa; |
|
| 1382 | 1383 |
|
| 1383 |
- ipv6_support (ipv6, false, tt); |
|
| 1384 |
+ ipv6_support (ipv6, true, tt); |
|
| 1385 |
+ memset(&ifr, 0x0, sizeof(ifr)); |
|
| 1384 | 1386 |
|
| 1385 | 1387 |
if (tt->type == DEV_TYPE_NULL) |
| 1386 | 1388 |
{
|
| ... | ... |
@@ -1399,9 +1435,10 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 1399 | 1399 |
} |
| 1400 | 1400 |
else if (tt->type == DEV_TYPE_TAP) |
| 1401 | 1401 |
{
|
| 1402 |
- ip_node = "/dev/ip"; |
|
| 1402 |
+ ip_node = "/dev/udp"; |
|
| 1403 | 1403 |
if (!dev_node) |
| 1404 | 1404 |
dev_node = "/dev/tap"; |
| 1405 |
+ arp_node = dev_node; |
|
| 1405 | 1406 |
dev_tuntap_type = "tap"; |
| 1406 | 1407 |
link_type = I_PLINK; /* was: I_LINK */ |
| 1407 | 1408 |
is_tun = false; |
| ... | ... |
@@ -1428,7 +1465,11 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 1428 | 1428 |
msg (M_ERR, "Can't open %s", dev_node); |
| 1429 | 1429 |
|
| 1430 | 1430 |
/* Assign a new PPA and get its unit number. */ |
| 1431 |
- if ((ppa = ioctl (tt->fd, TUNNEWPPA, ppa)) < 0) |
|
| 1431 |
+ strioc_ppa.ic_cmd = TUNNEWPPA; |
|
| 1432 |
+ strioc_ppa.ic_timout = 0; |
|
| 1433 |
+ strioc_ppa.ic_len = sizeof(ppa); |
|
| 1434 |
+ strioc_ppa.ic_dp = (char *)&ppa; |
|
| 1435 |
+ if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0) |
|
| 1432 | 1436 |
msg (M_ERR, "Can't assign new interface"); |
| 1433 | 1437 |
|
| 1434 | 1438 |
if ((if_fd = open (dev_node, O_RDWR, 0)) < 0) |
| ... | ... |
@@ -1437,27 +1478,83 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6 |
| 1437 | 1437 |
if (ioctl (if_fd, I_PUSH, "ip") < 0) |
| 1438 | 1438 |
msg (M_ERR, "Can't push IP module"); |
| 1439 | 1439 |
|
| 1440 |
+ if (tt->type == DEV_TYPE_TUN) |
|
| 1441 |
+ {
|
|
| 1440 | 1442 |
/* Assign ppa according to the unit number returned by tun device */ |
| 1441 | 1443 |
if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0) |
| 1442 | 1444 |
msg (M_ERR, "Can't set PPA %d", ppa); |
| 1443 |
- |
|
| 1444 |
- if ((muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0) |
|
| 1445 |
- msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type); |
|
| 1446 |
- |
|
| 1447 |
- close (if_fd); |
|
| 1445 |
+ } |
|
| 1448 | 1446 |
|
| 1449 | 1447 |
tt->actual_name = (char *) malloc (32); |
| 1450 | 1448 |
check_malloc_return (tt->actual_name); |
| 1451 | 1449 |
|
| 1452 | 1450 |
openvpn_snprintf (tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa); |
| 1453 | 1451 |
|
| 1452 |
+ if (tt->type == DEV_TYPE_TAP) |
|
| 1453 |
+ {
|
|
| 1454 |
+ if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) |
|
| 1455 |
+ msg (M_ERR, "Can't get flags\n"); |
|
| 1456 |
+ strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name)); |
|
| 1457 |
+ ifr.lifr_ppa = ppa; |
|
| 1458 |
+ /* Assign ppa according to the unit number returned by tun device */ |
|
| 1459 |
+ if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0) |
|
| 1460 |
+ msg (M_ERR, "Can't set PPA %d", ppa); |
|
| 1461 |
+ if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0) |
|
| 1462 |
+ msg (M_ERR, "Can't get flags\n"); |
|
| 1463 |
+ /* Push arp module to if_fd */ |
|
| 1464 |
+ if (ioctl (if_fd, I_PUSH, "arp") < 0) |
|
| 1465 |
+ msg (M_ERR, "Can't push ARP module"); |
|
| 1466 |
+ |
|
| 1467 |
+ /* Pop any modules on the stream */ |
|
| 1468 |
+ while (true) |
|
| 1469 |
+ {
|
|
| 1470 |
+ if (ioctl (tt->ip_fd, I_POP, NULL) < 0) |
|
| 1471 |
+ break; |
|
| 1472 |
+ } |
|
| 1473 |
+ /* Push arp module to ip_fd */ |
|
| 1474 |
+ if (ioctl (tt->ip_fd, I_PUSH, "arp") < 0) |
|
| 1475 |
+ msg (M_ERR, "Can't push ARP module\n"); |
|
| 1476 |
+ |
|
| 1477 |
+ /* Open arp_fd */ |
|
| 1478 |
+ if ((arp_fd = open (arp_node, O_RDWR, 0)) < 0) |
|
| 1479 |
+ msg (M_ERR, "Can't open %s\n", arp_node); |
|
| 1480 |
+ /* Push arp module to arp_fd */ |
|
| 1481 |
+ if (ioctl (arp_fd, I_PUSH, "arp") < 0) |
|
| 1482 |
+ msg (M_ERR, "Can't push ARP module\n"); |
|
| 1483 |
+ |
|
| 1484 |
+ /* Set ifname to arp */ |
|
| 1485 |
+ strioc_if.ic_cmd = SIOCSLIFNAME; |
|
| 1486 |
+ strioc_if.ic_timout = 0; |
|
| 1487 |
+ strioc_if.ic_len = sizeof(ifr); |
|
| 1488 |
+ strioc_if.ic_dp = (char *)𝔦 |
|
| 1489 |
+ if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
|
|
| 1490 |
+ msg (M_ERR, "Can't set ifname to arp\n"); |
|
| 1491 |
+ } |
|
| 1492 |
+ } |
|
| 1493 |
+ |
|
| 1494 |
+ if ((ip_muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0) |
|
| 1495 |
+ msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type); |
|
| 1496 |
+ |
|
| 1497 |
+ if (tt->type == DEV_TYPE_TAP) {
|
|
| 1498 |
+ if ((arp_muxid = ioctl (tt->ip_fd, link_type, arp_fd)) < 0) |
|
| 1499 |
+ msg (M_ERR, "Can't link %s device to ARP", dev_tuntap_type); |
|
| 1500 |
+ close (arp_fd); |
|
| 1501 |
+ } |
|
| 1502 |
+ |
|
| 1454 | 1503 |
CLEAR (ifr); |
| 1455 |
- strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name)); |
|
| 1456 |
- ifr.ifr_ip_muxid = muxid; |
|
| 1504 |
+ strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name)); |
|
| 1505 |
+ ifr.lifr_ip_muxid = ip_muxid; |
|
| 1506 |
+ if (tt->type == DEV_TYPE_TAP) {
|
|
| 1507 |
+ ifr.lifr_arp_muxid = arp_muxid; |
|
| 1508 |
+ } |
|
| 1457 | 1509 |
|
| 1458 |
- if (ioctl (tt->ip_fd, SIOCSIFMUXID, &ifr) < 0) |
|
| 1510 |
+ if (ioctl (tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0) |
|
| 1459 | 1511 |
{
|
| 1460 |
- ioctl (tt->ip_fd, I_PUNLINK, muxid); |
|
| 1512 |
+ if (tt->type == DEV_TYPE_TAP) |
|
| 1513 |
+ {
|
|
| 1514 |
+ ioctl (tt->ip_fd, I_PUNLINK , arp_muxid); |
|
| 1515 |
+ } |
|
| 1516 |
+ ioctl (tt->ip_fd, I_PUNLINK, ip_muxid); |
|
| 1461 | 1517 |
msg (M_ERR, "Can't set multiplexor id"); |
| 1462 | 1518 |
} |
| 1463 | 1519 |
|
| ... | ... |
@@ -1475,18 +1572,24 @@ solaris_close_tun (struct tuntap *tt) |
| 1475 | 1475 |
{
|
| 1476 | 1476 |
if (tt->ip_fd >= 0) |
| 1477 | 1477 |
{
|
| 1478 |
- struct ifreq ifr; |
|
| 1478 |
+ struct lifreq ifr; |
|
| 1479 | 1479 |
CLEAR (ifr); |
| 1480 |
- strncpynt (ifr.ifr_name, tt->actual_name, sizeof (ifr.ifr_name)); |
|
| 1480 |
+ strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name)); |
|
| 1481 | 1481 |
|
| 1482 |
- if (ioctl (tt->ip_fd, SIOCGIFFLAGS, &ifr) < 0) |
|
| 1482 |
+ if (ioctl (tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0) |
|
| 1483 | 1483 |
msg (M_WARN | M_ERRNO, "Can't get iface flags"); |
| 1484 | 1484 |
|
| 1485 |
- if (ioctl (tt->ip_fd, SIOCGIFMUXID, &ifr) < 0) |
|
| 1485 |
+ if (ioctl (tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0) |
|
| 1486 | 1486 |
msg (M_WARN | M_ERRNO, "Can't get multiplexor id"); |
| 1487 | 1487 |
|
| 1488 |
- if (ioctl (tt->ip_fd, I_PUNLINK, ifr.ifr_ip_muxid) < 0) |
|
| 1489 |
- msg (M_WARN | M_ERRNO, "Can't unlink interface"); |
|
| 1488 |
+ if (tt->type == DEV_TYPE_TAP) |
|
| 1489 |
+ {
|
|
| 1490 |
+ if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0) |
|
| 1491 |
+ msg (M_WARN | M_ERRNO, "Can't unlink interface(arp)"); |
|
| 1492 |
+ } |
|
| 1493 |
+ |
|
| 1494 |
+ if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0) |
|
| 1495 |
+ msg (M_WARN | M_ERRNO, "Can't unlink interface(ip)"); |
|
| 1490 | 1496 |
|
| 1491 | 1497 |
close (tt->ip_fd); |
| 1492 | 1498 |
tt->ip_fd = -1; |