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; |