Friday, May 27, 2016

How to Setup L2TP VPN Server on Mac OS X El Capitan (non-server version)

In this post, I will go over how to setup L2TP VPN server on your Mac OS X El Capitan (non-server version). It will be based on the excellent post from Jon but with slight modifications.

Before you start doing this, make sure the following ports are not blocked by your router or ISP.
UDP 500 for ISAKMP/IKE
UDP 1701 for L2TP
UDP 4500 for IPsec NAT Traversal

Usually, you should be able to configure your router to enable these ports for designated IP address. Therefore, you would probably need to assign static IP address for your to-be-server machine first, based on the physical address, and then open up the ports necessary.

Now, let us dive into the setup. First, create /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist file with the following content
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>ActiveServers</key>
  <array>
    <string>com.apple.ppp.l2tp</string>
  </array>
  <key>Servers</key>
  <dict>
    <key>com.apple.ppp.l2tp</key>
    <dict>
      <key>DNS</key>
      <dict>
        <key>OfferedSearchDomains</key>
        <array/>
        <key>OfferedServerAddresses</key>
        <array>
          <string>168.126.63.1</string>
          <string>8.8.4.4</string>
        </array>
      </dict>
      <key>IPv4</key>
      <dict>
        <key>ConfigMethod</key>
        <string>Manual</string>
        <key>DestAddressRanges</key>
        <array>
          <string>192.168.0.201</string>
          <string>192.168.0.255</string>
        </array>
      </dict>
      <key>Interface</key>
      <dict>
        <key>SubType</key>
        <string>L2TP</string>
        <key>Type</key>
        <string>PPP</string>
      </dict>
      <key>L2TP</key>
      <dict>
        <key>IPSecSharedSecret</key>
        <string>com.apple.ppp.l2tp</string>
        <key>IPSecSharedSecretEncryption</key>
        <string>Keychain</string>
        <key>Transport</key>
        <string>IPSec</string>
      </dict>
      <key>PPP</key>
      <dict>
        <key>AuthenticatorACLPlugins</key>
        <array>
          <string>DSACL</string>
        </array>
        <key>AuthenticatorPlugins</key>
        <array>
          <string>DSAuth</string>
        </array>
        <key>AuthenticatorProtocol</key>
        <array>
          <string>PAP</string>
        </array>
        <key>LCPEchoEnabled</key>
        <integer>1</integer>
        <key>LCPEchoFailure</key>
        <integer>5</integer>
        <key>LCPEchoInterval</key>
        <integer>60</integer>
        <key>Logfile</key>
        <string>/var/log/ppp/vpnd.log</string>
        <key>VerboseLogging</key>
        <integer>1</integer>
      </dict>
      <key>Server</key>
      <dict>
        <key>Logfile</key>
        <string>/var/log/ppp/vpnd.log</string>
        <key>MaximumSessions</key>
        <integer>128</integer>
        <key>VerboseLogging</key>
        <integer>1</integer>
      </dict>
    </dict>
  </dict>
</dict>
</plist>
Make modifications in line 19-20 and 29-30. Lines 19-20 will be your DNS addresses whereas lines 29-30 will be the start and end client addresses to be assigned by the server. Make sure that these addresses do not overlap with your router's assignment. 

Next, change the owner of the file by
$ sudo chown root:wheel /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist

and change the access control by
$ sudo chmod 644 /Library/Preferences/SystemConfiguration/com.apple.RemoteAccessServers.plist

Now you will need to provide the L2TP secret phrase. Run the following command where you replace SHARED-SECRET-PHRASE with your own.
$ sudo security add-generic-password -a com.apple.ppp.l2tp -s com.apple.net.racoon -T /usr/sbin/racoon -p "SHARED-SECRET-PHRASE" /Library/Keychains/System.keychain

Create /Library/LaunchDaemons/com.apple.ppp.l2tp.plist with the following content
 <?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN”
“http://www.apple.com/DTDs/PropertyList-1.0.dtd“>
<plist version=”1.0″>
    <dict>
        <key>Label</key>
        <string>com.apple.ppp.l2tp</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/sbin/vpnd</string>
            <string>-x</string>
            <string>-i</string>
            <string>com.apple.ppp.l2tp</string>
        </array>
        <key>OnDemand</key>
        <false/>
    </dict>
