/*
- * Copyright (c) 2004, 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*/
+#include <TargetConditionals.h>
#include "scutil.h"
#include "net.h"
+#include "prefs.h"
#include <SystemConfiguration/LinkConfiguration.h>
-/* -------------------- */
+#if TARGET_OS_EMBEDDED
+#define INLINE_PASSWORDS_USE_CFSTRING
+#endif // TARGET_OS_EMBEDDED
+
+
+#pragma mark -
+#pragma mark Interface management
static CFArrayRef
CFMutableArrayRef interfaces;
CFArrayRef real_interfaces;
- real_interfaces = SCNetworkInterfaceCopyAll();
+ real_interfaces = _SCNetworkInterfaceCopyAllWithPreferences(prefs);
if (real_interfaces == NULL) {
SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
return NULL;
CFRelease(real_interfaces);
// include pseudo interfaces
+ CFArrayAppendValue(interfaces, kSCNetworkInterfaceLoopback);
CFArrayAppendValue(interfaces, kSCNetworkInterfaceIPv4);
// include interfaces that we have created
__private_extern__
SCNetworkInterfaceRef
-_find_interface(char *match)
+_find_interface(int argc, char **argv, int *nArgs)
{
Boolean allowIndex = TRUE;
CFIndex i;
+ CFArrayRef myInterfaces = interfaces;
CFIndex n;
CFStringRef select_name = NULL;
SCNetworkInterfaceRef selected = NULL;
- if (strcasecmp(match, "$child") == 0) {
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("no interface specified\n"));
+ return NULL;
+ }
+
+ if (nArgs != NULL) *nArgs = 1;
+
+ if (strcasecmp(argv[0], "$child") == 0) {
if (net_interface == NULL) {
SCPrint(TRUE, stdout, CFSTR("interface not selected\n"));
goto done;
}
goto done;
- } else if (strcasecmp(match, "$service") == 0) {
+ } else if (strcasecmp(argv[0], "$service") == 0) {
if (net_service == NULL) {
SCPrint(TRUE, stdout, CFSTR("service not selected\n"));
goto done;
goto done;
}
- if (interfaces == NULL) {
+#if !TARGET_OS_IPHONE
+ else if (strcasecmp(argv[0], "$bond") == 0) {
+ CFStringRef interfaceType;
+
+ if (net_interface == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("interface not selected\n"));
+ goto done;
+ }
+
+ interfaceType = SCNetworkInterfaceGetInterfaceType(net_interface);
+ if (!CFEqual(interfaceType, kSCNetworkInterfaceTypeBond)) {
+ SCPrint(TRUE, stdout, CFSTR("interface not Bond\n"));
+ goto done;
+ }
+
+ if (argc < 2) {
+ SCPrint(TRUE, stdout, CFSTR("no member interface specified\n"));
+ return NULL;
+ }
+ argv++;
+ argc--;
+ if (nArgs != NULL) *nArgs += 1;
+
+ myInterfaces = SCBondInterfaceGetMemberInterfaces(net_interface);
+ if (myInterfaces == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("no member interfaces\n"));
+ goto done;
+ }
+ allowIndex = FALSE;
+ }
+#endif // !TARGET_OS_IPHONE
+
+ else if (strcasecmp(argv[0], "$bridge") == 0) {
+ CFStringRef interfaceType;
+
+ if (net_interface == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("interface not selected\n"));
+ goto done;
+ }
+
+ interfaceType = SCNetworkInterfaceGetInterfaceType(net_interface);
+ if (!CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) {
+ SCPrint(TRUE, stdout, CFSTR("interface not Bridge\n"));
+ goto done;
+ }
+
+ if (argc < 2) {
+ SCPrint(TRUE, stdout, CFSTR("no member interface specified\n"));
+ return NULL;
+ }
+ argv++;
+ argc--;
+ if (nArgs != NULL) *nArgs += 1;
+
+ myInterfaces = SCBridgeInterfaceGetMemberInterfaces(net_interface);
+ if (myInterfaces == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("no member interfaces\n"));
+ goto done;
+ }
+ allowIndex = FALSE;
+ }
+
+ else if (strcasecmp(argv[0], "$vlan") == 0) {
+ CFStringRef interfaceType;
+
+ if (net_interface == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("interface not selected\n"));
+ goto done;
+ }
+
+ interfaceType = SCNetworkInterfaceGetInterfaceType(net_interface);
+ if (!CFEqual(interfaceType, kSCNetworkInterfaceTypeVLAN)) {
+ SCPrint(TRUE, stdout, CFSTR("interface not VLAN\n"));
+ goto done;
+ }
+
+ selected = SCVLANInterfaceGetPhysicalInterface(net_interface);
+ if(selected == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("no physical interface\n"));
+ }
+
+ goto done;
+ }
+
+ if ((myInterfaces == NULL) && (interfaces == NULL)) {
interfaces = _copy_interfaces();
if (interfaces == NULL) {
return NULL;
}
+ myInterfaces = interfaces;
allowIndex = FALSE;
}
// try to select the interface by its display name
- select_name = CFStringCreateWithCString(NULL, match, kCFStringEncodingUTF8);
+ select_name = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
- n = CFArrayGetCount(interfaces);
+ n = (myInterfaces != NULL) ? CFArrayGetCount(myInterfaces) : 0;
for (i = 0; i < n; i++) {
SCNetworkInterfaceRef interface;
CFStringRef interfaceName;
- interface = CFArrayGetValueAtIndex(interfaces, i);
+ interface = CFArrayGetValueAtIndex(myInterfaces, i);
interfaceName = SCNetworkInterfaceGetLocalizedDisplayName(interface);
if ((interfaceName != NULL) && CFEqual(select_name, interfaceName)) {
if (selected == NULL) {
SCNetworkInterfaceRef interface;
CFStringRef bsd_name = NULL;
- interface = CFArrayGetValueAtIndex(interfaces, i);
- while ((interface != NULL) && (bsd_name == NULL)) {
- bsd_name = SCNetworkInterfaceGetBSDName(interface);
- if (bsd_name == NULL) {
- interface = SCNetworkInterfaceGetInterface(interface);
- }
- }
+ interface = CFArrayGetValueAtIndex(myInterfaces, i);
+ while ((interface != NULL) && (bsd_name == NULL)) {
+ bsd_name = SCNetworkInterfaceGetBSDName(interface);
+ if (bsd_name == NULL) {
+ interface = SCNetworkInterfaceGetInterface(interface);
+ }
+ }
if ((bsd_name != NULL) && CFEqual(select_name, bsd_name)) {
if (selected == NULL) {
SCNetworkInterfaceRef interface;
CFStringRef interfaceType;
- interface = CFArrayGetValueAtIndex(interfaces, i);
+ interface = CFArrayGetValueAtIndex(myInterfaces, i);
interfaceType = SCNetworkInterfaceGetInterfaceType(interface);
if (CFEqual(select_name, interfaceType)) {
if (selected == NULL) {
if (allowIndex) {
char *end;
- char *str = match;
+ char *str = argv[0];
long val;
// try to select the interface by its index
((*end == '\0') || (*end == '.')) &&
(errno == 0)) {
if ((val > 0) && (val <= n)) {
- selected = CFArrayGetValueAtIndex(interfaces, val - 1);
+ selected = CFArrayGetValueAtIndex(myInterfaces, val - 1);
if (*end == '.') {
str = end + 1;
}
interfaceType = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ argv++;
+ argc--;
+ if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBond)) {
+ SCPrint(TRUE, stdout, CFSTR("bond creation not yet supported\n"));
+ goto done;
+ }
+ if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) {
+ SCPrint(TRUE, stdout, CFSTR("bridge creation not yet supported\n"));
+ goto done;
+ }
if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVLAN)) {
-// xxxxx
-SCPrint(TRUE, stdout, CFSTR("vlan creation not yet supported\n"));
-goto done;
- } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBond)) {
-// xxxxx
-SCPrint(TRUE, stdout, CFSTR("bond creation not yet supported\n"));
-goto done;
- } else {
- if (argc < 2) {
- if (net_interface == NULL) {
- SCPrint(TRUE, stdout, CFSTR("no network interface selected\n"));
- goto done;
- }
+ SCPrint(TRUE, stdout, CFSTR("vlan creation not yet supported\n"));
+ goto done;
+ }
- interface = net_interface;
- } else {
- interface = _find_interface(argv[1]);
+ if (argc < 1) {
+ if (net_interface == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("no network interface selected\n"));
+ goto done;
}
- if (interface == NULL) {
- return;
- }
+ interface = net_interface;
+ } else {
+ interface = _find_interface(argc, argv, NULL);
+ }
- new_interface = SCNetworkInterfaceCreateWithInterface(interface, interfaceType);
- if (new_interface == NULL) {
- SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
- goto done;
- }
+ if (interface == NULL) {
+ goto done;
+ }
+
+ new_interface = SCNetworkInterfaceCreateWithInterface(interface, interfaceType);
+ if (new_interface == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
+ goto done;
}
if (new_interfaces == NULL) {
{
SCNetworkInterfaceRef interface;
- interface = _find_interface(argv[0]);
-
+ interface = _find_interface(argc, argv, NULL);
if (interface != NULL) {
CFStringRef interfaceName;
if (if_bsd_name != NULL) {
CFArrayRef available;
CFDictionaryRef active;
+ CFDictionaryRef cap_current;
int mtu_cur;
int mtu_min;
int mtu_max;
- if (NetworkInterfaceCopyMTU(if_bsd_name, &mtu_cur, &mtu_min, &mtu_max)) {
+ cap_current = SCNetworkInterfaceCopyCapability(interface, NULL);
+ if (cap_current != NULL) {
+ CFIndex i;
+ CFArrayRef cap_names;
+ CFMutableArrayRef cap_sorted;
+ const void **keys;
+ CFIndex n;
+
+ n = CFDictionaryGetCount(cap_current);
+ keys = CFAllocatorAllocate(NULL, n * sizeof(CFStringRef), 0);
+ CFDictionaryGetKeysAndValues(cap_current, keys, NULL);
+ cap_names = CFArrayCreate(NULL, keys, n, &kCFTypeArrayCallBacks);
+ CFAllocatorDeallocate(NULL, keys);
+
+ cap_sorted = CFArrayCreateMutableCopy(NULL, 0, cap_names);
+ CFRelease(cap_names);
+
+ CFArraySortValues(cap_sorted, CFRangeMake(0, n), (CFComparatorFunction)CFStringCompare, NULL);
+
+ SCPrint(TRUE, stdout, CFSTR("%@ capabilities = "), prefix);
+ for (i = 0; i < n; i++) {
+ CFStringRef cap_name;
+ int cap_val;
+ CFNumberRef val = NULL;
+
+ cap_name = CFArrayGetValueAtIndex(cap_sorted, i);
+ if (configuration != NULL) {
+ val = CFDictionaryGetValue(configuration, cap_name);
+ }
+ if (!isA_CFNumber(val)) {
+ val = CFDictionaryGetValue(cap_current, cap_name);
+ }
+
+ SCPrint(TRUE, stdout, CFSTR("%s%@%c"),
+ (i == 0) ? "" : ",",
+ cap_name,
+ (CFNumberGetValue(val, kCFNumberIntType, &cap_val) &&
+ (cap_val != 0)) ? '+' : '-');
+ }
+ SCPrint(TRUE, stdout, CFSTR("\n"));
+
+ CFRelease(cap_sorted);
+ CFRelease(cap_current);
+ }
+
+ if (SCNetworkInterfaceCopyMTU(interface, &mtu_cur, &mtu_min, &mtu_max)) {
char isCurrent = '*';
if (configuration != NULL) {
}
}
- SCPrint(TRUE, stdout, CFSTR("%@ mtu %c = %ld (%ld < n < %ld)\n"),
+ SCPrint(TRUE, stdout, CFSTR("%@ mtu %c = %d (%d < n < %d)\n"),
prefix,
isCurrent,
mtu_cur,
mtu_max);
}
- if (NetworkInterfaceCopyMediaOptions(if_bsd_name, NULL, &active, &available, TRUE)) {
+ if (SCNetworkInterfaceCopyMediaOptions(interface, NULL, &active, &available, TRUE)) {
char isCurrent = ' ';
CFArrayRef options = NULL;
CFArrayRef options_req = NULL;
CFIndex n_subtypes;
CFArrayRef subtypes;
- subtypes = NetworkInterfaceCopyMediaSubTypes(available);
+ subtypes = SCNetworkInterfaceCopyMediaSubTypes(available);
n_subtypes = (subtypes != NULL) ? CFArrayGetCount(subtypes) : 0;
for (i = 0; i < n_subtypes; i++) {
CFIndex j;
CFArrayRef subtype_options;
subtype = CFArrayGetValueAtIndex(subtypes, i);
- subtype_options = NetworkInterfaceCopyMediaSubTypeOptions(available, subtype);
+ subtype_options = SCNetworkInterfaceCopyMediaSubTypeOptions(available, subtype);
n_subtype_options = (subtype_options != NULL) ? CFArrayGetCount(subtype_options) : 0;
for (j = 0; j < n_subtype_options; j++) {
char isCurrent = ' ';
SCPrint(TRUE, stdout, CFSTR("\n"));
}
- CFRelease(subtype_options);
+ if (subtype_options != NULL) CFRelease(subtype_options);
}
+ if (subtypes != NULL) CFRelease(subtypes);
}
} else {
SCPrint(TRUE, stdout, CFSTR("\n"));
if (CFDictionaryGetCount(effective) > 0) {
SCPrint(TRUE, stdout, CFSTR("\n%@ per-interface configuration\n"), prefix);
- _show_entity(configuration, prefix);
+ _show_entity(effective, prefix);
}
CFRelease(effective);
}
+ if (CFEqual(if_type, kSCNetworkInterfaceTypePPP)) {
+ SCNetworkInterfaceRef childInterface;
+
+ childInterface = SCNetworkInterfaceGetInterface(interface);
+ if (childInterface != NULL) {
+ CFStringRef childInterfaceType;
+
+ childInterfaceType = SCNetworkInterfaceGetInterfaceType(childInterface);
+ if (CFEqual(childInterfaceType, kSCNetworkInterfaceTypeL2TP)) {
+ CFDictionaryRef ipsec_configuration;
+
+ ipsec_configuration = SCNetworkInterfaceGetExtendedConfiguration(interface, kSCEntNetIPSec);
+ if (isA_CFDictionary(ipsec_configuration) &&
+ (CFDictionaryGetCount(ipsec_configuration) > 0)) {
+ SCPrint(TRUE, stdout, CFSTR("\n%@ per-interface IPSec configuration\n"), prefix);
+ _show_entity(ipsec_configuration, prefix);
+ }
+ }
+ }
+ }
+
if (_sc_debug) {
SCPrint(TRUE, stdout, CFSTR("\n%@\n"), interface);
}
static Boolean
-validateMediaOptions(CFStringRef interfaceName, CFMutableDictionaryRef newConfiguration)
+validateMediaOptions(SCNetworkInterfaceRef interface, CFMutableDictionaryRef newConfiguration)
{
Boolean ok = TRUE;
CFNumberRef mtu;
int mtu_min;
int mtu_val;
- if (!NetworkInterfaceCopyMTU(interfaceName, NULL, &mtu_min, &mtu_max)) {
+ if (!SCNetworkInterfaceCopyMTU(interface, NULL, &mtu_min, &mtu_max)) {
SCPrint(TRUE, stdout, CFSTR("cannot set MTU\n"));
return FALSE;
}
config_options = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
}
- if (interfaceName == NULL) {
- SCPrint(TRUE, stdout, CFSTR("media type / options not available\n"));
- goto checked;
- }
-
- if (!NetworkInterfaceCopyMediaOptions(interfaceName, NULL, NULL, &available, FALSE)) {
+ if (!SCNetworkInterfaceCopyMediaOptions(interface, NULL, NULL, &available, FALSE)) {
SCPrint(TRUE, stdout, CFSTR("media type / options not available\n"));
goto checked;
}
goto checked;
}
- subtypes = NetworkInterfaceCopyMediaSubTypes(available);
+ subtypes = SCNetworkInterfaceCopyMediaSubTypes(available);
if ((subtypes == NULL) ||
!CFArrayContainsValue(subtypes,
CFRangeMake(0, CFArrayGetCount(subtypes)),
goto checked;
}
- subtype_options = NetworkInterfaceCopyMediaSubTypeOptions(available, subtype);
+ subtype_options = SCNetworkInterfaceCopyMediaSubTypeOptions(available, subtype);
if ((subtype_options == NULL) ||
!CFArrayContainsValue(subtype_options,
CFRangeMake(0, CFArrayGetCount(subtype_options)),
/* -------------------- */
-static Boolean
-set_interface_bond(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+static int
+__doRank(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
{
-// xxxxx ("+device", "-device")
-SCPrint(TRUE, stdout, CFSTR("bond interface management not yet supported\n"));
- return FALSE;
+ SCNetworkInterfaceRef interface;
+ CFStringRef interfaceName;
+ Boolean ok = FALSE;
+ SCNetworkServicePrimaryRank rank = kSCNetworkServicePrimaryRankDefault;
+ SCDynamicStoreRef store;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout,
+ CFSTR("%s not specified\n"),
+ description != NULL ? description : "rank");
+ return -1;
+ }
+
+ if (strlen(argv[0]) == 0) {
+ rank = kSCNetworkServicePrimaryRankDefault;
+ } else if ((strcasecmp(argv[0], "First") == 0)) {
+ rank = kSCNetworkServicePrimaryRankFirst;
+ } else if ((strcasecmp(argv[0], "Last") == 0)) {
+ rank = kSCNetworkServicePrimaryRankLast;
+ } else if ((strcasecmp(argv[0], "Never") == 0)) {
+ rank = kSCNetworkServicePrimaryRankNever;
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("invalid rank\n"));
+ return -1;
+ }
+
+ interfaceName = SCNetworkInterfaceGetBSDName(net_interface);
+ if (interfaceName == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("no BSD interface\n"));
+ return FALSE;
+ }
+
+ store = SCDynamicStoreCreate(NULL, CFSTR("scutil --net"), NULL, NULL);
+ interface = _SCNetworkInterfaceCopyActive(store, interfaceName);
+ CFRelease(store);
+ if (interface == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("No active interface\n"));
+ return -1;
+ }
+
+ ok = SCNetworkInterfaceSetPrimaryRank(interface, rank);
+ CFRelease(interface);
+ if (!ok) {
+ SCPrint(TRUE, stdout, CFSTR("could not update per-interface rank\n"));
+ return -1;
+ }
+
+ return 1;
}
/* -------------------- */
-static options airportOptions[] = {
+static void
+_replaceOne(const void *key, const void *value, void *context)
+{
+ CFMutableDictionaryRef newConfiguration = (CFMutableDictionaryRef)context;
+
+ CFDictionarySetValue(newConfiguration, key, value);
+ return;
+}
+
+
+static void
+updateInterfaceConfiguration(CFMutableDictionaryRef newConfiguration)
+{
+ CFDictionaryRef configuration;
+
+ CFDictionaryRemoveAllValues(newConfiguration);
+
+ configuration = SCNetworkInterfaceGetConfiguration(net_interface);
+ if (configuration != NULL) {
+ CFDictionaryApplyFunction(configuration, _replaceOne, (void *)newConfiguration);
+ }
+
+ return;
+}
+
+
+#pragma mark -
+#pragma mark Bond options
+
+
+static options bondOptions[] = {
{ "mtu" , NULL, isNumber , &kSCPropNetEthernetMTU , NULL, NULL },
- { "media" , NULL, isString , &kSCPropNetEthernetMediaSubType, NULL, NULL },
- { "mediaopt" , NULL, isStringArray, &kSCPropNetEthernetMediaOptions, NULL, NULL },
+ // xxx { "+device" , ... },
+ // xxx { "-device" , ... },
{ "?" , NULL , isHelp , NULL , NULL,
- "\nAirPort configuration commands\n\n"
- " set interface [mtu n] [media type] [mediaopts opts]\n"
+ "\nBond configuration commands\n\n"
+ " set interface [mtu n] [media type] [mediaopts opts]\n"
}
};
-#define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
+#define N_BOND_OPTIONS (sizeof(bondOptions) / sizeof(bondOptions[0]))
static Boolean
-set_interface_airport(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+set_interface_bond(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
{
CFStringRef interfaceName;
Boolean ok;
return FALSE;
}
- ok = _process_options(airportOptions, N_AIRPORT_OPTIONS, argc, argv, newConfiguration);
+ ok = _process_options(bondOptions, N_BOND_OPTIONS, argc, argv, newConfiguration);
if (ok) {
// validate configuration
- if (!validateMediaOptions(interfaceName, newConfiguration)) {
+ if (!validateMediaOptions(net_interface, newConfiguration)) {
return FALSE;
}
}
}
-/* -------------------- */
+#pragma mark -
+#pragma mark Bridge options
-static options ethernetOptions[] = {
+static options bridgeOptions[] = {
{ "mtu" , NULL, isNumber , &kSCPropNetEthernetMTU , NULL, NULL },
- { "media" , NULL, isString , &kSCPropNetEthernetMediaSubType, NULL, NULL },
- { "mediaopt" , NULL, isStringArray, &kSCPropNetEthernetMediaOptions, NULL, NULL },
+// xxx { "+device" , ... },
+// xxx { "-device" , ... },
{ "?" , NULL , isHelp , NULL , NULL,
- "\nEthernet configuration commands\n\n"
+ "\nBridge configuration commands\n\n"
" set interface [mtu n] [media type] [mediaopts opts]\n"
}
};
-#define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
+#define N_BRIDGE_OPTIONS (sizeof(bridgeOptions) / sizeof(bridgeOptions[0]))
static Boolean
-set_interface_ethernet(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+set_interface_bridge(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
{
CFStringRef interfaceName;
Boolean ok;
return FALSE;
}
- ok = _process_options(ethernetOptions, N_ETHERNET_OPTIONS, argc, argv, newConfiguration);
+ ok = _process_options(bridgeOptions, N_BRIDGE_OPTIONS, argc, argv, newConfiguration);
if (ok) {
// validate configuration
- if (!validateMediaOptions(interfaceName, newConfiguration)) {
+ if (!validateMediaOptions(net_interface, newConfiguration)) {
return FALSE;
}
}
}
-/* -------------------- */
+#pragma mark -
+#pragma mark AirPort options
-static options firewireOptions[] = {
+static options airportOptions[] = {
{ "mtu" , NULL, isNumber , &kSCPropNetEthernetMTU , NULL, NULL },
{ "media" , NULL, isString , &kSCPropNetEthernetMediaSubType, NULL, NULL },
{ "mediaopt" , NULL, isStringArray, &kSCPropNetEthernetMediaOptions, NULL, NULL },
- { "?" , NULL , isHelp , NULL , NULL,
- "\nFireWire configuration commands\n\n"
+ { "rank" , NULL, isOther , NULL , __doRank, NULL },
+
+ { "?" , NULL, isHelp , NULL , NULL,
+ "\nAirPort configuration commands\n\n"
" set interface [mtu n] [media type] [mediaopts opts]\n"
}
};
-#define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
+#define N_AIRPORT_OPTIONS (sizeof(airportOptions) / sizeof(airportOptions[0]))
static Boolean
-set_interface_firewire(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+set_interface_airport(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
{
CFStringRef interfaceName;
Boolean ok;
return FALSE;
}
- ok = _process_options(firewireOptions, N_FIREWIRE_OPTIONS, argc, argv, newConfiguration);
+ ok = _process_options(airportOptions, N_AIRPORT_OPTIONS, argc, argv, newConfiguration);
if (ok) {
// validate configuration
- if (!validateMediaOptions(interfaceName, newConfiguration)) {
+ if (!validateMediaOptions(net_interface, newConfiguration)) {
return FALSE;
}
}
}
-/* -------------------- */
-
+#pragma mark -
+#pragma mark Ethernet options
-static selections modemDialSelections[] = {
- { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone , 0 },
- { CFSTR("manual"), &kSCValNetModemDialModeManual , 0 },
- { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone, 0 },
- { NULL , NULL , 0 }
-};
-static options modemOptions[] = {
- { "ConnectionScript" , "script", isString , &kSCPropNetModemConnectionScript , NULL, NULL },
- { "DialMode" , "mode" , isChooseOne, &kSCPropNetModemDialMode , NULL, (void *)modemDialSelections },
- { "CallWaiting" , NULL , isBoolean , &kSCPropNetModemHoldEnabled , NULL, NULL },
- { "CallWaitingAlert" , NULL , isBoolean , &kSCPropNetModemHoldCallWaitingAudibleAlert, NULL, NULL },
- { "CallWaitingDisconnectOnAnswer", NULL , isBoolean , &kSCPropNetModemHoldDisconnectOnAnswer , NULL, NULL },
- { "DataCompression" , NULL , isBoolean , &kSCPropNetModemDataCompression , NULL, NULL },
- { "ErrorCorrection" , NULL , isBoolean , &kSCPropNetModemErrorCorrection , NULL, NULL },
- { "HoldReminder" , NULL , isBoolean , &kSCPropNetModemHoldReminder , NULL, NULL },
- { "HoldReminderTime" , "time" , isNumber , &kSCPropNetModemHoldReminderTime , NULL, NULL },
- { "PulseDial" , NULL , isBoolean , &kSCPropNetModemPulseDial , NULL, NULL },
- { "Speaker" , NULL , isBoolean , &kSCPropNetModemSpeaker , NULL, NULL },
+static int
+__doCapability(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ Boolean ok = FALSE;
- { "?" , NULL , isHelp , NULL , NULL,
- "\nModem configuration commands\n\n"
- " set interface [ConnectionScript connection-script]\n"
- " set interface [CallWaiting {enable|disable}]\n"
- " set interface [CallWaitingAlert {enable|disable}]\n"
- " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
- " set interface [DialMode {ignore|wait}]\n"
- " set interface [DataCompression {enable|disable}]\n"
- " set interface [ErrorCorrection {enable|disable}]\n"
- " set interface [HoldReminder {enable|disable}]\n"
- " set interface [HoldReminderTime n]\n"
- " set interface [PulseDial {enable|disable}]\n"
- " set interface [Speaker {enable|disable}]"
+ if (argc < 1) {
+ SCPrint(TRUE, stdout,
+ CFSTR("%s not specified\n"),
+ description != NULL ? description : "enable/disable");
+ return -1;
}
-};
-#define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
+ if (strlen(argv[0]) == 0) {
+ ok = SCNetworkInterfaceSetCapability(net_interface, key, NULL);
+ } else if ((strcasecmp(argv[0], "disable") == 0) ||
+ (strcasecmp(argv[0], "no" ) == 0) ||
+ (strcasecmp(argv[0], "off" ) == 0) ||
+ (strcasecmp(argv[0], "0" ) == 0)) {
+ ok = SCNetworkInterfaceSetCapability(net_interface, key, CFNumberRef_0);
+ } else if ((strcasecmp(argv[0], "enable") == 0) ||
+ (strcasecmp(argv[0], "yes" ) == 0) ||
+ (strcasecmp(argv[0], "on" ) == 0) ||
+ (strcasecmp(argv[0], "1" ) == 0)) {
+ ok = SCNetworkInterfaceSetCapability(net_interface, key, CFNumberRef_1);
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
+ return -1;
+ }
-static Boolean
-set_interface_modem(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
-{
- Boolean ok;
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ SCPrint(TRUE, stdout,
+ CFSTR("%@ not updated: %s\n"),
+ key,
+ SCErrorString(SCError()));
+ return -1;
+ }
- ok = _process_options(modemOptions, N_MODEM_OPTIONS, argc, argv, newConfiguration);
- return ok;
+ return 1;
}
-/* -------------------- */
+static options ethernetOptions[] = {
+ { "mtu" , NULL, isNumber , &kSCPropNetEthernetMTU , NULL, NULL },
+ { "media" , NULL, isString , &kSCPropNetEthernetMediaSubType, NULL, NULL },
+ { "mediaopt" , NULL, isStringArray, &kSCPropNetEthernetMediaOptions, NULL, NULL },
+ { "av" , NULL, isOther , &kSCPropNetEthernetCapabilityAV , __doCapability, NULL },
+ { "lro" , NULL, isOther , &kSCPropNetEthernetCapabilityLRO , __doCapability, NULL },
+ { "rxcsum" , NULL, isOther , &kSCPropNetEthernetCapabilityRXCSUM, __doCapability, NULL },
+ { "tso" , NULL, isOther , &kSCPropNetEthernetCapabilityTSO , __doCapability, NULL },
+ { "txcsum" , NULL, isOther , &kSCPropNetEthernetCapabilityTXCSUM, __doCapability, NULL },
-static int
+ { "rank" , NULL, isOther , NULL , __doRank, NULL },
+
+ { "?" , NULL, isHelp , NULL , NULL,
+ "\nEthernet configuration commands\n\n"
+ " set interface [mtu n] [media type] [mediaopts opts]\n"
+ }
+};
+#define N_ETHERNET_OPTIONS (sizeof(ethernetOptions) / sizeof(ethernetOptions[0]))
+
+
+static Boolean
+set_interface_ethernet(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ CFStringRef interfaceName;
+ Boolean ok;
+
+ interfaceName = SCNetworkInterfaceGetBSDName(net_interface);
+ if (interfaceName == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("no BSD interface\n"));
+ return FALSE;
+ }
+
+ ok = _process_options(ethernetOptions, N_ETHERNET_OPTIONS, argc, argv, newConfiguration);
+ if (ok) {
+ // validate configuration
+ if (!validateMediaOptions(net_interface, newConfiguration)) {
+ return FALSE;
+ }
+ }
+
+ return ok;
+}
+
+
+#pragma mark -
+#pragma mark IPSec options
+
+
+static int
+__doIPSecSharedSecret(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ CFStringRef encryptionType;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("IPSec shared secret not specified\n"));
+ return -1;
+ }
+
+ encryptionType = CFDictionaryGetValue(newConfiguration, kSCPropNetIPSecSharedSecretEncryption);
+ if (strlen(argv[0]) > 0) {
+ if (encryptionType == NULL) {
+#ifdef INLINE_PASSWORDS_USE_CFSTRING
+ CFStringRef pw;
+
+ pw = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+#else // INLINE_PASSWORDS_USE_CFSTRING
+ CFIndex n;
+ CFMutableDataRef pw;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ n = CFStringGetLength(str);
+ pw = CFDataCreateMutable(NULL, n * sizeof(UniChar));
+ CFDataSetLength(pw, n * sizeof(UniChar));
+ /* ALIGN: CF aligns to at least >8 bytes */
+ CFStringGetCharacters(str,
+ CFRangeMake(0, n),
+ (UniChar *)(void *)CFDataGetMutableBytePtr(pw));
+ CFRelease(str);
+#endif // INLINE_PASSWORDS_USE_CFSTRING
+
+ CFDictionarySetValue(newConfiguration, key, pw);
+ CFRelease(pw);
+ } else if (CFEqual(encryptionType, kSCValNetIPSecSharedSecretEncryptionKeychain)) {
+ Boolean ok;
+ CFDataRef pw;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ pw = CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingUTF8, 0);
+ ok = SCNetworkInterfaceSetPassword(net_interface,
+ kSCNetworkInterfacePasswordTypeIPSecSharedSecret,
+ pw,
+ NULL);
+ CFRelease(pw);
+ CFRelease(str);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType);
+ return -1;
+ }
+ } else {
+ if (encryptionType == NULL) {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ } else if (CFEqual(encryptionType, kSCValNetIPSecSharedSecretEncryptionKeychain)) {
+ Boolean ok;
+ ok = SCNetworkInterfaceRemovePassword(net_interface, kSCNetworkInterfacePasswordTypeIPSecSharedSecret);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("IPSec shared secret type \"%@\" not supported\n"), encryptionType);
+ return -1;
+ }
+ }
+
+ return 1;
+}
+
+
+static int
+__doIPSecSharedSecretType(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("IPSec shared secret type mode not specified\n"));
+ return -1;
+ }
+
+ if (strlen(argv[0]) > 0) {
+ if (strcasecmp(argv[0], "keychain") == 0) {
+ CFDictionarySetValue(newConfiguration, key, kSCValNetIPSecSharedSecretEncryptionKeychain);
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("invalid shared secret type\n"));
+ return -1;
+ }
+ } else {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ }
+
+ // encryption type changed, reset shared secret
+ CFDictionaryRemoveValue(newConfiguration, kSCPropNetIPSecSharedSecret);
+
+ return 1;
+}
+
+
+static int
+__doIPSecXAuthPassword(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ CFStringRef encryptionType;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("IPSec XAuth password not specified\n"));
+ return -1;
+ }
+
+ encryptionType = CFDictionaryGetValue(newConfiguration, kSCPropNetIPSecXAuthPasswordEncryption);
+ if (strlen(argv[0]) > 0) {
+ if (encryptionType == NULL) {
+#ifdef INLINE_PASSWORDS_USE_CFSTRING
+ CFStringRef pw;
+
+ pw = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+#else // INLINE_PASSWORDS_USE_CFSTRING
+ CFIndex n;
+ CFMutableDataRef pw;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ n = CFStringGetLength(str);
+ pw = CFDataCreateMutable(NULL, n * sizeof(UniChar));
+ CFDataSetLength(pw, n * sizeof(UniChar));
+ /* ALIGN: CF aligns to at least >8 byte boundries */
+ CFStringGetCharacters(str,
+ CFRangeMake(0, n),
+ (UniChar *)(void *)CFDataGetMutableBytePtr(pw));
+ CFRelease(str);
+#endif // INLINE_PASSWORDS_USE_CFSTRING
+
+ CFDictionarySetValue(newConfiguration, key, pw);
+ CFRelease(pw);
+ } else if (CFEqual(encryptionType, kSCValNetIPSecXAuthPasswordEncryptionKeychain)) {
+ Boolean ok;
+ CFDataRef pw;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ pw = CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingUTF8, 0);
+ ok = SCNetworkInterfaceSetPassword(net_interface,
+ kSCNetworkInterfacePasswordTypeIPSecXAuth,
+ pw,
+ NULL);
+ CFRelease(pw);
+ CFRelease(str);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType);
+ return -1;
+ }
+ } else {
+ if (encryptionType == NULL) {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ } else if (CFEqual(encryptionType, kSCValNetIPSecXAuthPasswordEncryptionKeychain)) {
+ Boolean ok;
+
+ ok = SCNetworkInterfaceRemovePassword(net_interface, kSCNetworkInterfacePasswordTypeIPSecXAuth);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("IPSec XAuthPassword type \"%@\" not supported\n"), encryptionType);
+ return -1;
+ }
+ }
+
+ return 1;
+}
+
+
+static int
+__doIPSecXAuthPasswordType(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("IPSec XAuth password type mode not specified\n"));
+ return -1;
+ }
+
+ if (strlen(argv[0]) > 0) {
+ if (strcasecmp(argv[0], "keychain") == 0) {
+ CFDictionarySetValue(newConfiguration, key, kSCValNetIPSecXAuthPasswordEncryptionKeychain);
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("invalid XAuth password type\n"));
+ return -1;
+ }
+ } else {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ }
+
+ // encryption type changed, reset XAuthPassword
+ CFDictionaryRemoveValue(newConfiguration, kSCPropNetIPSecXAuthPassword);
+
+ return 1;
+}
+
+
+static CF_RETURNS_RETAINED CFStringRef
+__cleanupDomainName(CFStringRef domain)
+{
+ CFMutableStringRef newDomain;
+
+ newDomain = CFStringCreateMutableCopy(NULL, 0, domain);
+ CFStringTrimWhitespace(newDomain);
+ CFStringTrim(newDomain, CFSTR("."));
+ if (CFStringGetLength(newDomain) == 0) {
+ CFRelease(newDomain);
+ newDomain = NULL;
+ }
+
+ return newDomain;
+}
+
+
+static int
+__doOnDemandDomains(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ CFMutableArrayRef domains;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("OnDemand domain name(s) not specified\n"));
+ return -1;
+ }
+
+ domains = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ if (strlen(argv[0]) > 0) {
+ CFArrayRef array;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ array = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR(","));
+ CFRelease(str);
+
+ if (array != NULL) {
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(array);
+
+ for (i = 0; i < n; i++) {
+ CFStringRef domain;
+
+ domain = __cleanupDomainName(CFArrayGetValueAtIndex(array, i));
+ if (domain != NULL) {
+ CFArrayAppendValue(domains, domain);
+ CFRelease(domain);
+ } else {
+ CFRelease(array);
+ CFRelease(domains);
+ SCPrint(TRUE, stdout, CFSTR("invalid OnDemand domain name\n"));
+ return -1;
+ }
+ }
+ CFRelease(array);
+ }
+ }
+
+ if (CFArrayGetCount(domains) > 0) {
+ CFDictionarySetValue(newConfiguration, key, domains);
+ } else {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ }
+
+ CFRelease(domains);
+ return 1;
+}
+
+
+static options ipsecOnDemandOptions[] = {
+ { "OnDemandMatchDomainsAlways" , "domain", isOther , &kSCPropNetIPSecOnDemandMatchDomainsAlways , __doOnDemandDomains, NULL },
+ { "always" , "domain", isOther , &kSCPropNetIPSecOnDemandMatchDomainsAlways , __doOnDemandDomains, NULL },
+ { "OnDemandMatchDomainsOnRetry", "domain", isOther , &kSCPropNetIPSecOnDemandMatchDomainsOnRetry, __doOnDemandDomains, NULL },
+ { "retry" , "domain", isOther , &kSCPropNetIPSecOnDemandMatchDomainsOnRetry, __doOnDemandDomains, NULL },
+ { "OnDemandMatchDomainsNever" , "domain", isOther , &kSCPropNetIPSecOnDemandMatchDomainsNever , __doOnDemandDomains, NULL },
+ { "never" , "domain", isOther , &kSCPropNetIPSecOnDemandMatchDomainsNever , __doOnDemandDomains, NULL },
+
+ { "?" , NULL , isHelp , NULL , NULL ,
+ "\nOnDemandMatch configuration commands\n\n"
+ " set interface OnDemandMatch always domain-name[,domain-name]\n"
+ " set interface OnDemandMatch retry domain-name[,domain-name]\n"
+ " set interface OnDemandMatch never domain-name[,domain-name]\n"
+ }
+};
+#define N_IPSEC_ONDEMAND_OPTIONS (sizeof(ipsecOnDemandOptions) / sizeof(ipsecOnDemandOptions[0]))
+
+
+static int
+__doIPSecOnDemandMatch(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ Boolean ok;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("set what?\n"));
+ return -1;
+ }
+
+ ok = _process_options(ipsecOnDemandOptions, N_IPSEC_ONDEMAND_OPTIONS, argc, argv, newConfiguration);
+ if (!ok) {
+ goto done;
+ }
+
+ done :
+
+ return argc;
+}
+
+
+static selections ipsecAuthenticationMethodSelections[] = {
+ { CFSTR("SharedSecret"), &kSCValNetIPSecAuthenticationMethodSharedSecret, 0 },
+ { CFSTR("Certificate") , &kSCValNetIPSecAuthenticationMethodCertificate , 0 },
+ { CFSTR("Hybrid") , &kSCValNetIPSecAuthenticationMethodHybrid , 0 },
+ { NULL , NULL , 0 }
+};
+
+
+static selections ipsecLocalIdentifierTypeSelections[] = {
+ { CFSTR("KeyID") , &kSCValNetIPSecLocalIdentifierTypeKeyID , 0 },
+ { NULL , NULL , 0 }
+};
+
+
+static options ipsecOptions[] = {
+ { "AuthenticationMethod" , NULL, isChooseOne , &kSCPropNetIPSecAuthenticationMethod , NULL , (void *)ipsecAuthenticationMethodSelections },
+ { "LocalIdentifier" , NULL, isString , &kSCPropNetIPSecLocalIdentifier , NULL , NULL },
+ { "group" , NULL, isString , &kSCPropNetIPSecLocalIdentifier , NULL , NULL },
+ { "LocalIdentifierType" , NULL, isChooseOne , &kSCPropNetIPSecLocalIdentifierType , NULL , (void *)ipsecLocalIdentifierTypeSelections },
+ { "RemoteAddress" , NULL, isString , &kSCPropNetIPSecRemoteAddress , NULL , NULL },
+ { "SharedSecret" , NULL, isOther , &kSCPropNetIPSecSharedSecret , __doIPSecSharedSecret , NULL },
+ { "SharedSecretEncryption" , NULL, isOther , &kSCPropNetIPSecSharedSecretEncryption , __doIPSecSharedSecretType , NULL },
+
+ // --- XAuth: ---
+ { "XAuthEnabled" , NULL, isBoolean , &kSCPropNetIPSecXAuthEnabled , NULL , NULL },
+ { "XAuthName" , NULL, isString , &kSCPropNetIPSecXAuthName , NULL , NULL },
+ { "XAuthPassword" , NULL, isOther , &kSCPropNetIPSecXAuthPassword , __doIPSecXAuthPassword , NULL },
+ { "XAuthPasswordEncryption", NULL, isOther , &kSCPropNetIPSecXAuthPasswordEncryption, __doIPSecXAuthPasswordType, NULL },
+
+ // --- OnDemand: ---
+ { "OnDemandEnabled" , NULL, isBoolean , &kSCPropNetIPSecOnDemandEnabled , NULL , NULL },
+ { "OnDemandMatch" , NULL, isOther , NULL , __doIPSecOnDemandMatch , NULL },
+
+ { "?" , NULL , isHelp , NULL , NULL,
+ "\nIPSec configuration commands\n\n"
+ " set interface [AuthenticationMethod {SharedSecret|Certificate|Hybrid}]\n"
+ " set interface [LocalIdentifier group]\n"
+ " set interface [LocalIdentifierType {KeyID}]\n"
+ " set interface [RemoteAddress name-or-address]\n"
+ " set interface [SharedSecret secret]\n"
+ " set interface [SharedSecretEncryption {Keychain}]\n"
+ " set interface [XAuthEnabled {enable|disable}]\n"
+ " set interface [XAuthPassword password]\n"
+ " set interface [XAuthPasswordEncryption {Keychain}]\n"
+ " set interface [OnDemandEnabled {enable|disable}]\n"
+ " set interface [OnDemandMatch <match-options>]\n"
+ }
+};
+#define N_IPSEC_OPTIONS (sizeof(ipsecOptions) / sizeof(ipsecOptions[0]))
+
+
+static Boolean
+set_interface_ipsec(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ Boolean ok;
+
+ ok = _process_options(ipsecOptions, N_IPSEC_OPTIONS, argc, argv, newConfiguration);
+ return ok;
+}
+
+
+#pragma mark -
+#pragma mark FireWire options
+
+
+static options firewireOptions[] = {
+ { "mtu" , NULL, isNumber , &kSCPropNetEthernetMTU , NULL, NULL },
+ { "media" , NULL, isString , &kSCPropNetEthernetMediaSubType, NULL, NULL },
+ { "mediaopt" , NULL, isStringArray, &kSCPropNetEthernetMediaOptions, NULL, NULL },
+
+ { "?" , NULL , isHelp , NULL , NULL,
+ "\nFireWire configuration commands\n\n"
+ " set interface [mtu n] [media type] [mediaopts opts]\n"
+ }
+};
+#define N_FIREWIRE_OPTIONS (sizeof(firewireOptions) / sizeof(firewireOptions[0]))
+
+
+static Boolean
+set_interface_firewire(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ CFStringRef interfaceName;
+ Boolean ok;
+
+ interfaceName = SCNetworkInterfaceGetBSDName(net_interface);
+ if (interfaceName == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("no BSD interface\n"));
+ return FALSE;
+ }
+
+ ok = _process_options(firewireOptions, N_FIREWIRE_OPTIONS, argc, argv, newConfiguration);
+ if (ok) {
+ // validate configuration
+ if (!validateMediaOptions(net_interface, newConfiguration)) {
+ return FALSE;
+ }
+ }
+
+ return ok;
+}
+
+
+#pragma mark -
+#pragma mark Modem options
+
+
+static selections modemDialSelections[] = {
+ { CFSTR("ignore"), &kSCValNetModemDialModeIgnoreDialTone , 0 },
+ { CFSTR("manual"), &kSCValNetModemDialModeManual , 0 },
+ { CFSTR("wait") , &kSCValNetModemDialModeWaitForDialTone, 0 },
+ { NULL , NULL , 0 }
+};
+
+static options modemOptions[] = {
+ { "ConnectionScript" , "script", isString , &kSCPropNetModemConnectionScript , NULL, NULL },
+ { "DialMode" , "mode" , isChooseOne, &kSCPropNetModemDialMode , NULL, (void *)modemDialSelections },
+ { "CallWaiting" , NULL , isBoolean , &kSCPropNetModemHoldEnabled , NULL, NULL },
+ { "CallWaitingAlert" , NULL , isBoolean , &kSCPropNetModemHoldCallWaitingAudibleAlert, NULL, NULL },
+ { "CallWaitingDisconnectOnAnswer", NULL , isBoolean , &kSCPropNetModemHoldDisconnectOnAnswer , NULL, NULL },
+ { "DataCompression" , NULL , isBoolean , &kSCPropNetModemDataCompression , NULL, NULL },
+ { "ErrorCorrection" , NULL , isBoolean , &kSCPropNetModemErrorCorrection , NULL, NULL },
+ { "HoldReminder" , NULL , isBoolean , &kSCPropNetModemHoldReminder , NULL, NULL },
+ { "HoldReminderTime" , "time" , isNumber , &kSCPropNetModemHoldReminderTime , NULL, NULL },
+ { "PulseDial" , NULL , isBoolean , &kSCPropNetModemPulseDial , NULL, NULL },
+ { "Speaker" , NULL , isBoolean , &kSCPropNetModemSpeaker , NULL, NULL },
+
+ { "?" , NULL , isHelp , NULL , NULL,
+ "\nModem configuration commands\n\n"
+ " set interface [ConnectionScript connection-script]\n"
+ " set interface [CallWaiting {enable|disable}]\n"
+ " set interface [CallWaitingAlert {enable|disable}]\n"
+ " set interface [CallWaitingDisconnectOnAnswer {enable|disable}]\n"
+ " set interface [DialMode {ignore|wait}]\n"
+ " set interface [DataCompression {enable|disable}]\n"
+ " set interface [ErrorCorrection {enable|disable}]\n"
+ " set interface [HoldReminder {enable|disable}]\n"
+ " set interface [HoldReminderTime n]\n"
+ " set interface [PulseDial {enable|disable}]\n"
+ " set interface [Speaker {enable|disable}]\n"
+ }
+};
+#define N_MODEM_OPTIONS (sizeof(modemOptions) / sizeof(modemOptions[0]))
+
+
+static Boolean
+set_interface_modem(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ Boolean ok;
+
+ ok = _process_options(modemOptions, N_MODEM_OPTIONS, argc, argv, newConfiguration);
+ return ok;
+}
+
+
+#pragma mark -
+#pragma mark PPP options
+
+
+static int
__doPPPAuthPW(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
{
+ CFStringRef encryptionType;
+
if (argc < 1) {
SCPrint(TRUE, stdout, CFSTR("PPP password not specified\n"));
return -1;
}
+ encryptionType = CFDictionaryGetValue(newConfiguration, kSCPropNetPPPAuthPasswordEncryption);
if (strlen(argv[0]) > 0) {
- CFStringRef encryptionType;
-
- encryptionType = CFDictionaryGetValue(newConfiguration, kSCPropNetPPPAuthPasswordEncryption);
if (encryptionType == NULL) {
+#ifdef INLINE_PASSWORDS_USE_CFSTRING
+ CFStringRef pw;
+
+ pw = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+#else // INLINE_PASSWORDS_USE_CFSTRING
CFIndex n;
CFMutableDataRef pw;
CFStringRef str;
n = CFStringGetLength(str);
pw = CFDataCreateMutable(NULL, n * sizeof(UniChar));
CFDataSetLength(pw, n * sizeof(UniChar));
+ /* ALIGN: CF aligns to at least >8 byte boundries */
CFStringGetCharacters(str,
CFRangeMake(0, n),
- (UniChar *)CFDataGetMutableBytePtr(pw));
+ (UniChar *)(void *)CFDataGetMutableBytePtr(pw));
CFRelease(str);
+#endif // INLINE_PASSWORDS_USE_CFSTRING
CFDictionarySetValue(newConfiguration, key, pw);
CFRelease(pw);
+ } else if (CFEqual(encryptionType, kSCValNetPPPAuthPasswordEncryptionKeychain)) {
+ Boolean ok;
+ CFDataRef pw;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ pw = CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingUTF8, 0);
+ ok = SCNetworkInterfaceSetPassword(net_interface,
+ kSCNetworkInterfacePasswordTypePPP,
+ pw,
+ NULL);
+ CFRelease(pw);
+ CFRelease(str);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
} else {
SCPrint(TRUE, stdout, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType);
return -1;
}
} else {
- CFDictionaryRemoveValue(newConfiguration, key);
+ if (encryptionType == NULL) {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ } else if (CFEqual(encryptionType, kSCValNetPPPAuthPasswordEncryptionKeychain)) {
+ Boolean ok;
+
+ ok = SCNetworkInterfaceRemovePassword(net_interface, kSCNetworkInterfacePasswordTypePPP);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType);
+ return -1;
+ }
}
return 1;
}
+static options l2tp_ipsecOptions[] = {
+ { "SharedSecret" , NULL, isOther , &kSCPropNetIPSecSharedSecret , __doIPSecSharedSecret , NULL },
+ { "SharedSecretEncryption", NULL, isOther , &kSCPropNetIPSecSharedSecretEncryption, __doIPSecSharedSecretType, NULL },
+
+ { "?" , NULL , isHelp , NULL , NULL,
+ "\nIPSec configuration commands\n\n"
+ " set interface ipsec [SharedSecret secret]\n"
+ " set interface ipsec [SharedSecretEncryption {Keychain}]\n"
+ }
+};
+#define N_L2TP_IPSEC_OPTIONS (sizeof(l2tp_ipsecOptions) / sizeof(l2tp_ipsecOptions[0]))
+
+
+static int
+__doPPPIPSec(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newPPPConfiguration)
+{
+ SCNetworkInterfaceRef childInterface;
+ CFStringRef childInterfaceType;
+ CFDictionaryRef configuration;
+ CFMutableDictionaryRef newConfiguration;
+ Boolean ok;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("set what?\n"));
+ return -1;
+ }
+
+ childInterface = SCNetworkInterfaceGetInterface(net_interface);
+ if (childInterface == NULL) {
+ SCPrint(TRUE, stdout, CFSTR("this interfaces configuration cannot be changed\n"));
+ return -1;
+ }
+
+ childInterfaceType = SCNetworkInterfaceGetInterfaceType(childInterface);
+ if (!CFEqual(childInterfaceType, kSCNetworkInterfaceTypeL2TP)) {
+ SCPrint(TRUE, stdout, CFSTR("this interfaces configuration cannot be changed\n"));
+ return -1;
+ }
+
+ configuration = SCNetworkInterfaceGetExtendedConfiguration(net_interface, kSCEntNetIPSec);
+ if (configuration == NULL) {
+ newConfiguration = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ } else {
+ newConfiguration = CFDictionaryCreateMutableCopy(NULL, 0, configuration);
+ CFDictionaryRemoveValue(newConfiguration, kSCResvInactive);
+ }
+
+ ok = _process_options(l2tp_ipsecOptions, N_L2TP_IPSEC_OPTIONS, argc, argv, newConfiguration);
+ if (!ok) {
+ goto done;
+ }
+
+ if (((configuration == NULL) && (CFDictionaryGetCount(newConfiguration) > 0)) ||
+ ((configuration != NULL) && !CFEqual(configuration, newConfiguration))) {
+ if (!SCNetworkInterfaceSetExtendedConfiguration(net_interface, kSCEntNetIPSec, newConfiguration)) {
+ if (SCError() == kSCStatusNoKey) {
+ SCPrint(TRUE, stdout, CFSTR("could not update per-service interface configuration\n"));
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
+ }
+ goto done;
+ }
+
+ _prefs_changed = TRUE;
+ }
+
+ done :
+
+ if (newConfiguration != NULL) CFRelease(newConfiguration);
+ return argc;
+}
+
+
+#ifdef NOTYET
+static options pppOnDemandOptions[] = {
+ { "OnDemandMatchDomainsAlways" , "domain", isOther , &kSCPropNetPPPOnDemandMatchDomainsAlways , __doOnDemandDomains, NULL },
+ { "always" , "domain", isOther , &kSCPropNetPPPOnDemandMatchDomainsAlways , __doOnDemandDomains, NULL },
+ { "OnDemandMatchDomainsOnRetry", "domain", isOther , &kSCPropNetPPPOnDemandMatchDomainsOnRetry, __doOnDemandDomains, NULL },
+ { "retry" , "domain", isOther , &kSCPropNetPPPOnDemandMatchDomainsOnRetry, __doOnDemandDomains, NULL },
+ { "OnDemandMatchDomainsNever" , "domain", isOther , &kSCPropNetPPPOnDemandMatchDomainsNever , __doOnDemandDomains, NULL },
+ { "never" , "domain", isOther , &kSCPropNetPPPOnDemandMatchDomainsNever , __doOnDemandDomains, NULL },
+
+ { "?" , NULL , isHelp , NULL , NULL ,
+ "\nOnDemandMatch configuration commands\n\n"
+ " set interface OnDemand always domain-name[,domain-name]\n"
+ " set interface OnDemand retry domain-name[,domain-name]\n"
+ " set interface OnDemand never domain-name[,domain-name]\n"
+ }
+};
+#define N_PPP_ONDEMAND_OPTIONS (sizeof(pppOnDemandOptions) / sizeof(pppOnDemandOptions[0]))
+
+
+static int
+__doPPPOnDemandMatch(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ Boolean ok;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("set what?\n"));
+ return -1;
+ }
+
+ ok = _process_options(pppOnDemandOptions, N_PPP_ONDEMAND_OPTIONS, argc, argv, newConfiguration);
+ if (!ok) {
+ goto done;
+ }
+
+ done :
+
+ return argc;
+}
+#endif // NOTYET
+
+
static selections authPromptSelections[] = {
{ CFSTR("before"), &kSCValNetPPPAuthPromptBefore, 0 },
{ CFSTR("after") , &kSCValNetPPPAuthPromptAfter , 0 },
static options pppOptions[] = {
- { "ACSP" , NULL , isBoolean , &kSCPropNetPPPACSPEnabled , NULL , NULL },
- { "ConnectTime" , "?time" , isNumber , &kSCPropNetPPPConnectTime , NULL , NULL },
- { "DialOnDemand" , NULL , isBoolean , &kSCPropNetPPPDialOnDemand , NULL , NULL },
- { "DisconnectOnFastUserSwitch", NULL , isBoolean , &kSCPropNetPPPDisconnectOnFastUserSwitch, NULL , NULL },
- { "DisconnectOnIdle" , NULL , isBoolean , &kSCPropNetPPPDisconnectOnIdle , NULL , NULL },
- { "DisconnectOnIdleTimer" , "timeout" , isNumber , &kSCPropNetPPPDisconnectOnIdleTimer , NULL , NULL },
- { "DisconnectOnLogout" , NULL , isBoolean , &kSCPropNetPPPDisconnectOnLogout , NULL , NULL },
- { "DisconnectOnSleep" , NULL , isBoolean , &kSCPropNetPPPDisconnectOnSleep , NULL , NULL },
- { "DisconnectTime" , "?time" , isNumber , &kSCPropNetPPPDisconnectTime , NULL , NULL },
- { "IdleReminder" , NULL , isBoolean , &kSCPropNetPPPIdleReminder , NULL , NULL },
- { "IdleReminderTimer" , "time" , isNumber , &kSCPropNetPPPIdleReminderTimer , NULL , NULL },
- { "Logfile" , "path" , isString , &kSCPropNetPPPLogfile , NULL , NULL },
- { "Plugins" , "plugin" , isStringArray , &kSCPropNetPPPPlugins , NULL , NULL },
- { "RetryConnectTime" , "time" , isNumber , &kSCPropNetPPPRetryConnectTime , NULL , NULL },
- { "SessionTimer" , "time" , isNumber , &kSCPropNetPPPSessionTimer , NULL , NULL },
- { "UseSessionTimer" , NULL , isBoolean , &kSCPropNetPPPUseSessionTimer , NULL , NULL },
- { "VerboseLogging" , NULL , isBoolean , &kSCPropNetPPPVerboseLogging , NULL , NULL },
+ { "ACSP" , NULL , isBoolean , &kSCPropNetPPPACSPEnabled , NULL , NULL },
+ { "ConnectTime" , "?time" , isNumber , &kSCPropNetPPPConnectTime , NULL , NULL },
+ { "DialOnDemand" , NULL , isBoolean , &kSCPropNetPPPDialOnDemand , NULL , NULL },
+ { "DisconnectOnFastUserSwitch", NULL , isBoolean , &kSCPropNetPPPDisconnectOnFastUserSwitch, NULL , NULL },
+ { "DisconnectOnIdle" , NULL , isBoolean , &kSCPropNetPPPDisconnectOnIdle , NULL , NULL },
+ { "DisconnectOnIdleTimer" , "timeout" , isNumber , &kSCPropNetPPPDisconnectOnIdleTimer , NULL , NULL },
+ { "DisconnectOnLogout" , NULL , isBoolean , &kSCPropNetPPPDisconnectOnLogout , NULL , NULL },
+ { "DisconnectOnSleep" , NULL , isBoolean , &kSCPropNetPPPDisconnectOnSleep , NULL , NULL },
+ { "DisconnectTime" , "?time" , isNumber , &kSCPropNetPPPDisconnectTime , NULL , NULL },
+ { "IdleReminder" , NULL , isBoolean , &kSCPropNetPPPIdleReminder , NULL , NULL },
+ { "IdleReminderTimer" , "time" , isNumber , &kSCPropNetPPPIdleReminderTimer , NULL , NULL },
+ { "Logfile" , "path" , isString , &kSCPropNetPPPLogfile , NULL , NULL },
+ { "Plugins" , "plugin" , isStringArray , &kSCPropNetPPPPlugins , NULL , NULL },
+ { "RetryConnectTime" , "time" , isNumber , &kSCPropNetPPPRetryConnectTime , NULL , NULL },
+ { "SessionTimer" , "time" , isNumber , &kSCPropNetPPPSessionTimer , NULL , NULL },
+ { "UseSessionTimer" , NULL , isBoolean , &kSCPropNetPPPUseSessionTimer , NULL , NULL },
+ { "VerboseLogging" , NULL , isBoolean , &kSCPropNetPPPVerboseLogging , NULL , NULL },
// --- Auth: ---
- { "AuthEAPPlugins" , "plugin" , isStringArray , &kSCPropNetPPPAuthEAPPlugins , NULL , NULL },
- { "AuthName" , "account" , isString , &kSCPropNetPPPAuthName , NULL , NULL },
- { "Account" , "account" , isString , &kSCPropNetPPPAuthName , NULL , NULL },
- { "AuthPassword" , "password" , isOther , &kSCPropNetPPPAuthPassword , __doPPPAuthPW , NULL },
- { "Password" , "password" , isOther , &kSCPropNetPPPAuthPassword , __doPPPAuthPW , NULL },
- { "AuthPasswordEncryption" , "type" , isOther , &kSCPropNetPPPAuthPasswordEncryption , __doPPPAuthPWType, NULL },
- { "AuthPrompt" , "before/after", isChooseOne , &kSCPropNetPPPAuthPrompt , NULL , (void *)authPromptSelections },
- { "AuthProtocol" , "protocol" , isChooseMultiple , &kSCPropNetPPPAuthProtocol , NULL , (void *)authProtocolSelections },
+ { "AuthEAPPlugins" , "plugin" , isStringArray , &kSCPropNetPPPAuthEAPPlugins , NULL , NULL },
+ { "AuthName" , "account" , isString , &kSCPropNetPPPAuthName , NULL , NULL },
+ { "Account" , "account" , isString , &kSCPropNetPPPAuthName , NULL , NULL },
+ { "AuthPassword" , "password" , isOther , &kSCPropNetPPPAuthPassword , __doPPPAuthPW , NULL },
+ { "Password" , "password" , isOther , &kSCPropNetPPPAuthPassword , __doPPPAuthPW , NULL },
+ { "AuthPasswordEncryption" , "type" , isOther , &kSCPropNetPPPAuthPasswordEncryption , __doPPPAuthPWType , NULL },
+ { "AuthPrompt" , "before/after", isChooseOne , &kSCPropNetPPPAuthPrompt , NULL , (void *)authPromptSelections },
+ { "AuthProtocol" , "protocol" , isChooseMultiple , &kSCPropNetPPPAuthProtocol , NULL , (void *)authProtocolSelections },
// --- Comm: ---
- { "CommRemoteAddress" , "phone#" , isString , &kSCPropNetPPPCommRemoteAddress , NULL , NULL },
- { "CommAlternateRemoteAddress", "phone#" , isString , &kSCPropNetPPPCommAlternateRemoteAddress, NULL , NULL },
- { "CommConnectDelay" , "time" , isNumber , &kSCPropNetPPPCommConnectDelay , NULL , NULL },
- { "CommDisplayTerminalWindow" , NULL , isBoolean , &kSCPropNetPPPCommDisplayTerminalWindow , NULL , NULL },
- { "CommRedialCount" , "retry count" , isNumber , &kSCPropNetPPPCommRedialCount , NULL , NULL },
- { "CommRedialEnabled" , NULL , isBoolean , &kSCPropNetPPPCommRedialEnabled , NULL , NULL },
- { "CommRedialInterval" , "retry delay" , isNumber , &kSCPropNetPPPCommRedialInterval , NULL , NULL },
- { "CommTerminalScript" , "script" , isString , &kSCPropNetPPPCommTerminalScript , NULL , NULL },
- { "CommUseTerminalScript" , NULL , isBoolean , &kSCPropNetPPPCommUseTerminalScript , NULL , NULL },
+ { "CommRemoteAddress" , "phone#" , isString , &kSCPropNetPPPCommRemoteAddress , NULL , NULL },
+ { "CommAlternateRemoteAddress", "phone#" , isString , &kSCPropNetPPPCommAlternateRemoteAddress, NULL , NULL },
+ { "CommConnectDelay" , "time" , isNumber , &kSCPropNetPPPCommConnectDelay , NULL , NULL },
+ { "CommDisplayTerminalWindow" , NULL , isBoolean , &kSCPropNetPPPCommDisplayTerminalWindow , NULL , NULL },
+ { "CommRedialCount" , "retry count" , isNumber , &kSCPropNetPPPCommRedialCount , NULL , NULL },
+ { "CommRedialEnabled" , NULL , isBoolean , &kSCPropNetPPPCommRedialEnabled , NULL , NULL },
+ { "CommRedialInterval" , "retry delay" , isNumber , &kSCPropNetPPPCommRedialInterval , NULL , NULL },
+ { "CommTerminalScript" , "script" , isString , &kSCPropNetPPPCommTerminalScript , NULL , NULL },
+ { "CommUseTerminalScript" , NULL , isBoolean , &kSCPropNetPPPCommUseTerminalScript , NULL , NULL },
// --- CCP: ---
- { "CCPEnabled" , NULL , isBoolean , &kSCPropNetPPPCCPEnabled , NULL , NULL },
- { "CCPMPPE40Enabled" , NULL , isBoolean , &kSCPropNetPPPCCPMPPE40Enabled , NULL , NULL },
- { "CCPMPPE128Enabled" , NULL , isBoolean , &kSCPropNetPPPCCPMPPE128Enabled , NULL , NULL },
+ { "CCPEnabled" , NULL , isBoolean , &kSCPropNetPPPCCPEnabled , NULL , NULL },
+ { "CCPMPPE40Enabled" , NULL , isBoolean , &kSCPropNetPPPCCPMPPE40Enabled , NULL , NULL },
+ { "CCPMPPE128Enabled" , NULL , isBoolean , &kSCPropNetPPPCCPMPPE128Enabled , NULL , NULL },
// --- IPCP: ---
- { "IPCPCompressionVJ" , NULL , isBoolean , &kSCPropNetPPPIPCPCompressionVJ , NULL , NULL },
- { "IPCPUsePeerDNS" , NULL , isBoolean , &kSCPropNetPPPIPCPUsePeerDNS , NULL , NULL },
+ { "IPCPCompressionVJ" , NULL , isBoolean , &kSCPropNetPPPIPCPCompressionVJ , NULL , NULL },
+ { "IPCPUsePeerDNS" , NULL , isBoolean , &kSCPropNetPPPIPCPUsePeerDNS , NULL , NULL },
// --- LCP: ---
- { "LCPEchoEnabled" , NULL , isBoolean , &kSCPropNetPPPLCPEchoEnabled , NULL , NULL },
- { "LCPEchoFailure" , NULL , isNumber , &kSCPropNetPPPLCPEchoFailure , NULL , NULL },
- { "LCPEchoInterval" , NULL , isNumber , &kSCPropNetPPPLCPEchoInterval , NULL , NULL },
- { "LCPCompressionACField" , NULL , isBoolean , &kSCPropNetPPPLCPCompressionACField , NULL , NULL },
- { "LCPCompressionPField" , NULL , isBoolean , &kSCPropNetPPPLCPCompressionPField , NULL , NULL },
- { "LCPMRU" , NULL , isNumber , &kSCPropNetPPPLCPMRU , NULL , NULL },
- { "LCPMTU" , NULL , isNumber , &kSCPropNetPPPLCPMTU , NULL , NULL },
- { "LCPReceiveACCM" , NULL , isNumber , &kSCPropNetPPPLCPReceiveACCM , NULL , NULL },
- { "LCPTransmitACCM" , NULL , isNumber , &kSCPropNetPPPLCPTransmitACCM , NULL , NULL },
+ { "LCPEchoEnabled" , NULL , isBoolean , &kSCPropNetPPPLCPEchoEnabled , NULL , NULL },
+ { "LCPEchoFailure" , NULL , isNumber , &kSCPropNetPPPLCPEchoFailure , NULL , NULL },
+ { "LCPEchoInterval" , NULL , isNumber , &kSCPropNetPPPLCPEchoInterval , NULL , NULL },
+ { "LCPCompressionACField" , NULL , isBoolean , &kSCPropNetPPPLCPCompressionACField , NULL , NULL },
+ { "LCPCompressionPField" , NULL , isBoolean , &kSCPropNetPPPLCPCompressionPField , NULL , NULL },
+ { "LCPMRU" , NULL , isNumber , &kSCPropNetPPPLCPMRU , NULL , NULL },
+ { "LCPMTU" , NULL , isNumber , &kSCPropNetPPPLCPMTU , NULL , NULL },
+ { "LCPReceiveACCM" , NULL , isNumber , &kSCPropNetPPPLCPReceiveACCM , NULL , NULL },
+ { "LCPTransmitACCM" , NULL , isNumber , &kSCPropNetPPPLCPTransmitACCM , NULL , NULL },
+
+ // --- IPSec: ---
+ { "IPSec" , NULL , isOther , NULL , __doPPPIPSec , NULL },
+
+#ifdef NOTYET
+ // --- OnDemand: ---
+ { "OnDemandEnabled" , NULL , isBoolean , &kSCPropNetPPPOnDemandEnabled , NULL , NULL },
+ { "OnDemandMatch" , NULL , isOther , NULL , __doPPPOnDemandMatch, NULL },
+#endif // NOTYET
// --- Help ---
- { "?" , NULL , isHelp , NULL , NULL ,
+ { "?" , NULL , isHelp , NULL , NULL ,
"\nPPP configuration commands\n\n"
" set interface [Account account]\n"
" set interface [Password password]\n"
" set interface [IdleReminderTimer time-in-seconds]\n"
" set interface [DisconnectOnIdle {enable|disable}]\n"
" set interface [DisconnectOnIdleTimer time-in-seconds]\n"
- " set interface [DisconnectOnLogout {enable|disable}]"
+ " set interface [DisconnectOnLogout {enable|disable}]\n"
+ " set interface [IPSec <ipsec-options>]\n"
+#ifdef NOTYET
+ " set interface [OnDemandEnabled {enable|disable}]\n"
+ " set interface [OnDemandMatch <match-options>]\n"
+#endif // NOTYET
}
};
#define N_PPP_OPTIONS (sizeof(pppOptions) / sizeof(pppOptions[0]))
}
-/* -------------------- */
+#pragma mark -
+#pragma mark VLAN options
static Boolean
}
-/* -------------------- */
+#pragma mark -
+#pragma mark VPN options
+
+
+static int
+__doVPNAuthPW(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ CFStringRef encryptionType;
+
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("VPN password not specified\n"));
+ return -1;
+ }
+
+ encryptionType = CFDictionaryGetValue(newConfiguration, kSCPropNetVPNAuthPasswordEncryption);
+ if (strlen(argv[0]) > 0) {
+ if (encryptionType == NULL) {
+#ifdef INLINE_PASSWORDS_USE_CFSTRING
+ CFStringRef pw;
+
+ pw = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+#else // INLINE_PASSWORDS_USE_CFSTRING
+ CFIndex n;
+ CFMutableDataRef pw;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ n = CFStringGetLength(str);
+ pw = CFDataCreateMutable(NULL, n * sizeof(UniChar));
+ CFDataSetLength(pw, n * sizeof(UniChar));
+ CFStringGetCharacters(str,
+ CFRangeMake(0, n),
+ (UniChar *)(void *)CFDataGetMutableBytePtr(pw));
+ CFRelease(str);
+#endif // INLINE_PASSWORDS_USE_CFSTRING
+
+ CFDictionarySetValue(newConfiguration, key, pw);
+ CFRelease(pw);
+ } else if (CFEqual(encryptionType, kSCValNetVPNAuthPasswordEncryptionKeychain)) {
+ Boolean ok;
+ CFDataRef pw;
+ CFStringRef str;
+
+ str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
+ pw = CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingUTF8, 0);
+ ok = SCNetworkInterfaceSetPassword(net_interface,
+ kSCNetworkInterfacePasswordTypeVPN,
+ pw,
+ NULL);
+ CFRelease(pw);
+ CFRelease(str);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("VPN password type \"%@\" not supported\n"), encryptionType);
+ return -1;
+ }
+ } else {
+ if (encryptionType == NULL) {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ } else if (CFEqual(encryptionType, kSCValNetVPNAuthPasswordEncryptionKeychain)) {
+ Boolean ok;
+
+ ok = SCNetworkInterfaceRemovePassword(net_interface, kSCNetworkInterfacePasswordTypeVPN);
+ if (ok) {
+ updateInterfaceConfiguration(newConfiguration);
+ } else {
+ return -1;
+ }
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("PPP password type \"%@\" not supported\n"), encryptionType);
+ return -1;
+ }
+ }
+
+ return 1;
+}
+
+
+static int
+__doVPNAuthPWType(CFStringRef key, const char *description, void *info, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ if (argc < 1) {
+ SCPrint(TRUE, stdout, CFSTR("VPN password type mode not specified\n"));
+ return -1;
+ }
+
+ if (strlen(argv[0]) > 0) {
+ if (strcasecmp(argv[0], "keychain") == 0) {
+ CFDictionarySetValue(newConfiguration, key, kSCValNetVPNAuthPasswordEncryptionKeychain);
+ } else if (strcasecmp(argv[0], "prompt") == 0) {
+ CFDictionarySetValue(newConfiguration, key, kSCValNetVPNAuthPasswordEncryptionPrompt);
+ } else {
+ SCPrint(TRUE, stdout, CFSTR("invalid password type\n"));
+ return -1;
+ }
+ } else {
+ CFDictionaryRemoveValue(newConfiguration, key);
+ }
+
+ // encryption type changed, reset password
+ CFDictionaryRemoveValue(newConfiguration, kSCPropNetVPNAuthPassword);
+
+ return 1;
+}
+
+
+static selections vpnAuthenticationMethodSelections[] = {
+ { CFSTR("Password") , &kSCValNetVPNAuthenticationMethodPassword , 0 },
+ { CFSTR("Certificate") , &kSCValNetVPNAuthenticationMethodCertificate , 0 },
+ { NULL , NULL , 0 }
+};
+
+
+static options vpnOptions[] = {
+ { "AuthName" , "account" , isString , &kSCPropNetVPNAuthName , NULL , NULL },
+ { "Account" , "account" , isString , &kSCPropNetVPNAuthName , NULL , NULL },
+ { "AuthPassword" , "password" , isOther , &kSCPropNetVPNAuthPassword , __doVPNAuthPW , NULL },
+ { "Password" , "password" , isOther , &kSCPropNetVPNAuthPassword , __doVPNAuthPW , NULL },
+ { "AuthPasswordEncryption" , "type" , isOther , &kSCPropNetVPNAuthPasswordEncryption , __doVPNAuthPWType , NULL },
+ { "AuthenticationMethod" , NULL , isChooseOne , &kSCPropNetVPNAuthenticationMethod , NULL , (void *)vpnAuthenticationMethodSelections },
+ { "ConnectTime" , "?time" , isNumber , &kSCPropNetVPNConnectTime , NULL , NULL },
+ { "DisconnectOnFastUserSwitch", NULL , isBoolean , &kSCPropNetVPNDisconnectOnFastUserSwitch, NULL , NULL },
+ { "DisconnectOnIdle" , NULL , isBoolean , &kSCPropNetVPNDisconnectOnIdle , NULL , NULL },
+ { "DisconnectOnIdleTimer" , "timeout" , isNumber , &kSCPropNetVPNDisconnectOnIdleTimer , NULL , NULL },
+ { "DisconnectOnLogout" , NULL , isBoolean , &kSCPropNetVPNDisconnectOnLogout , NULL , NULL },
+ { "DisconnectOnSleep" , NULL , isBoolean , &kSCPropNetVPNDisconnectOnSleep , NULL , NULL },
+ { "Logfile" , "path" , isString , &kSCPropNetVPNLogfile , NULL , NULL },
+ { "MTU" , NULL , isNumber , &kSCPropNetVPNMTU , NULL , NULL },
+ { "RemoteAddress" , "server" , isString , &kSCPropNetVPNRemoteAddress , NULL , NULL },
+ { "Server" , "server" , isString , &kSCPropNetVPNRemoteAddress , NULL , NULL },
+ { "VerboseLogging" , NULL , isBoolean , &kSCPropNetVPNVerboseLogging , NULL , NULL },
+
+ // --- Help ---
+ { "?" , NULL , isHelp , NULL , NULL ,
+ "\nVPN configuration commands\n\n"
+ " set interface [Server server]\n"
+ " set interface [Account account]\n"
+ " set interface [Password password]\n"
+ }
+};
+#define N_VPN_OPTIONS (sizeof(vpnOptions) / sizeof(vpnOptions[0]))
+
+
+static Boolean
+set_interface_vpn(int argc, char **argv, CFMutableDictionaryRef newConfiguration)
+{
+ Boolean ok;
+
+ ok = _process_options(vpnOptions, N_VPN_OPTIONS, argc, argv, newConfiguration);
+ return ok;
+}
+
+
+#pragma mark -
+#pragma mark [more] Interface management
__private_extern__
}
configuration = SCNetworkInterfaceGetConfiguration(net_interface);
- if (configuration == NULL) {
+ if (configuration != NULL) {
+ configuration = CFDictionaryCreateCopy(NULL, configuration);
+ newConfiguration = CFDictionaryCreateMutableCopy(NULL, 0, configuration);
+ CFDictionaryRemoveValue(newConfiguration, kSCResvInactive);
+ } else {
newConfiguration = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- } else {
- newConfiguration = CFDictionaryCreateMutableCopy(NULL, 0, configuration);
- CFDictionaryRemoveValue(newConfiguration, kSCResvInactive);
}
interfaceType = SCNetworkInterfaceGetInterfaceType(net_interface);
- if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBond)) {
- ok = set_interface_bond(argc, argv, newConfiguration);
- } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeEthernet)) {
+ if (CFEqual(interfaceType, kSCNetworkInterfaceTypeEthernet)) {
ok = set_interface_ethernet(argc, argv, newConfiguration);
} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeFireWire)) {
ok = set_interface_firewire(argc, argv, newConfiguration);
+ } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) {
+ ok = set_interface_ipsec(argc, argv, newConfiguration);
} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeModem)) {
ok = set_interface_modem(argc, argv, newConfiguration);
} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIEEE80211)) {
ok = set_interface_airport(argc, argv, newConfiguration);
} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPP)) {
ok = set_interface_ppp(argc, argv, newConfiguration);
+ } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBond)) {
+ ok = set_interface_bond(argc, argv, newConfiguration);
+ } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeBridge)) {
+ ok = set_interface_bridge(argc, argv, newConfiguration);
} else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVLAN)) {
ok = set_interface_vlan(argc, argv, newConfiguration);
+ } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) {
+ ok = set_interface_vpn(argc, argv, newConfiguration);
} else {
SCPrint(TRUE, stdout, CFSTR("this interfaces configuration cannot be changed\n"));
}
goto done;
}
- net_changed = TRUE;
+ _prefs_changed = TRUE;
}
done :
+ if (configuration != NULL) CFRelease(configuration);
if (newConfiguration != NULL) CFRelease(newConfiguration);
return;
}
{
SCNetworkInterfaceRef interface;
- if (argc == 1) {
- interface = _find_interface(argv[0]);
+ if (argc >= 1) {
+ interface = _find_interface(argc, argv, NULL);
} else {
if (net_interface != NULL) {
interface = net_interface;
__private_extern__
-CFStringRef
+CF_RETURNS_RETAINED CFStringRef
_interface_description(SCNetworkInterfaceRef interface)
{
CFMutableStringRef description;