
diff -crB shrewsoft/source/iked/CMakeLists.txt shrewsoft.new/source/iked/CMakeLists.txt
*** shrewsoft/source/iked/CMakeLists.txt	2011-11-04 11:43:58.000000000 -0700
--- shrewsoft.new/source/iked/CMakeLists.txt	2011-11-04 11:56:18.000000000 -0700
***************
*** 65,70 ****
--- 65,81 ----
  	iked.cpp
  	main.cpp )
  
+ if( APPLE )
+     include_directories ( /Developer/Headers/FlatCarbon )
+     find_library( CORE_SERVICES CoreServices )
+     find_library( SYSTEM_CONFIGURATION SystemConfiguration )
+     target_link_libraries(
+         iked
+         ${CORE_SERVICES}
+         ${SYSTEM_CONFIGURATION} )
+ endif( APPLE )
+ 
+ 
  target_link_libraries(
  	iked
  	ss_ike

diff -crB shrewsoft/source/iked/ike.socket.cpp shrewsoft.new/source/iked/ike.socket.cpp
*** shrewsoft/source/iked/ike.socket.cpp	2011-11-04 11:43:58.000000000 -0700
--- shrewsoft.new/source/iked/ike.socket.cpp	2011-11-04 11:53:38.000000000 -0700
***************
*** 843,903 ****
  			tunnel->adapter->name );
  	}
  
! 	if( tunnel->xconf.opts & ( IPSEC_OPTS_DNSS | IPSEC_OPTS_DOMAIN ) )
  	{
  		// backup the current resolv.conf file
! 
  		rename( "/etc/resolv.conf", "/etc/resolv.iked" );
! 
  		FILE * fp1 = fopen( "/etc/resolv.iked", "r" );
  		FILE * fp2 = fopen( "/etc/resolv.conf", "w+" );
! 
  		if( fp2 != NULL )
  		{
  			// write configuration
! 
  			if( tunnel->xconf.opts & IPSEC_OPTS_DOMAIN )
  				fprintf( fp2, "domain\t%s\n", tunnel->xconf.nscfg.dnss_suffix );
! 
  			if( tunnel->xconf.opts & IPSEC_OPTS_DNSS )
  				for( int i = 0; i < tunnel->xconf.nscfg.dnss_count; i++ )
  					fprintf( fp2, "nameserver\t%s\n",
! 						inet_ntoa( tunnel->xconf.nscfg.dnss_list[ i ] ) );
! 
  			if( fp1 != NULL )
  			{
  				// merge additional options
! 
  				char line[ 1024 ];
! 
  				while( fgets( line, sizeof( line ), fp1 ) != NULL )
  				{
  					if( !strncmp( line, "domain", 6 ) )
  					{
  						if( !( tunnel->xconf.opts & IPSEC_OPTS_DOMAIN ) )
  							fwrite( line, strlen( line ), 1, fp2 );
! 
  						continue;
  					}
! 
  					if( !strncmp( line, "nameserver", 9 ) )
  					{
  						if( !( tunnel->xconf.opts & IPSEC_OPTS_DNSS ) )
  							fwrite( line, strlen( line ), 1, fp2 );
! 
  						continue;
  					}
! 
  					fwrite( line, strlen( line ), 1, fp2 );
  				}
! 
  				fclose( fp1 );
  			}
! 
  			fclose( fp2 );
  		}
  	}
! 
  	return true;
  }
  
--- 843,960 ----
  			tunnel->adapter->name );
  	}
  