</plist>

Finally, you need to load the launchd config and start the daemon after reboot:
$ sudo launchctl load -w /Library/LaunchDaemons/com.apple.ppp.l2tp.plist

If you want to disable VPN service and not start the daemon after reboot, run
$ sudo launchctl unload -w /Library/LaunchDaemons/com.apple.ppp.l2tp.plist

Now, you  should be able to connect to your VPN server! To login, use your Mac OS X's username and password.

Thursday, May 26, 2016

How to Install OPENCV on Mac OS X with libstdc++ for CUDA

Installing opencv on Mac OS X has been painful for me because the older version of CUDA toolkit does not support libc++, while the default compilation option for OS X's clang is to use libc++ instead of libstdc++. Due to this issue, I kept getting errors like
undefined symbols for architecture x86_64: "cv::imread(std::string const&, int)" referenced from ...

So, in this post, I will cover how to install opencv on Mac OS X using libstdc++ and successfully run CUDA programs.

The easiest way is to use homebrew to install opencv. If you already do not have homebrew installed on your Mac OS X system, please refer here.

First, we will need to edit the default make option. To do so, run the command
$ brew tap homebrew/science
$ brew edit opencv

You may want to replace option "32-bit" with option "64-bit" in line 15, although I am not sure if this makes any difference.

Next, add a line with -DCMAKE_CXX_FLAGS:STRING=-stdlib=libstdc++ into line 76, after which it should read something like below:
      args = std_cmake_args + %W[
        -DCMAKE_OSX_DEPLOYMENT_TARGET=
        -DBUILD_ZLIB=OFF
        -DBUILD_TIFF=OFF
        -DBUILD_PNG=OFF
        -DBUILD_OPENEXR=OFF
        -DBUILD_JASPER=OFF
        -DBUILD_JPEG=OFF
        -DCMAKE_CXX_FLAGS:STRING=-stdlib=libstdc++
        -DJPEG_INCLUDE_DIR=#{jpeg.opt_include}
        -DJPEG_LIBRARY=#{jpeg.opt_lib}/libjpeg.#{dylib}
      ]

By the way, this formula file can also be edited by the following command
$ vim /usr/local/Library/Taps/homebrew/homebrew-science/opencv.rb

To restore the file back to the original, you may run
$ cd /usr/local/Library/Taps/homebrew/homebrew-science
$ git checkout -- opencv.rb

To restore all formula files in the folder to the default, you may run
$ git reset --hard HEAD

Now, you may proceed to install opencv, but make sure to compile it from source
$ brew install --build-from-source opencv

Please note that it will take quite some time to build the library, so please be patient. After complete, you may want to verify whether it has been compiled with libstdc++
$ otools -L /usr/local/Cellar/opencv/2.4.12_2/lib/libopencv_imgproc.dylib
libopencv_imgproc.dylib:
/usr/local/opt/opencv/lib/libopencv_imgproc.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/local/Cellar/opencv/2.4.12_2/lib/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.12)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

As you can see, opencv has been compiled against libstdc++ instead of libc++. Now, you will be able to run your CUDA programs. Note, however, that you will need to ask g++ to link against libstdc++ as well. That is, for example, compile with the option as shown below:
$ g++ your_program.cxx -stdlib=libstdc++

How to Run CUDA on Mac

I have a mid-2010 mac mini, which is equipped with NVIDIA's GeForce 320m integrated graphics chip. Although the official list of CUDA-supported devices does not include GeForce 320m, this chip indeed supports CUDA.

To install CUDA driver and toolkit, download the toolkit for Mac OS X platform from NVIDIA's website. Note that I tried installing toolkit v7.5, but it did not work. The older version v6.0 worked fine, so you probably want to download it instead. After download, simply install it on the system. You will notice that, however, it runs very well until you reboot your system.

In order to fix this issue, you will need to do the following:

1. If you are running El Capitan, disable OS X's System Integrity Protection (SIP). See the instructions here.

2. The following instruction was provided by canemacchina from here. I am reproducing it below.

