Browse code

Integrate support for TAP mode on Solaris, written by Kazuyoshi Aizawa <admin2@whiteboard.ne.jp>.

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>

Gert Doering authored on 2010/10/30 00:41:53
Showing 1 changed files
... ...
@@ -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 *)&ifr;
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;