!     if( tunnel->xconf.opts & ( IPSEC_OPTS_DNSS | IPSEC_OPTS_DOMAIN ) )
  	{
+         
  		// backup the current resolv.conf file
! #ifndef __APPLE__
  		rename( "/etc/resolv.conf", "/etc/resolv.iked" );
!         
  		FILE * fp1 = fopen( "/etc/resolv.iked", "r" );
  		FILE * fp2 = fopen( "/etc/resolv.conf", "w+" );
!         
  		if( fp2 != NULL )
  		{
  			// write configuration
!             
  			if( tunnel->xconf.opts & IPSEC_OPTS_DOMAIN )
  				fprintf( fp2, "domain\t%s\n", tunnel->xconf.nscfg.dnss_suffix );
!             
  			if( tunnel->xconf.opts & IPSEC_OPTS_DNSS )
  				for( int i = 0; i < tunnel->xconf.nscfg.dnss_count; i++ )
  					fprintf( fp2, "nameserver\t%s\n",
!                             inet_ntoa( tunnel->xconf.nscfg.dnss_list[ i ] ) );
!             
  			if( fp1 != NULL )
  			{
  				// merge additional options
!                 
  				char line[ 1024 ];
!                 
  				while( fgets( line, sizeof( line ), fp1 ) != NULL )
  				{
  					if( !strncmp( line, "domain", 6 ) )
  					{
  						if( !( tunnel->xconf.opts & IPSEC_OPTS_DOMAIN ) )
  							fwrite( line, strlen( line ), 1, fp2 );
!                         
  						continue;
  					}
!                     
  					if( !strncmp( line, "nameserver", 9 ) )
  					{
  						if( !( tunnel->xconf.opts & IPSEC_OPTS_DNSS ) )
  							fwrite( line, strlen( line ), 1, fp2 );
!                         
  						continue;
  					}
!                     
  					fwrite( line, strlen( line ), 1, fp2 );
  				}
!                 
  				fclose( fp1 );
  			}
!             
  			fclose( fp2 );
  		}
+ #else
+         
+         //use SystemConfigurationFramework on OSX
+         //see:
+         //  http://developer.apple.com/library/mac/#documentation/Networking/Reference/SCDynamicStore/Reference/reference.html#//apple_ref/doc/uid/TP40008287
+         //  http://hints.macworld.com/article.php?story=20050621051643993
+         
+         printf("set dns settings\n");
+         //get current settings
+         SCDynamicStoreRef dynRef=SCDynamicStoreCreate(kCFAllocatorSystemDefault, CFSTR("iked"), NULL, NULL);
+         CFDictionaryRef ipv4key = (CFDictionaryRef)SCDynamicStoreCopyValue(dynRef,CFSTR("State:/Network/Global/IPv4"));
+         CFStringRef primaryserviceid = (CFStringRef)CFDictionaryGetValue(ipv4key,CFSTR("PrimaryService"));
+         CFStringRef primaryservicepath = CFStringCreateWithFormat(NULL,NULL,CFSTR("State:/Network/Service/%@/DNS"),primaryserviceid);
+         CFDictionaryRef dnskey = (CFDictionaryRef)SCDynamicStoreCopyValue(dynRef,primaryservicepath);
+         CFMutableDictionaryRef newdnskey = CFDictionaryCreateMutableCopy(NULL,0,dnskey);
+         
+         
+         //store current config for cleanup
+         this->dnsconfig = CFDictionaryCreateCopy(NULL,dnskey);
+         
+         //create new values
+         CFMutableArrayRef dnsserveraddresses = NULL;
+         if( tunnel->xconf.opts & IPSEC_OPTS_DOMAIN ){
+             CFStringRef domainname = CFStringCreateWithCString(NULL,
+                                                                tunnel->xconf.nscfg.dnss_suffix,
+                                                                kCFStringEncodingMacRoman);
+             
+             CFDictionarySetValue(newdnskey,CFSTR("DomainName"),domainname);
+             CFRelease(domainname);
+         }
+         
+         if( tunnel->xconf.opts & IPSEC_OPTS_DNSS ){
+             dnsserveraddresses = CFArrayCreateMutable(NULL,0,NULL);
+             for( int i = 0; i < tunnel->xconf.nscfg.dnss_count; i++ ){
+                 CFStringRef dnsserveraddress = CFStringCreateWithCString(NULL,
+                                                                          inet_ntoa( tunnel->xconf.nscfg.dnss_list[ i ] ),
+                                                                          kCFStringEncodingMacRoman);
+                 CFArrayAppendValue(dnsserveraddresses, dnsserveraddress) ;
+                 //CFRelease(dnsserveraddress);
+             }
+             CFDictionarySetValue(newdnskey, CFSTR("ServerAddresses"), dnsserveraddresses);
+         }
+         
+         //set values
+         SCDynamicStoreSetValue(dynRef, primaryservicepath, newdnskey);
+         
+         //clean up
+         CFRelease(dynRef);
+         CFRelease(newdnskey);
+         CFRelease(dnsserveraddresses);
+         CFRelease(primaryservicepath);
+         CFRelease(ipv4key);
+         CFRelease(dnskey);
+         
+ #endif //__APPLE__
+         
  	}