Create /System/Library/LaunchDaemons/com.nvidia.cuda.launchd.plist file with the content

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>com.nvidia.cuda.launchd</string>
        <key>ProgramArguments</key>
        <array>
                <string>/sbin/kextload</string>
                <string>/System/Library/Extensions/CUDA.kext</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
<key>UserName</key>
        <string>root</string>
</dict>
</plist>

Next, set the owner of the file
$ sudo chown 0:0 /System/Library/LaunchDaemons/com.nvidia.cuda.launchd.plist

Finally enable the daemons
$ sudo launchctl load -w /System/Library/LaunchDaemons/com.nvidia.cuda.launchd.plist

That's it. Now you will be able to run CUDA on your old Mac.

How to Mount Mac OS X's HFS+ Partition in Ubuntu 14.04 LTS

To mount HFS+ partition, one first needs to install the necessary package:
$ sudo apt-get install hfsprogs

Next, create the mounting directory
$ sudo mkdir /media/mntpoint

Next, mount the partition
$ sudo mount -t hfsplus -o force,rw /dev/sdXY /media/mntpoint
where sdXY can be something like sda1, sda2, sda3, sdb1, sdb2, sdb3, etc.

To unmount, run the command
$ sudo umount /media/mntpoint

If you are not sure whether the exfat partition you are looking for is /dev/sda1 or /dev/sda2, then you could also run
$ sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL

Thursday, May 19, 2016

Transition from C to C++: Struct vs. Class

Here, I will write about some of the changes that a C programmer should be aware of when transitioning into C++.

Some key differences between class and struct:
  1. In C, struct holds a chunk of data. In C++, class also holds a chunk of data but in addition it also defines some methods related to it.
  2. All the fields in struct is visible to anyone, while the fields are private by default in class.
  3. In C, you need the keyword struct as the identifier, whereas in C++ you do not need the keyword class.
  4. In C++, you also have a static field. However, it needs to be declared globally; Otherwise you will get a linker error.
The following code summarizes the differences:

// C++
class Class {
int data1; // private by default
char data2; // private by default
public:
   static int length; // static variable
class Class* method1() {...}; // public method that returns pointer to Class object.
Class* method2() {...}; // class identifier is not necessary
};

int Class::length; // must declare it globally

// C
struct Struct {
int data1; // public by default
char data2; // public by default
};
struct Struct* func1() {...} // a function that returns a pointer to struct Struct. struct identifier is necessary

Monday, May 16, 2016

How to Disable System Integrity Protection (SIP) on Mac OS X El Capitan

If you want to disable the newly-added but quite annoying feature called the system integrity protection on OS X El Capitan, please follow the procedures below. This security feature disables users--even with the admin privilege--to modify /System, /sbin, and /usr directories, except /usr/local sub-directory.

First, you will need to enter recovery mode. To do this, you can simply press and hold [command] and [R] keys during the boot. However, if you are like me, using a mac mini plugged with a windows keyboard, it will be very difficult to enter recovery mode. In that case, what I did was to continually repeat the cycles of pressing and releasing both [Alt] keys very fast until the boot option menu pops up, at which point I can simply use the arrow keys to select recovery mode.

Second, once you are in the recovery mode, simply run the terminal from the drop down menu. In the terminal, run
# csrutil disable && reboot

You can always enable the feature back by running
# csrutil enable && reboot

Tuesday, May 10, 2016

Tower of Hanoi using Induction and Recursion

Induction is a very powerful method in mathematics; it provides simple yet elegant proofs. One of the most well-known problems that can be very easily tackled using induction is the Tower of Hanoi.

The problem is stated as follows.

There are three identical rods, and we are given N disks of varying sizes. All the disks are initially stacked up onto one of the rods in the descending order of the disk size from bottom to top, i.e., the largest on the bottom and the smallest on the top. We are to move all the disks from one rod to another with three rules:

1. Only one disk can be moved at a time.
2. Only the top-most disk can be moved from one rod and be placed onto a different rod.
3. No disk can be placed on top of a smaller disk.

With these rules, what is the method for moving some arbitrary N disks? What is the minimum number of moves required to do so?

