/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#import "Network.h"
NSString *NetworkAddressesKey = @"addresses";
NSString *NetworkBridgeKey = @"bridge";
NSString *NetworkBroadcastKey = @"broadcast";
NSString *NetworkDhcpKey = @"dhcp";
NSString *NetworkMacKey = @"mac";
NSString *NetworkMtuKey = @"mtu";
NSString *NetworkMulticastKey = @"multicast";
NSString *NetworkNameKey = @"name";
NSString *NetworkNetconfKey = @"netconf";
NSString *NetworkNwidKey = @"nwid";
NSString *NetworkPortNameKey = @"port";
NSString *NetworkPortErrorKey = @"portError";
NSString *NetworkStatusKey = @"status";
NSString *NetworkTypeKey = @"type";
NSString *NetworkAllowManagedKey = @"allowManaged";
NSString *NetworkAllowGlobalKey = @"allowGlobal";
NSString *NetworkAllowDefaultKey = @"allowDefault";
NSString *NetworkAllowDNSKey = @"allowDNS";
@implementation Network
- (id)initWithJsonData:(NSDictionary*)jsonData
{
self = [super init];
if(self) {
if([jsonData objectForKey:@"assignedAddresses"]) {
_assignedAddresses = (NSArray*)[jsonData objectForKey:@"assignedAddresses"];
}
if([jsonData objectForKey:@"bridge"]) {
_bridge = [(NSNumber*)[jsonData objectForKey:@"bridge"] boolValue];
}
if([jsonData objectForKey:@"broadcastEnabled"]) {
_broadcastEnabled = [(NSNumber*)[jsonData objectForKey:@"broadcastEnabled"] boolValue];
}
if([jsonData objectForKey:@"dhcp"]) {
_dhcp = [(NSNumber*)[jsonData objectForKey:@"dhcp"] boolValue];
}
if([jsonData objectForKey:@"mac"]) {
_mac = (NSString*)[jsonData objectForKey:@"mac"];
}
if([jsonData objectForKey:@"mtu"]) {
_mtu = [(NSNumber*)[jsonData objectForKey:@"mtu"] intValue];
}
if([jsonData objectForKey:@"name"]) {
_name = (NSString*)[jsonData objectForKey:@"name"];
}
if([jsonData objectForKey:@"netconfRevision"]) {
_netconfRevision = [(NSNumber*)[jsonData objectForKey:@"netconfRevision"] intValue];
}
if([jsonData objectForKey:@"nwid"]) {
NSString *networkid = (NSString*)[jsonData objectForKey:@"nwid"];
NSScanner *scanner = [NSScanner scannerWithString:networkid];
[scanner scanHexLongLong:&_nwid];
}
if([jsonData objectForKey:@"portDeviceName"]) {
_portDeviceName = (NSString*)[jsonData objectForKey:@"portDeviceName"];
}
if([jsonData objectForKey:@"portError"]) {
_portError = [(NSNumber*)[jsonData objectForKey:@"portError"] intValue];
}
if([jsonData objectForKey:@"allowManaged"]) {
_allowManaged = [(NSNumber*)[jsonData objectForKey:@"allowManaged"] boolValue];
}
if([jsonData objectForKey:@"allowGlobal"]) {
_allowGlobal = [(NSNumber*)[jsonData objectForKey:@"allowGlobal"] boolValue];
}
if([jsonData objectForKey:@"allowDefault"]) {
_allowDefault = [(NSNumber*)[jsonData objectForKey:@"allowDefault"] boolValue];
}
if([jsonData objectForKey:@"allowDNS"]) {
_allowDNS = [(NSNumber*)[jsonData objectForKey:@"allowDNS"] boolValue];
} else {
_allowDNS = false;
}
if([jsonData objectForKey:@"status"]) {
NSString *statusStr = (NSString*)[jsonData objectForKey:@"status"];
if([statusStr isEqualToString:@"REQUESTING_CONFIGURATION"]) {
_status = REQUESTING_CONFIGURATION;
}
else if([statusStr isEqualToString:@"OK"]) {
_status = OK;
}
else if([statusStr isEqualToString:@"ACCESS_DENIED"]) {
_status = ACCESS_DENIED;
}
else if([statusStr isEqualToString:@"NOT_FOUND"]) {
_status = NOT_FOUND;
}
else if([statusStr isEqualToString:@"PORT_ERROR"]) {
_status = PORT_ERROR;
}
else if([statusStr isEqualToString:@"CLIENT_TOO_OLD"]) {
_status = CLIENT_TOO_OLD;
}
}
if([jsonData objectForKey:@"type"]) {
NSString *typeStr = (NSString*)[jsonData objectForKey:@"type"];
if([typeStr isEqualToString:@"PRIVATE"]) {
_type = PRIVATE;
}
else if([typeStr isEqualToString:@"PUBLIC"]) {
_type = PUBLIC;
}
}
_connected = YES;
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if(self) {
if([aDecoder containsValueForKey:NetworkAddressesKey]) {
_assignedAddresses = (NSArray*)[aDecoder decodeObjectForKey:NetworkAddressesKey];
}
if([aDecoder containsValueForKey:NetworkBridgeKey]) {
_bridge = [aDecoder decodeBoolForKey:NetworkBridgeKey];
}
if([aDecoder containsValueForKey:NetworkBroadcastKey]) {
_broadcastEnabled = [aDecoder decodeBoolForKey:NetworkBroadcastKey];
}
if([aDecoder containsValueForKey:NetworkDhcpKey]) {
_dhcp = [aDecoder decodeBoolForKey:NetworkDhcpKey];
}
if([aDecoder containsValueForKey:NetworkMacKey]) {
_mac = (NSString*)[aDecoder decodeObjectForKey:NetworkMacKey];
}
if([aDecoder containsValueForKey:NetworkMtuKey]) {
_mtu = (int)[aDecoder decodeIntegerForKey:NetworkMtuKey];
}
if([aDecoder containsValueForKey:NetworkNameKey]) {
_name = (NSString*)[aDecoder decodeObjectForKey:NetworkNameKey];
}
if([aDecoder containsValueForKey:NetworkNetconfKey]) {
_netconfRevision = (int)[aDecoder decodeIntegerForKey:NetworkNetconfKey];
}
if([aDecoder containsValueForKey:NetworkNwidKey]) {
_nwid = [(NSNumber*)[aDecoder decodeObjectForKey:NetworkNwidKey] unsignedLongLongValue];
}
if([aDecoder containsValueForKey:NetworkPortNameKey]) {
_portDeviceName = (NSString*)[aDecoder decodeObjectForKey:NetworkPortNameKey];
}
if([aDecoder containsValueForKey:NetworkPortErrorKey]) {
_portError = (int)[aDecoder decodeIntegerForKey:NetworkPortErrorKey];
}
if([aDecoder containsValueForKey:NetworkStatusKey]) {
_status = (enum NetworkStatus)[aDecoder decodeIntegerForKey:NetworkStatusKey];
}
if([aDecoder containsValueForKey:NetworkTypeKey]) {
_type = (enum NetworkType)[aDecoder decodeIntegerForKey:NetworkTypeKey];
}
if([aDecoder containsValueForKey:NetworkAllowManagedKey]) {
_allowManaged = [aDecoder decodeBoolForKey:NetworkAllowManagedKey];
}
if([aDecoder containsValueForKey:NetworkAllowGlobalKey]) {
_allowGlobal = [aDecoder decodeBoolForKey:NetworkAllowGlobalKey];
}
if([aDecoder containsValueForKey:NetworkAllowDefaultKey]) {
_allowDefault = [aDecoder decodeBoolForKey:NetworkAllowDefaultKey];
}
if([aDecoder containsValueForKey:NetworkAllowDNSKey]) {
_allowDNS = [aDecoder decodeBoolForKey:NetworkAllowDNSKey];
} else {
_allowDNS = false;
}
_connected = NO;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_assignedAddresses forKey:NetworkAddressesKey];
[aCoder encodeBool:_bridge forKey:NetworkBridgeKey];
[aCoder encodeBool:_broadcastEnabled forKey:NetworkBroadcastKey];
[aCoder encodeBool:_dhcp forKey:NetworkDhcpKey];
[aCoder encodeObject:_mac forKey:NetworkMacKey];
[aCoder encodeInteger:_mtu forKey:NetworkMtuKey];
[aCoder encodeObject:_name forKey:NetworkNameKey];
[aCoder encodeInteger:_netconfRevision forKey:NetworkNetconfKey];
[aCoder encodeObject:[NSNumber numberWithUnsignedLongLong:_nwid]
forKey:NetworkNwidKey];
[aCoder encodeObject:_portDeviceName forKey:NetworkPortNameKey];
[aCoder encodeInteger:_portError forKey:NetworkPortErrorKey];
[aCoder encodeInteger:_status forKey:NetworkStatusKey];
[aCoder encodeInteger:_type forKey:NetworkTypeKey];
[aCoder encodeBool:_allowManaged forKey:NetworkAllowManagedKey];
[aCoder encodeBool:_allowGlobal forKey:NetworkAllowGlobalKey];
[aCoder encodeBool:_allowDefault forKey:NetworkAllowDefaultKey];
[aCoder encodeBool:_allowDNS forKey:NetworkAllowDNSKey];
}
+ (BOOL)defaultRouteExists:(NSArray*)netList
{
for(Network *net in netList) {
if (net.allowDefault && net.connected) {
return YES;
}
}
return NO;
}
- (NSString*)statusString {
switch(_status) {
case REQUESTING_CONFIGURATION:
return @"REQUESTING_CONFIGURATION";
case OK:
return @"OK";
case ACCESS_DENIED:
return @"ACCESS_DENIED";
case NOT_FOUND:
return @"NOT_FOUND";
case PORT_ERROR:
return @"PORT_ERROR";
case CLIENT_TOO_OLD:
return @"CLIENT_TOO_OLD";
default:
return @"";
}
}
- (NSString*)typeString {
switch(_type) {
case PUBLIC:
return @"PUBLIC";
case PRIVATE:
return @"PRIVATE";
default:
return @"";
}
}
- (BOOL)hasSameNetworkId:(UInt64)networkId
{
return self.nwid == networkId;
}
- (BOOL)isEqualToNetwork:(Network*)network
{
return [self.assignedAddresses isEqualToArray:network.assignedAddresses] &&
self.bridge == network.bridge &&
self.broadcastEnabled == network.broadcastEnabled &&
self.dhcp == network.dhcp &&
[self.mac isEqualToString:network.mac] &&
self.mtu == network.mtu &&
self.netconfRevision == network.netconfRevision &&
[self.name isEqualToString:network.name] &&
self.nwid == network.nwid &&
[self.portDeviceName isEqualToString:network.portDeviceName] &&
self.status == network.status &&
self.type == network.type &&
self.allowManaged == network.allowManaged &&
self.allowGlobal == network.allowGlobal &&
self.allowDefault == network.allowDefault &&
self.allowDNS == network.allowDNS &&
self.connected == network.connected;
}
- (BOOL)isEqual:(id)object
{
if (self == object) {
return YES;
}
if (![object isKindOfClass:[Network class]]) {
return NO;
}
return [self isEqualToNetwork:object];
}
- (NSUInteger)hash
{
return [self.assignedAddresses hash] ^
self.bridge ^
self.broadcastEnabled ^
self.dhcp ^
[self.mac hash] ^
self.mtu ^
self.netconfRevision ^
[self.name hash] ^
self.nwid ^
[self.portDeviceName hash] ^
self.portError ^
self.status ^
self.type ^
self.allowManaged ^
self.allowGlobal ^
self.allowDefault ^
self.allowDNS ^
self.connected;
}
@end