!     
  	return true;
  }
  
***************
*** 905,915 ****
  {
  	if( tunnel->xconf.opts & ( IPSEC_OPTS_DNSS | IPSEC_OPTS_DOMAIN ) )
  	{
  		// restore the previous resolv.conf file
! 
  		rename( "/etc/resolv.iked", "/etc/resolv.conf" );
! 	}
! 
  	if( tunnel->xconf.opts & IPSEC_OPTS_ADDR )
  	{
  		if( tunnel->adapter != NULL )
--- 962,988 ----
  {
  	if( tunnel->xconf.opts & ( IPSEC_OPTS_DNSS | IPSEC_OPTS_DOMAIN ) )
  	{
+ #ifndef __APPLE__
  		// restore the previous resolv.conf file
!         
  		rename( "/etc/resolv.iked", "/etc/resolv.conf" );
! #else
!         if(this->dnsconfig){
!             SCDynamicStoreRef dynRef=SCDynamicStoreCreate(kCFAllocatorSystemDefault, CFSTR("iked"), NULL, NULL);
!             CFDictionaryRef ipv4key = (CFDictionaryRef)SCDynamicStoreCopyValue(dynRef,CFSTR("State:/Network/Global/IPv4"));
!             CFStringRef primaryserviceid = (CFStringRef)CFDictionaryGetValue(ipv4key,CFSTR("PrimaryService"));
!             CFStringRef primaryservicepath = CFStringCreateWithFormat(NULL,NULL,CFSTR("State:/Network/Service/%@/DNS"),primaryserviceid);
!             SCDynamicStoreSetValue(dynRef, primaryservicepath, this->dnsconfig);
!             
!             CFRelease(this->dnsconfig);
!             CFRelease(dynRef);
!             CFRelease(ipv4key);
!             CFRelease(primaryservicepath);
!         }
!         
! #endif
!     }
!     
  	if( tunnel->xconf.opts & IPSEC_OPTS_ADDR )
  	{
  		if( tunnel->adapter != NULL )
***************
*** 918,923 ****
  			tunnel->adapter = NULL;
  		}
  	}
! 
  	return true;
  }
--- 991,996 ----
  			tunnel->adapter = NULL;
  		}
  	}
!     
  	return true;
  }

diff -crB shrewsoft/source/iked/iked.h shrewsoft.new/source/iked/iked.h
*** shrewsoft/source/iked/iked.h	2011-11-04 11:43:58.000000000 -0700
--- shrewsoft.new/source/iked/iked.h	2011-11-04 12:02:52.000000000 -0700
***************
*** 78,83 ****
--- 78,85 ----
  #  else
  #   include <sys/sysctl.h>
  #   include "compat/tun_ioctls.h"
+ #   include <SystemConfiguration/SCPreferences.h>
+ #   include <SystemConfiguration/SCDynamicStore.h>
  #  endif
  # endif
  # ifdef __FreeBSD__
***************
*** 480,486 ****
  	IKED_XAUTH_LDAP		xauth_ldap;
  
  #endif
! 
  	// id name helper functions
  
  	const char *	find_name( long type, long id );
--- 482,492 ----
  	IKED_XAUTH_LDAP		xauth_ldap;
  
  #endif
!     
! #ifdef __APPLE__
!     CFDictionaryRef dnsconfig;
! #endif //__APPLE__
!     
  	// id name helper functions
  
  	const char *	find_name( long type, long id );