It is rather a difficult problem at first glance. Probably the simplest way to solve this mathematically is by induction.

As with any other mathematical induction problem, one starts with the base case: N=1. We simply move the only disk from one rod to another. That's it. Very simple. So, the it requires f(1)=1 move, where f(n) represents the minimum number of moves required to solve the problem for n disks.

Next, we assume that we have a way of solving the case for some N=n. Utilizing this, can we solve the case for N=n+1? You bet! Assume that initially n+1 disks are stacked onto rod 1. We break the process of moving n+1 disks into three steps:
1. Move the upper n disks to a different rod, say rod 2 using the aforementioned assumption.
2. Move the largest disk to the other rod, say rod 3.
3. Move the n disks on rod 2 onto rod 3, again using the same method.

Note that these processes all obey the three rules for the Tower of Hanoi. In addition, this must be the minimum number of moves; there simply is no way to do it with fewer moves while still obeying the rules.

So, if it requires f(n) moves to solve the problem for the case of N=n, then we readily see that f(n+1)=2*f(n)+1, i.e., it requires 2*f(n)+1 moves to solve the problem for the case of N=n+1. Now, I will argue that f(n)=2^n-1. Let's prove this by induction.

Base case: f(1) = 2^1-1 = 1
Assumption: f(n) = 2^n-1
Next case: f(n+1) = 2*f(n)+1 = 2*(2^n-1)+1 = 2^(n+1)-1

That's it. We have proved it using induction. Now, it is time to implement in program. We do this by recursion. With it, I can get the step by step move instruction for moving, say 4 disks from rod 1 to 3.

$ javac Hanoi.java
$ java Hanoi 4
Move #1: disk1; rod 1==>2
Move #2: disk2; rod 1==>3
Move #3: disk1; rod 2==>3
Move #4: disk3; rod 1==>2
Move #5: disk1; rod 3==>1
Move #6: disk2; rod 3==>2
Move #7: disk1; rod 1==>2
Move #8: disk4; rod 1==>3
Move #9: disk1; rod 2==>3
Move #10: disk2; rod 2==>1
Move #11: disk1; rod 3==>1
Move #12: disk3; rod 2==>3
Move #13: disk1; rod 1==>2
Move #14: disk2; rod 1==>3
Move #15: disk1; rod 2==>3
Total moves required is 15


Below is the implementation in Java.

// Hanoi.java
public class Hanoi
{
  static int moves = 0;

  /** implements the Tower of Hanoi problem via recursion
   *  the argument to the program should be an integer N > 0
   */
  public static void main (String[] args)
  {
    int N;
    if (args.length == 0)
    {
      System.out.println ("Error: Provide a positive integer number N");
      System.exit(-1);
    }

    N = Integer.parseInt(args[0]);
    if (N < 1)
    {
      System.out.println ("Error: N must be positive");
      System.exit(-1);
    }

    int moves = moveDisks (N, 1, 3);
    if (moves != Hanoi.moves)
    {
      System.out.println ("Error: Something is wrong with the implementation!!");
      System.exit(-1);
    }

    System.out.println ("Total moves required is " + moves);
    return;
  }

  /** recursively move n disks to a different rod
   *  three rods are indexed 1,2,3
   *
   * @param n is the number of disks to move
   * @param from is the rod index from which to move
   * @param to is the rod index to which to move
   * @return the minimum number of moves
   */
  static int moveDisks (int n, int from, int to)
  {
    if (n == 1)
    {
      /* base case */
      moves++;
      System.out.println ("Move #" + moves + ": disk1; rod " + from + "==>" + to);
      return 1;
    }

    /* index number of the remaining rod */
    int rem = 1;
    for (int i=1; i<=3; i++)
    {
      if (rem == from || rem == to)
        rem++;
      else
        break;
    }

    /* move n-1 disks from FROM to REM */
    int sum = moveDisks (n-1, from, rem);

    /* move the largest disk */
    moves++;
    System.out.println ("Move #" + moves + ": disk" + n + "; rod " + from + "==>" + to);
    sum++;

    /* move the n-1 disks back from REM to TO */
    sum += moveDisks (n-1, rem, to);

    return sum;
  }
}