See also http://www.whiteboard.ne.jp/~admin2/tuntap/
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Kazuyoshi Aizawa <admin2@whiteboard.ne.jp>
Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
... | ... |
@@ -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,7 +702,13 @@ do_ifconfig (struct tuntap *tt, |
701 | 701 |
); |
702 | 702 |
} |
703 | 703 |
else |
704 |
- no_tap_ifconfig (); |
|
704 |
+ argv_printf (&argv, |
|
705 |
+ " %s %s %s netmask %s broadcast + up", |
|
706 |
+ IFCONFIG_PATH, |
|
707 |
+ actual, |
|
708 |
+ ifconfig_local, |
|
709 |
+ ifconfig_remote_netmask |
|
710 |
+ ); |
|
705 | 711 |
|
706 | 712 |
argv_msg (M_INFO, &argv); |
707 | 713 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed")) |
... | ... |
@@ -1372,15 +1379,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 +1408,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 +1438,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 +1451,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 +1545,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; |