diff --git a/Base.lproj/MainMenu.xib b/Base.lproj/MainMenu.xib index 348f392..15abda1 100644 --- a/Base.lproj/MainMenu.xib +++ b/Base.lproj/MainMenu.xib @@ -1,14 +1,14 @@ - + - + - + @@ -69,12 +69,12 @@ - + - + @@ -129,7 +129,7 @@ - + @@ -152,131 +152,32 @@ - - - - + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + @@ -284,7 +185,7 @@ - + @@ -292,14 +193,14 @@ - + - + - + @@ -307,7 +208,7 @@ - + @@ -315,14 +216,14 @@ - + - + - + @@ -330,7 +231,7 @@ - + @@ -338,14 +239,14 @@ - + - + - + @@ -353,7 +254,7 @@ - + @@ -361,14 +262,14 @@ - + - + - + @@ -376,7 +277,7 @@ - + @@ -384,14 +285,14 @@ - + - + - + @@ -404,14 +305,14 @@ - + - + - + @@ -424,14 +325,14 @@ - + - + - + @@ -443,15 +344,117 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -459,18 +462,18 @@ - + - + - - + + - + @@ -488,7 +491,7 @@ - + @@ -500,7 +503,7 @@ - + @@ -512,7 +515,7 @@ - + @@ -526,33 +529,33 @@ - + - + - + - + - + - + - + @@ -561,11 +564,11 @@ - + - + - + @@ -573,14 +576,14 @@ @@ -588,18 +591,18 @@ - + - + - + - + @@ -607,7 +610,7 @@ - + @@ -615,14 +618,14 @@ - + - + - + @@ -630,7 +633,7 @@ - + @@ -638,14 +641,14 @@ - + - + - + @@ -653,42 +656,22 @@ - + - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -696,7 +679,7 @@ - + @@ -704,14 +687,14 @@ - + - + - + @@ -724,14 +707,14 @@ - + - + - + @@ -739,7 +722,275 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -752,7 +1003,7 @@ - + @@ -760,31 +1011,11 @@ - + - - - - - - - - - - - - + + @@ -794,59 +1025,93 @@ + + + + + + + + + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IPSubnetCalc.h b/IPSubnetCalc.h deleted file mode 100644 index 2f8e620..0000000 --- a/IPSubnetCalc.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// IPSubnetCalc.h -// SubnetCalc -// -// Created by Julien Mulot on Tue May 06 2003. -// Copyright (c) 2009 Julien Mulot. All rights reserved. -// - -#import -#import -#import -#import -#import -#import - -#define DOT(x) ((8 * (x)) + ((x) - 1)) - -@interface IPSubnetCalc : NSObject { - NSString *networkClass; - - unsigned int netId; - unsigned int netBits; - unsigned int mask; - - unsigned int subnetMax; - unsigned int subnetBits; - unsigned int maskBits; - unsigned int subnetBitsMax; - unsigned int subnetMask; - - unsigned int hostBits; - unsigned int hostMax; - unsigned int hostAddr; - unsigned int hostId; - unsigned int hostSubnetLbound; - unsigned int hostSubnetUbound; - - unsigned int ciscoWildcard; - char bitMap[36]; - Boolean classless; -} - -@property Boolean classless; - -+ (NSString *)denumberize:(unsigned int)address; -+ (unsigned int)numberize:(const char *)address; -+ (int)countOnBits:(unsigned int)number; -- (void)initAddress:(const char *)address; -- (void)initAddressAndMask:(const char *)address mask:(unsigned int)addressMask; -- (void)initAddressAndMaskWithUnsignedInt:(unsigned int)address mask:(unsigned int)addressMask; -- (NSString *)subnetHostAddrRange; -- (NSString *)networkClass; -- (unsigned int)netBits; -- (NSString *)hexMap; -- (NSString *)binMap; -- (NSString *)bitMap; -- (NSNumber *)hostAddr; -- (unsigned int)hostAddrIntValue; -- (NSNumber *)subnetBits; -- (NSNumber *)maskBits; -- (unsigned int)maskBitsIntValue; -- (NSNumber *)subnetMax; -- (NSNumber *)hostMax; -- (NSString *)subnetMask; -- (unsigned int)subnetMaskIntValue; -- (NSString *)subnetId; -- (NSString *)netId; -- (unsigned int)netIdIntValue; -- (NSString *)subnetBroadcast; -- (NSString *)supernetRoute:(int)supernetMaskBits; -- (NSString *)supernetAddrRange:(int)supernetMaskBits; - -@end diff --git a/IPSubnetCalc.m b/IPSubnetCalc.m deleted file mode 100644 index 54ef8c5..0000000 --- a/IPSubnetCalc.m +++ /dev/null @@ -1,395 +0,0 @@ -// -// IPSubnetCalc.m -// SubnetCalc -// -// Created by Julien Mulot on Tue May 06 2003. -// Copyright (c) 2009 Julien Mulot. All rights reserved. -// - -#import "IPSubnetCalc.h" - - -@implementation IPSubnetCalc - -@synthesize classless; - -+ (unsigned int)numberize:(const char *)address -{ - unsigned int sin_addr; - - if (address != NULL) - { - if ((inet_pton(AF_INET, address, &sin_addr)) <= 0) - return (-1); - return (ntohl(sin_addr)); - } - return (0); -} - -+ (NSString *)denumberize:(unsigned int)address -{ - char *buffer; - unsigned int addr_nl; - NSString *nstr; - - addr_nl = htonl(address); - if (!(buffer = malloc(INET_ADDRSTRLEN * sizeof (char)))) - return (NULL); - if (!inet_ntop(AF_INET, &addr_nl, buffer, INET_ADDRSTRLEN * sizeof (char))) - { - free(buffer); - return (NULL); - } - nstr = [NSString stringWithCString: buffer encoding: NSASCIIStringEncoding]; - free(buffer); - return (nstr); -} - -- (unsigned int)setBitsFromRight:(int)nbits -{ - int i; - unsigned int number = 0; - - for (i = 0; i < nbits; i++) - number += (int) pow(2, i); - return (number); -} - -+ (int)countOnBits:(unsigned int)number -{ - unsigned int mask_tmp = 1; - int i, on_bits; - - on_bits = 0; - mask_tmp <<= 31; - for (i = 0; i < 32; i++) - { - if (mask_tmp & number) - on_bits++; - number <<= 1; - } - return (on_bits); -} - - -- (IBAction)setBitMap -{ - int i; - int dots = 0; - char bitcode = 'n'; - - bitMap[DOT(1)] = '.'; - bitMap[DOT(2)] = '.'; - bitMap[DOT(3)] = '.'; - bitMap[35] = 0; - - for (i = 0; i < 35; i++) - { - if (i == DOT(1) || i == DOT(2) || i == DOT(3)) - { - dots++; - continue; - } - if (i == (netBits + dots)) - bitcode = 's'; - if (i == (netBits + subnetBits + dots)) - bitcode = 'h'; - bitMap[i] = bitcode; - } -} - -- (IBAction)initNetwork -{ - netId= mask & hostAddr; - maskBits = netBits + subnetBits; - hostBits = 32 - maskBits; - hostMax = pow(2, hostBits) - 2; - hostId = hostAddr - netId; - subnetMask = ~(mask | [self setBitsFromRight:hostBits]); - subnetMax = pow(2, subnetBits); - subnetBitsMax = 32 - netBits; - ciscoWildcard = ~(mask | subnetMask); - hostSubnetLbound = (mask | subnetMask) & hostAddr; - hostSubnetUbound = hostSubnetLbound + hostMax - 1; - [self setBitMap]; -} - -- (IBAction)setMask:(unsigned int)val -{ - mask = val; -} - -- (IBAction)setHostAddr:(unsigned int)val -{ - hostAddr = val; -} - -- (int)incorrectSubnetBits -{ - return (subnetBits > (32 - netBits) ? 1 : 0); -} - -- (char)getClass:(unsigned int)address -{ - unsigned int addr_val; - - addr_val = (address & 0xff000000) >> 24; - - if (addr_val < 127) - return ('a'); - if (addr_val >= 127 && addr_val < 192) - return ('b'); - if (addr_val >= 192 && addr_val < 224) - return ('c'); - return ('d'); -} - -- (int)setClassInfo:(char)class defaults:(const int)setDefaults -{ - switch (class) - { - case 'a' : - networkClass = @"A"; - netBits = 8; - netId = 0x01000000; - mask = 0xff000000; - break; - case 'b' : - networkClass = @"B"; - netBits = 16; - netId = 0x80000000; - mask = 0xffff0000; - break; - case 'c' : - networkClass = @"C"; - netBits = 24; - netId = 0xc0000000; - mask = 0xffffff00; - break; - case 'd' : - networkClass = @"D"; - break; - default : - return (-1); - } - if (setDefaults) - hostAddr = netId + 1; - return (0); -} - -- (void)initByAddr:(unsigned int)address -{ - char class; - - class = [self getClass:address]; - subnetBits = 0; - hostAddr = address; - [self setClassInfo:class defaults:0]; - [self initNetwork]; -} - -- (void)initByAddrAndMask:(unsigned int)address mask:(unsigned int)addressMask -{ - char class; - - class = [self getClass:address]; - hostAddr = address; - [self setClassInfo:class defaults:0]; - if (mask > addressMask) - { - mask = addressMask; - netBits = [IPSubnetCalc countOnBits:addressMask]; - subnetBits = 0; - } - else - { - subnetMask = mask^addressMask; - subnetBits = [IPSubnetCalc countOnBits:subnetMask]; - } - [self initNetwork]; -} - -- (void)initAddress:(const char *)address -{ - if (address) - { - [self initByAddr:[IPSubnetCalc numberize:address]]; - } - -} - -- (void)initAddressAndMask:(const char *)address mask:(unsigned int)addressMask -{ - if (address) - { - [self initByAddrAndMask:[IPSubnetCalc numberize:address] mask:addressMask]; - } - -} - -- (void)initAddressAndMaskWithUnsignedInt:(unsigned int)address mask:(unsigned int)addressMask -{ - [self initByAddrAndMask:address mask:addressMask]; - -} -- (NSString *)subnetHostAddrRange -{ - NSString *strRange; - unsigned int tmpmask; - - strRange = [[NSString alloc] initWithString: [IPSubnetCalc denumberize: ((hostAddr & (mask | subnetMask)) + 1)]]; - tmpmask = -1; - tmpmask >>= maskBits; - return ([strRange stringByAppendingFormat: @" - %@", [IPSubnetCalc denumberize: ((hostAddr | tmpmask) - 1)]]); -} - -- (NSString *)bitMap -{ - return ([NSString stringWithCString: bitMap encoding: NSASCIIStringEncoding]); -} - -- (NSString *)binMap -{ - NSString *str_binmap; - unsigned int address; - unsigned int mask_tmp = 1; - int i; - - str_binmap = [[NSString alloc] init]; - address = hostAddr; - mask_tmp <<= 31; - for (i = 0; i < 32; i++) - { - if (mask_tmp& address) - str_binmap = [str_binmap stringByAppendingString: @"1"]; - else - str_binmap = [str_binmap stringByAppendingString: @"0"]; - address <<= 1; - if (i != 31 && ((i + 1) % 8 == 0)) - str_binmap = [str_binmap stringByAppendingString: @"."]; - } - return (str_binmap); -} - -- (NSString *)hexMap -{ - NSString *str_hexmap; - unsigned int address; - int i; - - str_hexmap = [[NSString alloc] init]; - address = hostAddr; - for (i = 0; i < 4; i++) - { - str_hexmap = [str_hexmap stringByAppendingFormat: @"%.2X", ((address << (8 * i)) >> 24)]; - if (i != 3) - str_hexmap = [str_hexmap stringByAppendingString: @"."]; - } - return (str_hexmap); -} - -- (NSNumber *)subnetBits -{ - return ([NSNumber numberWithUnsignedInt: subnetBits]); -} - -- (NSNumber *)maskBits -{ - return ([NSNumber numberWithUnsignedInt: maskBits]); -} - -- (unsigned int)maskBitsIntValue -{ - return (maskBits); -} - -- (NSNumber *)subnetMax -{ - return ([NSNumber numberWithUnsignedInt: subnetMax]); -} - -- (NSNumber *)hostMax -{ - return ([NSNumber numberWithUnsignedInt: hostMax]); -} - -- (NSString *)subnetId -{ - return ([IPSubnetCalc denumberize: (hostAddr & (mask | subnetMask))]); -} - -- (NSString *)netId -{ - return ([IPSubnetCalc denumberize: (netId)]); -} - -- (unsigned int)netIdIntValue -{ - return (netId); -} - -- (NSString *)subnetMask -{ - return ([IPSubnetCalc denumberize: (mask | subnetMask)]); -} - -- (unsigned int)subnetMaskIntValue -{ - return (mask | subnetMask); -} - -- (NSString *)subnetBroadcast -{ - return ([IPSubnetCalc denumberize: (hostAddr & (mask | subnetMask)) | ~(mask | subnetMask)]); -} - -- (NSNumber *)hostAddr -{ - return ([NSNumber numberWithUnsignedInt: hostAddr]); -} - -- (unsigned int)hostAddrIntValue -{ - return (hostAddr); -} - -- (NSString *)networkClass -{ - return (networkClass); -} - -- (unsigned int)netBits -{ - return (netBits); -} - -- (NSString *)supernetRoute:(int)supernetMaskBits -{ - unsigned int tmpmask = -1; - - tmpmask <<= (32 - supernetMaskBits); - return ([IPSubnetCalc denumberize: (hostAddr & tmpmask)]); -} - -- (NSString *)supernetAddrRange:(int)supernetMaskBits -{ - NSString *strRange; - unsigned int tmpmask = -1; - - tmpmask <<= (32 - supernetMaskBits); - strRange = [[NSString alloc] initWithString: [IPSubnetCalc denumberize: (hostAddr & tmpmask)]]; - tmpmask = -1; - tmpmask >>= supernetMaskBits; - return ([strRange stringByAppendingFormat: @" - %@", [IPSubnetCalc denumberize: (hostAddr | tmpmask)]]); -} - -- (id)init -{ - self = [super init]; - if (self) { - [self setClassless: NO]; - } - return self; -} - -@end diff --git a/IPSubnetcalc.swift b/IPSubnetcalc.swift new file mode 100644 index 0000000..c0de9de --- /dev/null +++ b/IPSubnetcalc.swift @@ -0,0 +1,982 @@ +// +// IPSubnetcalc.swift +// SubnetCalc +// +// Created by Julien Mulot on 22/11/2020. +// + +import Foundation +import Cocoa + + +class IPSubnetCalc: NSObject { + //********* + //Constants + //********* + enum Constants { + //private constants + static let NETWORK_BITS_MIN_CLASSLESS:Int = 1 + static let NETWORK_BITS_MIN:Int = 8 + static let NETWORK_BITS_MAX:Int = 32 + + //IPv6 constants + static let addr16Full: UInt16 = 0xFFFF + static let addr16Empty: UInt16 = 0x0000 + static let defaultIPv6to4Mask: Int = 96 + //static let addr128Full: [UInt16] = [addr16Full, addr16Full, addr16Full, addr16Full, addr16Full, addr16Full, addr16Full, addr16Full] + //static let addr128Empty: [UInt16] = [addr16Empty, addr16Empty, addr16Empty, addr16Empty, addr16Empty, addr16Empty, addr16Empty, addr16Empty] + //static let addr16Hex1: UInt16 = 0xF000 + //static let addr16Hex2: UInt16 = 0x0F00 + //static let addr16Hex3: UInt16 = 0x00F0 + //static let addr16Hex4: UInt16 = 0x000F + static let resIPv6Blocks: [String : String] = ["::1/128" : "Loopback Address", + "::/128" : " Unspecified Address", + "::ffff:0:0/96" : "IPv4-mapped Address", + "64:ff9b::/96" : "IPv4-IPv6 Translation", + "64:ff9b:1::/48" : "IPv4-IPv6 Translation", + "100::/64" : "Discard-Only Address Block", + "2001::/23" : "IETF Protocol Assignments", + "2001::/32" : "TEREDO", + "2001:1::1/128" : "Port Control Protocol Anycast", + "2001:1::2/128" : "Traversal Using Relays around NAT Anycast", + "2001:2::/48" : "Benchmarking", + "2001:3::/32" : "AMT", + "2001:4:112::/48" : "AS112-v6", + "2001:10::/28" : "Deprecated (previously ORCHID)", + "2001:20::/28" : "ORCHIDv2", + "2001:db8::/32" : "Documentation", + "2002::/16" : "6to4", + "2620:4f:8000::/48" : "Direct Delegation AS112 Service", + "fc00::/7" : "Unique-Local", + "fe80::/10" : "Link-Local Unicast" + ] + + //IPv4 constants + static let classAbits: Int = 8 + static let classBbits: Int = 16 + static let classCbits: Int = 24 + static let addr32Full: UInt32 = 0xFFFFFFFF + static let addr32Empty: UInt32 = 0x00000000 + static let addr32Digit1: UInt32 = 0xFF000000 + static let addr32Digit2: UInt32 = 0x00FF0000 + static let addr32Digit3: UInt32 = 0x0000FF00 + static let addr32Digit4: UInt32 = 0x000000FF + static let netIdClassA: UInt32 = 0x01000000 + static let maskClassA: UInt32 = 0xFF000000 + static let netIdClassB: UInt32 = 0x80000000 + static let maskClassB: UInt32 = 0xFFFF0000 + static let netIdClassC: UInt32 = 0xC0000000 + static let maskClassC: UInt32 = 0xFFFFFF00 + static let netIdClassD: UInt32 = 0xE0000000 + static let maskClassD: UInt32 = 0xF0000000 + static let netIdClassE: UInt32 = 0xF0000000 + static let maskClassE: UInt32 = 0xF0000000 + } + + //**************** + //Class Properties + //**************** + var ipv4Address: String + var maskBits: Int + var ipv6Address: String + var ipv6MaskBits: Int + + + //************* + //IPv4 SECTION + //************* + static func binarize(ipAddress: String, space: Bool = false, dotted: Bool = true) -> String { + var ipAddressBin = [String]() + var binStr = String() + var ipDigits = [String]() + + ipDigits = ipAddress.components(separatedBy: ".") + + for index in 0...3 { + ipAddressBin.append(String(Int(ipDigits[index])!, radix: 2)) + while (ipAddressBin[index].count < 8) { + ipAddressBin[index].insert("0", at: ipAddressBin[index].startIndex) + } + + var digitBin = ipAddressBin[index] + if (space == true) { + digitBin.insert(" ", at: ipAddressBin[index].index(ipAddressBin[index].startIndex, offsetBy: 4)) + } + if (index < 3) { + if (dotted == true) { + binStr += digitBin + "." + } + else { + binStr += digitBin + } + } + else { + binStr += digitBin + } + } + return (binStr) + } + + func binaryMap(dotted: Bool = true) -> String { + return (IPSubnetCalc.binarize(ipAddress: ipv4Address, space: false, dotted: dotted)) + } + + static func hexarize(ipAddress: String, dotted: Bool = true) -> String { + var ipDigits = [String]() + var hexIP = String() + var hex4: String + + ipDigits = ipAddress.components(separatedBy: ".") + for index in 0...3 { + hex4 = String(format: "%X", Int(ipDigits[index])!) + if (hex4.count == 1) { + hex4 = "0" + hex4 + } + hexIP += hex4 + if (index < 3) { + if (dotted == true) { + hexIP += "." + } + } + } + return (hexIP) + } + + func hexaMap(dotted: Bool = true) -> String { + return (IPSubnetCalc.hexarize(ipAddress: ipv4Address, dotted: dotted)) + } + + static func numerize(ipAddress: String) -> UInt32 { + var ipAddressNum: UInt32 = 0 + var ipDigits = [String]() + + ipDigits = ipAddress.components(separatedBy: ".") + + for index in 0...3 { + ipAddressNum += UInt32(ipDigits[index])! << (32 - 8 * (index + 1)) + } + return (ipAddressNum & Constants.addr32Full) + } + + //OLD numerize a String as a Mask bits value to UInt32 + /* + static func numerize(maskDigit: String) -> UInt32 { + var maskNum: UInt32 = 0 + + if (Int(maskDigit) != nil) { + maskNum = (Constants.addr32Full << (32 - Int(maskDigit)!)) & Constants.addr32Full + } + return (maskNum) + } + */ + + //numerize a Mask bits value to UInt32 + static func numerize(maskbits: Int) -> UInt32 { + return ((Constants.addr32Full << (32 - maskbits)) & Constants.addr32Full) + } + + static func digitize(ipAddress: UInt32) -> String { + var ipDigits = String() + + ipDigits.append(String(((ipAddress & Constants.addr32Digit1) >> Constants.classCbits)) + ".") + ipDigits.append(String(((ipAddress & Constants.addr32Digit2) >> Constants.classBbits)) + ".") + ipDigits.append(String(((ipAddress & Constants.addr32Digit3) >> Constants.classAbits)) + ".") + ipDigits.append(String(((ipAddress & Constants.addr32Digit4)))) + return (ipDigits) + } + + static func isValidIP(ipAddress: String, mask: String?, classless: Bool = false) -> Bool { + var ip4Digits = [String]() + + ip4Digits = ipAddress.components(separatedBy: ".") + if (ip4Digits.count == 4) { + for item in ip4Digits { + if let digit = Int(item, radix: 10) { + if (digit > 255) { + print("bad IPv4 digit \(digit)") + return false + } + } + else { + print("not digit: \(item)") + return false + } + } + } + else { + print("bad IPv4 format \(ip4Digits)") + return false + } + if mask != nil { + if let maskNum = Int(mask!) { + if (classless == true) { + if (maskNum < Constants.NETWORK_BITS_MIN_CLASSLESS || maskNum > Constants.NETWORK_BITS_MAX) { + print("IPv4 classless mask \(maskNum) invalid") + return false + } + } + else if (maskNum < Constants.NETWORK_BITS_MIN || maskNum > Constants.NETWORK_BITS_MAX) { + print("IPv4 mask \(maskNum) invalid") + return false + } + } + else { + print("IPv4 mask \(mask!) is not digit") + return false + } + } + else { + //print("null mask") + } + return true + } + + func subnetId() -> String { + var subnetId: UInt32 = 0 + let ipBits = IPSubnetCalc.numerize(ipAddress: self.ipv4Address) + let maskBits = IPSubnetCalc.numerize(maskbits: self.maskBits) + + subnetId = ipBits & maskBits + return (IPSubnetCalc.digitize(ipAddress: subnetId)) + } + + func subnetBroadcast() -> String { + var broadcast: UInt32 = 0 + let ipBits = IPSubnetCalc.numerize(ipAddress: self.ipv4Address) + let maskBits = IPSubnetCalc.numerize(maskbits: self.maskBits) + + broadcast = ipBits & maskBits | (Constants.addr32Full >> self.maskBits) + return (IPSubnetCalc.digitize(ipAddress: broadcast)) + } + + func subnetMask() -> String { + var subnetMask: UInt32 = 0 + + subnetMask = Constants.addr32Full << (32 - self.maskBits) + return (IPSubnetCalc.digitize(ipAddress: subnetMask)) + } + + func wildcardMask() -> String { + var wildcardMask: UInt32 = 0 + + wildcardMask = ~(Constants.addr32Full << (32 - self.maskBits)) + return (IPSubnetCalc.digitize(ipAddress: wildcardMask)) + } + + func maxHosts() -> Int { + var maxHosts: UInt32 = 0 + + if (self.maskBits == 32) { + return (0) + } + maxHosts = (Constants.addr32Full >> self.maskBits) - 1 + return (Int(maxHosts)) + } + + func maxCIDRSubnets() -> Int { + var max: Int = 0 + + max = Int(truncating: NSDecimalNumber(decimal: pow(2, (32 - self.maskBits)))) + //max = Int(truncating: pow(2, (32 - self.maskBits)) as NSDecimalNumber) + return (max) + } + + func maxCIDRSupernet() -> Int { + let classType = self.netClass() + var result: Decimal + + if (classType == "A") { + result = pow(2, Constants.classAbits - self.maskBits) + if (result > 0) { + return (Int(truncating: NSDecimalNumber(decimal: result))) + } + } + else if (classType == "B") { + result = pow(2, Constants.classBbits - self.maskBits) + if (result > 0) { + return (Int(truncating: NSDecimalNumber(decimal: result))) + } + } + else if (classType == "C") { + result = pow(2, Constants.classCbits - self.maskBits) + if (result > 0) { + return (Int(truncating: NSDecimalNumber(decimal: result))) + } + } + return (1) + } + + func subnetRange() -> String { + var range = String() + var firstIP: UInt32 = 0 + var lastIP: UInt32 = 0 + + if (maskBits == 31 || maskBits == 32) { + firstIP = IPSubnetCalc.numerize(ipAddress: subnetId()) + lastIP = IPSubnetCalc.numerize(ipAddress: subnetBroadcast()) + } + else { + firstIP = IPSubnetCalc.numerize(ipAddress: subnetId()) + 1 + lastIP = IPSubnetCalc.numerize(ipAddress: subnetBroadcast()) - 1 + } + range = IPSubnetCalc.digitize(ipAddress: firstIP) + " - " + IPSubnetCalc.digitize(ipAddress: lastIP) + return (range) + } + + func subnetCIDRRange() -> String { + var range = String() + var firstIP: UInt32 = 0 + var lastIP: UInt32 = 0 + + firstIP = IPSubnetCalc.numerize(ipAddress: subnetId()) + lastIP = IPSubnetCalc.numerize(ipAddress: subnetBroadcast()) + range = IPSubnetCalc.digitize(ipAddress: firstIP) + " - " + IPSubnetCalc.digitize(ipAddress: lastIP) + return (range) + } + + static func netClass(ipAddress: String) -> String { + let ipNum = IPSubnetCalc.numerize(ipAddress: ipAddress) + let addr1stByte = (ipNum & Constants.maskClassA) >> 24 + + if (addr1stByte < 127) { + return ("A") + } + if (addr1stByte >= 127 && addr1stByte < 192) { + return ("B") + } + if (addr1stByte >= 192 && addr1stByte < 224) { + return ("C") + } + if (addr1stByte >= 224 && addr1stByte < 240) { + return ("D") + } + return ("E") + } + + func netClass() -> String { + return (IPSubnetCalc.netClass(ipAddress: ipv4Address)) + } + + func subnetBits() -> Int { + let classType = self.netClass() + var bits: Int = 0 + + if (classType == "A") { + if (self.maskBits > Constants.classAbits) { + bits = self.maskBits - Constants.classAbits + } + } + else if (classType == "B") { + if (self.maskBits > Constants.classBbits) { + bits = self.maskBits - Constants.classBbits + } + } + else if (classType == "C") { + if (self.maskBits > Constants.classCbits) { + bits = self.maskBits - Constants.classCbits + } + } + return (bits) + } + + func classBits() -> Int { + let classType = self.netClass() + + if (classType == "A") { + return (Constants.classAbits) + } + else if (classType == "B") { + return (Constants.classBbits) + } + else if (classType == "C") { + return (Constants.classCbits) + } + return (32) + } + + func classMask() -> UInt32 { + let classType = self.netClass() + + if (classType == "A") { + return (Constants.maskClassA) + } + else if (classType == "B") { + return (Constants.maskClassB) + } + else if (classType == "C") { + return (Constants.maskClassC) + } + else if (classType == "D") { + return (Constants.maskClassD) + } + else if (classType == "E") { + return (Constants.maskClassE) + } + return (Constants.maskClassE) + } + + static func maskBits(maskAddr: String) -> Int { + var bits: Int = 0 + + var mask:UInt32 = IPSubnetCalc.numerize(ipAddress: maskAddr) + while (mask != 0) { + bits += 1 + mask <<= 1 + } + //print("maskBits \(maskAddr) bits: \(bits)") + return (bits) + } + + static func maskBits(mask: UInt32) -> Int { + var bits: Int = 0 + var tmpmask = mask + + while (tmpmask != 0) { + bits += 1 + tmpmask <<= 1 + } + //print("maskBits \(mask) bits: \(bits)") + return (bits) + } + + func netBits() -> Int { + let classType = self.netClass() + var bits: Int = 0 + + if (classType == "A") { + if (self.maskBits > Constants.classAbits) { + bits = Constants.classAbits + } + else { + bits = self.maskBits + } + } + else if (classType == "B") { + if (self.maskBits > Constants.classBbits) { + bits = Constants.classBbits + } + else { + bits = self.maskBits + } + } + else if (classType == "C") { + if (self.maskBits > Constants.classCbits) { + bits = Constants.classCbits + } + else { + bits = self.maskBits + } + } + return (bits) + } + + func maxSubnets() -> Int { + var maxSubnets: Int = 0 + + let bits = subnetBits() + maxSubnets = Int(truncating: NSDecimalNumber(decimal: pow(2, bits))) + return (maxSubnets) + } + + func bitMap(dotted: Bool = true) -> String { + let netBits = self.netBits() + let subnetBits = self.subnetBits() + var bitMap = String() + + for index in 0...31 { + if (index < netBits) { + bitMap.append("n") + } + else if (index < (netBits + subnetBits)) { + bitMap.append("s") + } + else { + bitMap.append("h") + } + if ((index < 31) && ((index + 1) % 8 == 0)) { + if (dotted == true) { + bitMap.append(".") + } + } + } + return (bitMap) + } + + func displayIPInfo() { + print("IP Host : " + self.ipv4Address) + print("Mask bits : \(self.maskBits)") + print("Mask : " + self.subnetMask()) + print("Subnet bits : \(self.subnetBits())") + print("Subnet ID : " + self.subnetId()) + print("Broadcast : " + self.subnetBroadcast()) + print("Max Host : \(self.maxHosts())") + print("Max Subnet : \(self.maxSubnets())") + print("Subnet Range : " + self.subnetRange()) + print("IP Class Type : " + self.netClass()) + print("Hexa IP : " + self.hexaMap()) + print("Binary IP : " + self.binaryMap()) + print("BitMap : " + self.bitMap()) + print("CIDR Netmask : " + self.subnetMask()) + print("Wildcard Mask : " + self.wildcardMask()) + print("CIDR Max Subnet : \(self.maxCIDRSubnets())") + print("CIDR Max Hosts : \(self.maxHosts())") + print("CIDR Network (Route) : " + self.subnetId()) + print("CIDR Net Notation : " + self.subnetId() + "/" + String(self.maskBits)) + print("CIDR Address Range : " + self.subnetCIDRRange()) + print("IP number in binary : " + String(IPSubnetCalc.numerize(ipAddress: self.ipv4Address), radix: 2)) + print("Mask bin : " + String(IPSubnetCalc.numerize(maskbits: self.maskBits), radix: 2)) + //print("Subnet ID bin : " + String(self.subnetId(), radix: 2)) + //print("Broadcast bin : " + String(self.subnetBroadcast(), radix: 2)) + } + + //************* + //IPv6 SECTION + //************* + static func isValidIPv6(ipAddress: String, mask: Int?) -> Bool { + var ip4Hex: [String]? + var hex: UInt16? + + if mask != nil { + if (mask! < 1 || mask! > 128) { + print("mask \(mask!) invalid") + return false + } + } + else { + //print("null mask") + } + + ip4Hex = ipAddress.components(separatedBy: ":") + if (ip4Hex == nil) { + print("\(ipAddress) invalid") + return false + } + if (ip4Hex!.count != 8) { + print("no 8 hex") + if (ipAddress.contains("::")) + { + if (ipAddress.components(separatedBy: "::").count > 2) { + print("too many '::'") + return false + } + } + else { + print("IPv6 \(ipAddress) bad format") + return false + } + } + for index in 0...(ip4Hex!.count - 1) { + //print("Index : \(index) IPHex : \(ip4Hex[index]) Dec : \(String(UInt16(ip4Hex[index], radix: 16)!, radix: 16))") + if (ip4Hex![index].count > 4 && ip4Hex![index].count != 0) { + print("\(ip4Hex![index]) too large") + return false + } + hex = UInt16(ip4Hex![index], radix: 16) + if hex != nil { + if (hex! < 0 || hex! > 0xFFFF) { + print("\(hex!) is invalid") + return false + } + } + else { + if (ip4Hex![index] != "") { + print("\(ip4Hex![index]) not an integer") + return false + } + } + } + return true + } + + static func convertIPv4toIPv6(ipAddress: String, _6to4: Bool = false) -> String { + var ipv6str = String() + + let addr = numerize(ipAddress: ipAddress) + ipv6str.append(String((((Constants.addr32Digit1 | Constants.addr32Digit2) & addr) >> 16), radix: 16)) + ipv6str.append(":") + ipv6str.append(String(((Constants.addr32Digit3 | Constants.addr32Digit4) & addr), radix: 16)) + if (_6to4) + { + return ("2002:" + ipv6str + ":0:0:0:0:0") + } + return ("0:0:0:0:0:ffff:" + ipv6str) + } + + static func convertIPv6toIPv4(ipAddress: String) -> (String, String) { + var ipv4str = String() + //let ip4Hex = fullAddressIPv6(ipAddress: ipAddress).components(separatedBy: ":") + let ip4Hex = ipAddress.components(separatedBy: ":") + let index = ip4Hex.count + if (ip4Hex[0] == "2002") { + if (index > 2) { + if (ip4Hex[1] == "") { + ipv4str.append("0.0") + } + else { + ipv4str.append(String((UInt32(ip4Hex[1], radix: 16)! & Constants.addr32Digit3) >> 8)) + ipv4str.append("." + String((UInt32(ip4Hex[1], radix: 16)! & Constants.addr32Digit4))) + } + if (ip4Hex[2] == "") { + ipv4str.append(".0.0") + } + else { + ipv4str.append("." + String((UInt32(ip4Hex[2], radix: 16)! & Constants.addr32Digit3) >> 8)) + ipv4str.append("." + String((UInt32(ip4Hex[2], radix: 16)! & Constants.addr32Digit4))) + } + } + return (ipv4str, "6to4") + } + else { + if (index < 2) { + ipv4str.append("0.0") + } + else { + if (ip4Hex[index - 2] == "") { + ipv4str.append("0.0") + } + else { + ipv4str.append(String((UInt32(ip4Hex[index - 2], radix: 16)! & Constants.addr32Digit3) >> 8)) + ipv4str.append("." + String((UInt32(ip4Hex[index - 2], radix: 16)! & Constants.addr32Digit4))) + } + } + if (ip4Hex[index - 1] == "") { + ipv4str.append(".0.0") + } + else { + ipv4str.append("." + String((UInt32(ip4Hex[index - 1], radix: 16)! & Constants.addr32Digit3) >> 8)) + ipv4str.append("." + String((UInt32(ip4Hex[index - 1], radix: 16)! & Constants.addr32Digit4))) + } + return (ipv4str, "IPv4-Mapped") + } + } + + static func numerizeIPv6(ipAddress: String) -> [UInt16] { + var ipAddressNum: [UInt16] = Array(repeating: 0, count: 8) + var ip4Hex = [String]() + + ip4Hex = ipAddress.components(separatedBy: ":") + for index in 0...(ip4Hex.count - 1) { + if (ip4Hex[index] == "") { + ip4Hex[index] = "0" + } + ipAddressNum[index] = UInt16(ip4Hex[index], radix: 16)! + //print("Index: \(index) Ip4Hex: \(ip4Hex[index]) Hexa : \(UInt16(ip4Hex[index], radix: 16)!)") + } + return (ipAddressNum) + } + + static func binarizeIPv6(ipAddress: String, delimiter: Bool = false) -> String { + var ip4Hex: [String] + var binary: String + var binStr = String() + + ip4Hex = ipAddress.components(separatedBy: ":") + for index in 0...7 { + binary = String(UInt16(ip4Hex[index], radix: 16)!, radix: 2) + while (binary.count < 16) { + binary.insert("0", at: binary.startIndex) + } + binStr.append(binary) + if (delimiter && index < 7) { + binStr.append(":") + } + //print("Index: \(index) Ip4Hex: \(ip4Hex[index]) Bin : \(binary)") + } + return (binStr) + } + + static func numerizeMaskIPv6(maskbits: Int) -> [UInt16] { + var maskNum: [UInt16] = Array(repeating: 0, count: 8) + + for i in 0...7 { + //print("Index : \(i), mask bits : \(maskbits - (16 * (i + 1)) >= 0 ? 16 : (maskbits % (16 * i)) < maskbits ? (maskbits % (16 * i)) : 0) Div : \(maskbits / (16 * (i + 1))) Mod : \(maskbits % (16 * (i + 1)))") + if ((maskbits - (16 * i)) < 16) { + if ((maskbits - (16 * i)) > 0) { + maskNum[i] = UInt16(Constants.addr16Full & (Constants.addr16Full << (16 - (maskbits - (16 * i))))) + } + else { + //print("Index : \(i), ZERO mask : \(maskNum[i])") + } + } + else { + maskNum[i] = Constants.addr16Full + } + } + return (maskNum) + } + + static func hexarizeIPv6(num: [UInt16], full: Bool = true, column: Bool = false) -> String { + var hex: String + var hexStr = String() + + for index in 0...(num.count - 1) { + hex = String(num[index], radix: 16) + while (hex.count < 4 && full) { + hex.insert("0", at: hex.startIndex) + } + hexStr.append(hex) + if (column && index < (num.count - 1)) { + hexStr.append(":") + } + } + return (hexStr) + } + + func hexaIDIPv6() -> String { + var hexID: String = fullAddressIPv6(ipAddress: self.ipv6Address) + let delimiter: Set = [":"] + hexID.removeAll(where: { delimiter.contains($0) }) + return("0x\(hexID)") + } + + func binaryIDIPv6() -> String { + return (IPSubnetCalc.binarizeIPv6(ipAddress: self.ipv6Address)) + } + + func digitizeIPv6() -> String { + var digitStr = String() + let numIP = IPSubnetCalc.numerizeIPv6(ipAddress: self.ipv6Address) + + for index in 0...7 { + if (index != 7) { + digitStr.append("\(numIP[index]):") + } + else { + digitStr.append("\(numIP[index])") + } + } + return (digitStr) + } + + func fullAddressIPv6(ipAddress: String) -> String { + var fullAddr = String() + var ip4Hex = [String]() + var prevIsZero = false + + ip4Hex = ipAddress.components(separatedBy: ":") + for index in 0...(ip4Hex.count - 1) { + //print("Index : \(index) Hex : \(ip4Hex[index])") + if (ip4Hex[index] == "" && !prevIsZero) { + prevIsZero = true + //print("Index : \(index + 1) is empty, \(8 - ip4Hex.count + 1) hex quad are missing") + while (ip4Hex[index].count < (4 * (8 - ip4Hex.count + 1))) { + ip4Hex[index].insert("0", at: ip4Hex[index].startIndex) + } + } + else { + while (ip4Hex[index].count < 4) { + ip4Hex[index].insert("0", at: ip4Hex[index].startIndex) + } + } + fullAddr.append(ip4Hex[index]) + } + var offset = fullAddr.index(fullAddr.startIndex, offsetBy: 4) + for _ in 1...7 { + fullAddr.insert(":", at: offset) + offset = fullAddr.index(offset, offsetBy: 5) + } + return (fullAddr) + } + + func compactAddressIPv6(ipAddress: String) -> String { + var shortAddr = String() + var ip4Hex = [String]() + var prevIsZero = false + var prevAreZero = false + var prevCompactZero = false + var prevNonZero = false + + //print("IP Address: \(ipAddress)") + ip4Hex = self.fullAddressIPv6(ipAddress: ipAddress).components(separatedBy: ":") + for index in 0...(ip4Hex.count - 1) { + if (UInt16(ip4Hex[index], radix: 16)! == 0) { + if (!prevIsZero || prevCompactZero) { + if index == (ip4Hex.count - 1) { + shortAddr.append("0") + } + else { + shortAddr.append("0:") + } + } + else if (prevIsZero && !prevAreZero) { + shortAddr.removeLast(2) + prevAreZero = true + } + if (prevIsZero && index == (ip4Hex.count - 1)) { + if (shortAddr == "") { + shortAddr.append("::") + } + else { + shortAddr.append(":") + } + } + prevIsZero = true + } + else { + if (prevAreZero && !prevCompactZero) { + if (!prevNonZero) { + shortAddr.append("::") + } + else { + shortAddr.append(":") + } + prevCompactZero = true + } + shortAddr.append(String(UInt16(ip4Hex[index], radix: 16)!, radix: 16)) + if (index != (ip4Hex.count - 1)) { + shortAddr.append(":") + } + prevIsZero = false + prevAreZero = false + prevNonZero = true + } + //print("Index : \(index) IPHex : \(ip4Hex[index]) shortAddr: \(shortAddr)") + } + return (shortAddr) + } + + func networkIPv6() -> String { + var netID = [UInt16]() + let numMask = IPSubnetCalc.numerizeMaskIPv6(maskbits: self.ipv6MaskBits) + let numIP = IPSubnetCalc.numerizeIPv6(ipAddress: fullAddressIPv6(ipAddress: self.ipv6Address)) + + for index in 0...7 { + //print("Index: \(index) IP: \(numIP[index]) Mask : \(numMask[index]) Result : \(numIP[index] & (numMask[index])) ") + netID.append((numIP[index] & numMask[index])) + } + return (IPSubnetCalc.hexarizeIPv6(num: netID, full: false, column: true)) + } + + func networkRangeIPv6() -> String { + var netID = [UInt16]() + var netID2 = [UInt16]() + let numMask = IPSubnetCalc.numerizeMaskIPv6(maskbits: self.ipv6MaskBits) + let numIP = IPSubnetCalc.numerizeIPv6(ipAddress: self.ipv6Address) + + for index in 0...7 { + //print("Index: \(index) IP: \(numIP[index]) Mask : \(numMask[index]) Result : \(numIP[index] & (numMask[index])) ") + netID.append((numIP[index] & numMask[index])) + } + for index in 0...7 { + //print("Index: \(index) IP: \(numIP[index]) Mask : \(numMask[index]) Result : \(numIP[index] & (numMask[index])) ") + netID2.append((numIP[index] | ~numMask[index])) + } + var netIDStr = IPSubnetCalc.hexarizeIPv6(num: netID, full: true, column: true) + netIDStr.append(" - \(IPSubnetCalc.hexarizeIPv6(num: netID2, full: true, column: true))") + return (netIDStr) + } + + func totalIPAddrIPv6() -> Decimal { + var total = Decimal() + var number: Decimal = 2 + + NSDecimalPower(&total, &number , (128 - self.ipv6MaskBits), NSDecimalNumber.RoundingMode.plain) + return (total) + } + + func dottedDecimalIPv6() -> String { + var ipv4str = String() + + let ip4Hex = fullAddressIPv6(ipAddress: self.ipv6Address).components(separatedBy: ":") + for index in (0...(ip4Hex.count - 1)) { + if (index != 0) { + ipv4str.append(".") + + } + if (ip4Hex[index] == "") { + ipv4str.append("0.0") + } + else { + ipv4str.append(String((UInt32(ip4Hex[index], radix: 16)! & Constants.addr32Digit3) >> 8)) + ipv4str.append("." + String((UInt32(ip4Hex[index], radix: 16)! & Constants.addr32Digit4))) + } + } + return ipv4str + } + + func ip6ARPA () -> String { + var ipARPA = fullAddressIPv6(ipAddress: self.ipv6Address) + let delimiter: Set = [":"] + + ipARPA.removeAll(where: { delimiter.contains($0) }) + ipARPA = String(ipARPA.reversed()) + + var offset = ipARPA.index(ipARPA.startIndex, offsetBy: 1) + for _ in 0...(ipARPA.count - 2) { + ipARPA.insert(".", at: offset) + offset = ipARPA.index(offset, offsetBy: 2) + } + ipARPA.append(".ip6.arpa") + return (ipARPA) + } + + func resBlockIPv6() -> String? { + var netID = networkIPv6() + + netID = fullAddressIPv6(ipAddress: netID) + //print("NetID BEFORE compact : \(netID)") + netID = compactAddressIPv6(ipAddress: netID) + //print("NetID AFTER compact : \(netID)") + netID.append("/\(self.ipv6MaskBits)") + + for item in Constants.resIPv6Blocks { + if (item.key == netID) { + return (item.value + " (\(item.key))") + } + } + return nil + } + + init?(ipAddress: String, maskbits: Int) { + if (IPSubnetCalc.isValidIP(ipAddress: ipAddress, mask: String(maskbits), classless: true)) { + self.ipv4Address = ipAddress + self.maskBits = maskbits + self.ipv6Address = IPSubnetCalc.convertIPv4toIPv6(ipAddress: ipAddress) + self.ipv6MaskBits = maskbits + Constants.defaultIPv6to4Mask + } + else { + return nil + } + } + + convenience init?(_ ipAddress: String) { + var classbit: Int + + if (IPSubnetCalc.isValidIP(ipAddress: ipAddress, mask: nil)) { + switch (IPSubnetCalc.netClass(ipAddress: ipAddress)) { + case "A": + classbit = Constants.classAbits + case "B": + classbit = Constants.classBbits + case "C": + classbit = Constants.classCbits + default: + classbit = Constants.classAbits + } + self.init(ipAddress: ipAddress, maskbits: classbit) + } + else { + return nil + } + } + + init?(ipv6: String, maskbits: Int) { + if (IPSubnetCalc.isValidIPv6(ipAddress: ipv6, mask: maskbits)) { + (self.ipv4Address, _) = IPSubnetCalc.convertIPv6toIPv4(ipAddress: ipv6) + if (maskbits >= (Constants.defaultIPv6to4Mask + Constants.classAbits)) { + self.maskBits = maskbits - Constants.defaultIPv6to4Mask + } + else { + self.maskBits = Constants.classAbits + } + + // full ? compact ? validated ? + self.ipv6Address = ipv6 + self.ipv6MaskBits = maskbits + //print("init IPv6 ipv6 addr: \(self.ipv6Address) ipv4 addr: \(self.ipv4Address)") + } + else { + return nil + } + } +} diff --git a/README.md b/README.md index 16833e1..afa0f02 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ # SubnetCalc -Subnet Calculator for MacOS +Subnet Calculator for MacOS + +What's New in version 2.0: +- IPv6 support! +- Address Class D (Multicast) and Class E (Reserved) support +- 31 and 32 mask bits support +- New Tab presentation +- Recoded in Swift +- Add alerts for bad IP or mask format +- Fix bugs -What's New in version 1.6: -- Dark Mode support -- Selectable cells for copy -- New App icon -- Universal binary (Apple Silicon support) For more information: http://subnetcalc.mulot.org diff --git a/SubnetCalc-Info.plist b/SubnetCalc-Info.plist index 93b4c6a..27f8f5a 100644 --- a/SubnetCalc-Info.plist +++ b/SubnetCalc-Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.6 + 2.0 CFBundleSignature JMUL CFBundleVersion - 3 + 4 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/SubnetCalc.xcodeproj/project.pbxproj b/SubnetCalc.xcodeproj/project.pbxproj index 0a5376e..19c1567 100644 --- a/SubnetCalc.xcodeproj/project.pbxproj +++ b/SubnetCalc.xcodeproj/project.pbxproj @@ -8,14 +8,13 @@ /* Begin PBXBuildFile section */ 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; }; - 256AC3DA0F4B6AC300CF3369 /* SubnetCalcAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* SubnetCalcAppDelegate.m */; }; 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; - 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; - 945E62F825658DBF00CDC9C7 /* SubnetCalcUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 945E62F725658DBF00CDC9C7 /* SubnetCalcUITests.m */; }; + 9482A32725765B30008D2C56 /* SubnetCalcUITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9482A32625765B30008D2C56 /* SubnetCalcUITest.swift */; }; 949420B812D3C62A00E2F57D /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 949420B712D3C62A00E2F57D /* License.txt */; }; - 949420BD12D3C64500E2F57D /* IPSubnetCalc.m in Sources */ = {isa = PBXBuildFile; fileRef = 949420BA12D3C64500E2F57D /* IPSubnetCalc.m */; }; 9494DD211F7BEAE80032DB19 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9494DD201F7BEAE80032DB19 /* Images.xcassets */; }; + 94AC2613256AF7C900811156 /* SubnetCalcAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94AC2612256AF7C900811156 /* SubnetCalcAppDelegate.swift */; }; + 94B1C507256ABC1B00F992A3 /* IPSubnetcalc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B1C506256ABC1B00F992A3 /* IPSubnetcalc.swift */; }; 94B6031212F74DC7005AA5EB /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94B6031112F74DC7005AA5EB /* CoreFoundation.framework */; }; /* End PBXBuildFile section */ @@ -32,23 +31,19 @@ /* Begin PBXFileReference section */ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; - 256AC3D80F4B6AC300CF3369 /* SubnetCalcAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubnetCalcAppDelegate.h; sourceTree = ""; }; - 256AC3D90F4B6AC300CF3369 /* SubnetCalcAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SubnetCalcAppDelegate.m; sourceTree = ""; }; - 256AC3F00F4B6AF500CF3369 /* SubnetCalc_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubnetCalc_Prefix.pch; sourceTree = ""; }; - 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 8D1107310486CEB800E47090 /* SubnetCalc-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SubnetCalc-Info.plist"; sourceTree = ""; }; 8D1107320486CEB800E47090 /* SubnetCalc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SubnetCalc.app; sourceTree = BUILT_PRODUCTS_DIR; }; 945E62EF25658A9500CDC9C7 /* SubnetCalc.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = SubnetCalc.xctestplan; sourceTree = ""; }; - 945E62F525658DBF00CDC9C7 /* SubnetCalcUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SubnetCalcUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 945E62F725658DBF00CDC9C7 /* SubnetCalcUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SubnetCalcUITests.m; sourceTree = ""; }; + 945E62F525658DBF00CDC9C7 /* SubnetCalcUITests-Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SubnetCalcUITests-Runner.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 945E62F925658DBF00CDC9C7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9482A32625765B30008D2C56 /* SubnetCalcUITest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubnetCalcUITest.swift; sourceTree = ""; }; 949420B712D3C62A00E2F57D /* License.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = License.txt; sourceTree = ""; }; - 949420B912D3C64500E2F57D /* IPSubnetCalc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IPSubnetCalc.h; sourceTree = ""; }; - 949420BA12D3C64500E2F57D /* IPSubnetCalc.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = IPSubnetCalc.m; sourceTree = ""; }; 9494DD1F1F7BE7B40032DB19 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 9494DD201F7BEAE80032DB19 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = SubnetCalc/Images.xcassets; sourceTree = ""; }; + 94AC2612256AF7C900811156 /* SubnetCalcAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubnetCalcAppDelegate.swift; sourceTree = ""; }; + 94B1C506256ABC1B00F992A3 /* IPSubnetcalc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPSubnetcalc.swift; sourceTree = ""; }; 94B6031112F74DC7005AA5EB /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 94CDB5F6255EE11D0010F1E4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 94D8C5731520F99500B27A3A /* SubnetCalc.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = SubnetCalc.entitlements; sourceTree = ""; }; @@ -77,10 +72,8 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( - 949420B912D3C64500E2F57D /* IPSubnetCalc.h */, - 949420BA12D3C64500E2F57D /* IPSubnetCalc.m */, - 256AC3D80F4B6AC300CF3369 /* SubnetCalcAppDelegate.h */, - 256AC3D90F4B6AC300CF3369 /* SubnetCalcAppDelegate.m */, + 94B1C506256ABC1B00F992A3 /* IPSubnetcalc.swift */, + 94AC2612256AF7C900811156 /* SubnetCalcAppDelegate.swift */, ); name = Classes; sourceTree = ""; @@ -108,7 +101,7 @@ isa = PBXGroup; children = ( 8D1107320486CEB800E47090 /* SubnetCalc.app */, - 945E62F525658DBF00CDC9C7 /* SubnetCalcUITests.xctest */, + 945E62F525658DBF00CDC9C7 /* SubnetCalcUITests-Runner.app */, ); name = Products; sourceTree = ""; @@ -130,8 +123,6 @@ 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( - 256AC3F00F4B6AF500CF3369 /* SubnetCalc_Prefix.pch */, - 29B97316FDCFA39411CA2CEA /* main.m */, ); name = "Other Sources"; sourceTree = ""; @@ -144,7 +135,6 @@ 8D1107310486CEB800E47090 /* SubnetCalc-Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, 1DDD58140DA1D0A300B32029 /* MainMenu.xib */, - 945E62EF25658A9500CDC9C7 /* SubnetCalc.xctestplan */, ); name = Resources; sourceTree = ""; @@ -161,7 +151,8 @@ 945E62F625658DBF00CDC9C7 /* SubnetCalcUITests */ = { isa = PBXGroup; children = ( - 945E62F725658DBF00CDC9C7 /* SubnetCalcUITests.m */, + 945E62EF25658A9500CDC9C7 /* SubnetCalc.xctestplan */, + 9482A32625765B30008D2C56 /* SubnetCalcUITest.swift */, 945E62F925658DBF00CDC9C7 /* Info.plist */, ); path = SubnetCalcUITests; @@ -203,7 +194,7 @@ ); name = SubnetCalcUITests; productName = SubnetCalcUITests; - productReference = 945E62F525658DBF00CDC9C7 /* SubnetCalcUITests.xctest */; + productReference = 945E62F525658DBF00CDC9C7 /* SubnetCalcUITests-Runner.app */; productType = "com.apple.product-type.bundle.ui-testing"; }; /* End PBXNativeTarget section */ @@ -212,10 +203,10 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1220; + LastUpgradeCheck = 1230; TargetAttributes = { 8D1107260486CEB800E47090 = { - LastSwiftMigration = 0820; + LastSwiftMigration = 1220; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Sandbox = { @@ -225,6 +216,7 @@ }; 945E62F425658DBF00CDC9C7 = { CreatedOnToolsVersion = 12.2; + LastSwiftMigration = 1220; ProvisioningStyle = Automatic; TestTargetID = 8D1107260486CEB800E47090; }; @@ -274,9 +266,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8D11072D0486CEB800E47090 /* main.m in Sources */, - 256AC3DA0F4B6AC300CF3369 /* SubnetCalcAppDelegate.m in Sources */, - 949420BD12D3C64500E2F57D /* IPSubnetCalc.m in Sources */, + 94B1C507256ABC1B00F992A3 /* IPSubnetcalc.swift in Sources */, + 94AC2613256AF7C900811156 /* SubnetCalcAppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -284,7 +275,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 945E62F825658DBF00CDC9C7 /* SubnetCalcUITests.m in Sources */, + 9482A32725765B30008D2C56 /* SubnetCalcUITest.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -321,6 +312,7 @@ 945E62FD25658DBF00CDC9C7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -355,6 +347,8 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = mulot.org.SubnetCalcUITests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TEST_TARGET_NAME = SubnetCalc; }; name = Debug; @@ -362,6 +356,7 @@ 945E62FE25658DBF00CDC9C7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -391,6 +386,7 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = mulot.org.SubnetCalcUITests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TEST_TARGET_NAME = SubnetCalc; }; name = Release; @@ -400,6 +396,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = SubnetCalc.entitlements; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; @@ -410,13 +407,15 @@ GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = SubnetCalc_Prefix.pch; INFOPLIST_FILE = "SubnetCalc-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = net.mulot.subnetcalc; PRODUCT_NAME = SubnetCalc; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 3.0; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -425,6 +424,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = SubnetCalc.entitlements; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; @@ -433,13 +433,14 @@ ENABLE_HARDENED_RUNTIME = YES; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_PREFIX_HEADER = SubnetCalc_Prefix.pch; INFOPLIST_FILE = "SubnetCalc-Info.plist"; INSTALL_PATH = /Applications; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = net.mulot.subnetcalc; PRODUCT_NAME = SubnetCalc; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 3.0; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -533,6 +534,7 @@ PROVISIONING_PROFILE = ""; SDKROOT = macosx; STRIP_INSTALLED_PRODUCT = YES; + SWIFT_COMPILATION_MODE = wholemodule; }; name = Release; }; diff --git a/SubnetCalc.xcodeproj/xcshareddata/xcschemes/SubnetCalc.xcscheme b/SubnetCalc.xcodeproj/xcshareddata/xcschemes/SubnetCalc.xcscheme index 2d3571f..978c4c8 100644 --- a/SubnetCalc.xcodeproj/xcshareddata/xcschemes/SubnetCalc.xcscheme +++ b/SubnetCalc.xcodeproj/xcshareddata/xcschemes/SubnetCalc.xcscheme @@ -1,6 +1,6 @@ diff --git a/SubnetCalcAppDelegate.h b/SubnetCalcAppDelegate.h deleted file mode 100644 index 4afb7b1..0000000 --- a/SubnetCalcAppDelegate.h +++ /dev/null @@ -1,87 +0,0 @@ -// -// SubnetCalcAppDelegate.h -// SubnetCalc -// -// Created by Julien Mulot on 04/01/11. -// Copyright 2011 mulot.net. All rights reserved. -// - -#import "IPSubnetCalc.h" -#import - -@interface SubnetCalcAppDelegate : NSObject { - IBOutlet NSTextField *addrField; - IBOutlet NSTextField *classBinaryMap; - IBOutlet NSTextField *classBitMap; - IBOutlet NSTextField *classHexaMap; - IBOutlet NSPopUpButton *exportButton; - IBOutlet NSPopUpButton *classType; - IBOutlet NSComboBox *maskBitsCombo; - IBOutlet NSComboBox *maxHostsBySubnetCombo; - IBOutlet NSComboBox *maxSubnetsCombo; - IBOutlet NSComboBox *subnetBitsCombo; - IBOutlet NSTextField *subnetBroadcast; - IBOutlet NSTextField *subnetHostAddrRange; - IBOutlet NSTextField *subnetId; - IBOutlet NSComboBox *subnetMaskCombo; - IBOutlet NSTableView *subnetsHostsView; - IBOutlet NSComboBox *supernetMaskBitsCombo; - IBOutlet NSComboBox *supernetMaskCombo; - IBOutlet NSComboBox *supernetMaxCombo; - IBOutlet NSComboBox *supernetMaxAddr; - IBOutlet NSComboBox *supernetMaxSubnetsCombo; - IBOutlet NSTextField *supernetRoute; - IBOutlet NSTextField *supernetAddrRange; - IBOutlet NSTabView *tabView; - IBOutlet NSSlider *subnetBitsSlide; - IBOutlet NSTextField *bitsOnSlide; - IBOutlet NSButton *tabViewClassLess; - IBOutlet NSButton *wildcard; - //IBOutlet NSView *mainWindow; - //IBOutlet NSWindow *window; - IBOutlet NSMenuItem *darkModeMenu; - IBOutlet NSApplication *NSApp; -} - -@property (assign) IBOutlet NSWindow *window; - -- (void)doIPSubnetCalc:(unsigned int)mask; -- (void)doSupernetCalc:(int)maskBits; -- (void)initClassInfos:(NSString *)c; -- (void)initCIDR; -- (int)checkAddr:(NSString *)address; -- (void)bitsOnSlidePos; -- (NSString *)URLEncode:(NSString *)url; -- (IBAction)calc:(id)sender; -- (IBAction)ipAddrEdit:(id)sender; -- (IBAction)changeAddrClassType:(id)sender; -- (IBAction)changeMaskBits:(id)sender; -- (IBAction)changeMaxHosts:(id)sender; -- (IBAction)changeMaxSubnets:(id)sender; -- (IBAction)changeSubnetBits:(id)sender; -- (IBAction)changeSubnetMask:(id)sender; -- (IBAction)changeSupernetMaskBits:(id)sender; -- (IBAction)changeSupernetMask:(id)sender; -- (IBAction)changeSupernetMax:(id)sender; -- (IBAction)changeSupernetMaxAddr:(id)sender; -- (IBAction)changeSupernetMaxSubnets:(id)sender; -- (IBAction)subnetBitsSlide:(id)sender; -- (IBAction)changeTableViewClass:(id)sender; -- (IBAction)changeWildcard:(id)sender; -- (IBAction)exportCSV:(id)sender; -- (void)printAllSubnets; -- (void)darkMode:(id)sender; -- (int)numberOfRowsInTableView:(NSTableView *)aTableView; -- (id)tableView:(NSTableView *)aTableView -objectValueForTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex; -- (void)tableView:(NSTableView *)aTableView - setObjectValue:(id)anObject - forTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex; - -@end - -IPSubnetCalc *ipsc; -NSArray *tab_tabView; - diff --git a/SubnetCalcAppDelegate.m b/SubnetCalcAppDelegate.m deleted file mode 100644 index bf1861e..0000000 --- a/SubnetCalcAppDelegate.m +++ /dev/null @@ -1,713 +0,0 @@ -// -// SubnetCalcAppDelegate.m -// SubnetCalc -// -// Created by Julien Mulot on 04/01/11. -// Copyright 2011 mulot.net. All rights reserved. -// - -#import "SubnetCalcAppDelegate.h" -#import -#import -#import -#import - -#define BUFFER_LINES 1000 -#define NETWORK_BITS_MIN_CLASSLESS 1 -#define NETWORK_BITS_MIN 8 -#define NETWORK_BITS_MAX 32 - -@implementation SubnetCalcAppDelegate - -@synthesize window; - -- (int)checkAddr:(NSString *)address -{ - NSRange range; - - if (address) - { - range = [address rangeOfString:@"/"]; - if (range.location != NSNotFound) - { - if (([[address substringFromIndex: range.location + 1] intValue] > NETWORK_BITS_MAX) - || ([[address substringFromIndex: range.location + 1] intValue] < NETWORK_BITS_MIN)) - return (-1); - if ([IPSubnetCalc numberize: [[address substringToIndex: range.location] cStringUsingEncoding: NSASCIIStringEncoding]] == -1) - return (-1); - [tabView selectTabViewItemAtIndex: 1]; - } - else if ([IPSubnetCalc numberize: [address cStringUsingEncoding: NSASCIIStringEncoding]] == -1) - return (-1); - } - else - { - return (-2); - } - return (0); -} - -- (void)initClassInfos:(NSString *)c -{ - if ([c isEqualToString: @"A"]) - { - [classType selectItemAtIndex: 0]; - } - else if ([c isEqualToString: @"B"]) - { - [classType selectItemAtIndex: 1]; - } - else if ([c isEqualToString: @"C"]) - { - [classType selectItemAtIndex: 2]; - } - else if ([c isEqualToString: @"D"]) - { - [classType selectItemAtIndex: 3]; - tab_tabView = [tabView tabViewItems]; - [tabView removeTabViewItem: [tab_tabView objectAtIndex: 1]]; - [tabView removeTabViewItem: [tab_tabView objectAtIndex: 2]]; - [tabView removeTabViewItem: [tab_tabView objectAtIndex: 3]]; - } -} - -- (void)initCIDR -{ - unsigned int tmp_mask; - unsigned int addr_nl; - int i; - - for (i = 1; i <= 30; i++) - [supernetMaskBitsCombo addItemWithObjectValue: [NSString stringWithFormat: @"%d", i]]; - tmp_mask = -1; - for (i = 31; i > 1; i--) - { - //addr_nl = htonl(tmp_mask << i); - addr_nl = (tmp_mask << i); - [supernetMaskCombo addItemWithObjectValue: [IPSubnetCalc denumberize: addr_nl]]; - } - for (i = 0; i < 30; i++) - { - tmp_mask = pow(2, i); - [supernetMaxCombo addItemWithObjectValue: [NSString stringWithFormat: @"%u", tmp_mask]]; - } - for (i = 1; i < 32; i++) - { - tmp_mask = pow(2, i) - 2; - [supernetMaxAddr addItemWithObjectValue: [NSString stringWithFormat: @"%u", tmp_mask]]; - } - for (i = 0; i < 32; i++) - { - tmp_mask = (pow(2, i)); - [supernetMaxSubnetsCombo addItemWithObjectValue: [NSString stringWithFormat: @"%u", tmp_mask]]; - } - /* - [supernetMaxCombo selectItemAtIndex: 7]; - [supernetMaxAddr selectItemAtIndex: 23]; - [supernetMaskBitsCombo selectItemAtIndex: 7]; - [supernetMaskCombo selectItemAtIndex: 7]; - [supernetMaxSubnetsCombo selectItemAtIndex: 24]; - */ -} - -- (void)doIPSubnetCalc:(unsigned int)mask -{ - NSRange range; - NSMutableAttributedString *astr; - - if([[addrField stringValue] length] == 0) - [addrField setStringValue: NSLocalizedString(@"10.0.0.0", nil)]; - if ([self checkAddr: [addrField stringValue]]) - { - NSAlert *alert = [[NSAlert alloc] init]; - [alert addButtonWithTitle: @"OK"]; - [alert setMessageText: @"Bad IP Address"]; - [alert setAlertStyle: NSAlertStyleWarning]; - [alert setInformativeText:@"Bad format"]; - if ([alert runModal] == NSAlertFirstButtonReturn) - return; - } - if ([tabView numberOfTabViewItems] != 4) - { - [tabView addTabViewItem: [tab_tabView objectAtIndex:1]]; - [tabView addTabViewItem: [tab_tabView objectAtIndex:2]]; - [tabView addTabViewItem: [tab_tabView objectAtIndex:3]]; - } - /* - [supernetMaskBitsCombo removeAllItems]; - [supernetMaskCombo removeAllItems]; - [supernetMaxAddr removeAllItems]; - [supernetMaxCombo removeAllItems]; - [supernetMaxSubnetsCombo removeAllItems]; - */ - ipsc = [[IPSubnetCalc alloc] init]; - if (ipsc) - { - if ([tabViewClassLess state] == NSOnState) - { - [ipsc setClassless: YES]; - } - else - { - [ipsc setClassless: NO]; - } - range = [[addrField stringValue] rangeOfString:@"/"]; - if (range.location != NSNotFound) - { - mask = -1; - mask <<= (32 - [[[addrField stringValue] substringFromIndex: range.location + 1] intValue]); - [addrField setStringValue: [[addrField stringValue] substringToIndex: range.location]]; - } - if (mask) - [ipsc initAddressAndMask: [[addrField stringValue] cStringUsingEncoding: NSASCIIStringEncoding] mask: mask]; - else - [ipsc initAddress: [[addrField stringValue] cStringUsingEncoding: NSASCIIStringEncoding]]; - [self initClassInfos: [ipsc networkClass]]; - [supernetRoute setStringValue: [ipsc supernetRoute: [[supernetMaskBitsCombo objectValueOfSelectedItem] intValue]]]; - [supernetAddrRange setStringValue: [ipsc supernetAddrRange: [[supernetMaskBitsCombo objectValueOfSelectedItem] intValue]]]; - astr = [[NSMutableAttributedString alloc] initWithString : [ipsc bitMap]]; - /* - if ([[ipsc maskBits] intValue] >= 24) - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 27)]; - else if ([[ipsc maskBits] intValue] >= 16) - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 18)]; - else - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 9)]; - */ - [classBitMap setAttributedStringValue: astr]; - [classBinaryMap setStringValue: [ipsc binMap]]; - [classHexaMap setStringValue: [ipsc hexMap]]; - [subnetBitsCombo selectItemWithObjectValue: [[ipsc subnetBits] stringValue]]; - [maskBitsCombo selectItemWithObjectValue: [[ipsc maskBits] stringValue]]; - [maxSubnetsCombo selectItemWithObjectValue: [[ipsc subnetMax] stringValue]]; - [maxHostsBySubnetCombo selectItemWithObjectValue: [[ipsc hostMax] stringValue]]; - if ([wildcard state] == NSOnState) - { - [subnetMaskCombo selectItemWithObjectValue: [IPSubnetCalc denumberize: ~([ipsc subnetMaskIntValue])]]; - } - else - { - [subnetMaskCombo selectItemWithObjectValue: [ipsc subnetMask]]; - } - [subnetId setStringValue: [ipsc subnetId]]; - [subnetHostAddrRange setStringValue: [ipsc subnetHostAddrRange]]; - [subnetBroadcast setStringValue: [ipsc subnetBroadcast]]; - [bitsOnSlide setStringValue: [[ipsc maskBits] stringValue]]; - [subnetBitsSlide setFloatValue: [[ipsc maskBits] floatValue]]; - [self doSupernetCalc: [ipsc maskBitsIntValue]]; - [self bitsOnSlidePos]; - [subnetsHostsView reloadData]; - } -} - - -- (IBAction)calc:(id)sender -{ - if (ipsc) - { - [self doIPSubnetCalc:[ipsc subnetMaskIntValue]]; - } - else - { - [self doIPSubnetCalc:0]; - } -} - -- (IBAction)ipAddrEdit:(id)sender -{ - [self calc:nil]; -} - -- (IBAction)changeAddrClassType:(id)sender -{ - NSMutableAttributedString *astr; - - if ([tabView numberOfTabViewItems] != 4) - { - [tabView addTabViewItem: [tab_tabView objectAtIndex:1]]; - [tabView addTabViewItem: [tab_tabView objectAtIndex:2]]; - [tabView addTabViewItem: [tab_tabView objectAtIndex:3]]; - } - if ([sender indexOfSelectedItem] == 0) - { - astr = [[NSMutableAttributedString alloc] initWithString : NSLocalizedString(@"nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh", nil)]; - /* - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 9)]; - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(9, 26)]; - */ - [classBitMap setAttributedStringValue: astr]; - [classBinaryMap setStringValue: NSLocalizedString(@"00000001000000000000000000000000", nil)]; - } - else if ([sender indexOfSelectedItem] == 1) - { - astr = [[NSMutableAttributedString alloc] initWithString : NSLocalizedString(@"nnnnnnnn.nnnnnnnn.hhhhhhhh.hhhhhhhh", nil)]; - /* - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 18)]; - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(18, 17)]; - */ - [classBitMap setAttributedStringValue: astr]; - [classBinaryMap setStringValue: NSLocalizedString(@"10000000000000000000000000000000", nil)]; - } - else if ([sender indexOfSelectedItem] == 2) - { - astr = [[NSMutableAttributedString alloc] initWithString : NSLocalizedString(@"nnnnnnnn.nnnnnnnn.nnnnnnnn.hhhhhhhh", nil)]; - /* - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 27)]; - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(27, 8)]; - */ - [classBitMap setAttributedStringValue: astr]; - [classBinaryMap setStringValue: NSLocalizedString(@"11000000000000000000000000000000", nil)]; - } - else if ([sender indexOfSelectedItem] == 3) - { - tab_tabView = [tabView tabViewItems]; - [tabView removeTabViewItem: [tab_tabView objectAtIndex: 1]]; - [tabView removeTabViewItem: [tab_tabView objectAtIndex: 2]]; - [tabView removeTabViewItem: [tab_tabView objectAtIndex: 3]]; - } -} - -- (IBAction)changeMaxHosts:(id)sender -{ - unsigned int mask = -1; - - [self doIPSubnetCalc:(mask << (2 + [sender indexOfSelectedItem]))]; -} - -- (IBAction)changeMaxSubnets:(id)sender -{ - unsigned int mask = -1; - - if (ipsc) - [self doIPSubnetCalc: (mask << (32 - ([sender indexOfSelectedItem] + [ipsc netBits])))]; - else - [self doIPSubnetCalc: (mask << (32 - ([sender indexOfSelectedItem] + 8)))]; -} - -- (IBAction)changeSubnetBits:(id)sender -{ - unsigned int mask = -1; - - if (ipsc) - [self doIPSubnetCalc: (mask << (32 - ([[sender objectValueOfSelectedItem] intValue] + [ipsc netBits])))]; - else - [self doIPSubnetCalc: (mask << (32 - ([[sender objectValueOfSelectedItem] intValue] + 8)))]; -} - -- (IBAction)changeSubnetMask:(id)sender -{ - unsigned int sin_addr; - - if ((inet_pton(AF_INET, [[sender objectValueOfSelectedItem] cStringUsingEncoding: NSASCIIStringEncoding]?:"0", &sin_addr )) <= 0) - { - NSAlert *alert = [[NSAlert alloc] init]; - [alert addButtonWithTitle: @"OK"]; - [alert setMessageText: @"Bad Subnet Mask"]; - [alert setAlertStyle: NSAlertStyleWarning]; - [alert setInformativeText:@"Bad format"]; - if ([alert runModal] == NSAlertFirstButtonReturn) - { - if (ipsc) - { - if ([wildcard state] == NSOnState) - { - [subnetMaskCombo selectItemWithObjectValue: [IPSubnetCalc denumberize: ~([ipsc subnetMaskIntValue])]]; - } - else - { - [subnetMaskCombo selectItemWithObjectValue: [ipsc subnetMask]]; - } - } - } - } - else { - if ([wildcard state] == NSOnState) - { - sin_addr = ~sin_addr; - [self doIPSubnetCalc: ntohl(sin_addr)]; - } - else - { - [self doIPSubnetCalc: ntohl(sin_addr)]; - } - } -} - -- (IBAction)changeMaskBits:(id)sender -{ - unsigned int mask = -1; - - [self doIPSubnetCalc:(mask << (32 - [[sender objectValueOfSelectedItem] intValue]))]; -} - -- (void)doSupernetCalc:(int)maskBits -{ - unsigned int mask = -1; - unsigned int result = 0; - - if (maskBits >=0 && maskBits <= 32 && ipsc) - { - [supernetMaskBitsCombo selectItemWithObjectValue: [NSString stringWithFormat: @"%d", maskBits]]; - //[supernetMaskCombo selectItemWithObjectValue: [IPSubnetCalc denumberize: (mask << ((8 - maskBits)) & 0x000000FF)]]; - [supernetMaskCombo selectItemWithObjectValue: [IPSubnetCalc denumberize: (mask << (32 - maskBits))]]; - if ([[ipsc networkClass] isEqualToString: @"A"]) - result = pow(2, 8 - maskBits); - else if ([[ipsc networkClass] isEqualToString: @"B"]) - result = pow(2, 16 - maskBits); - else if ([[ipsc networkClass] isEqualToString: @"C"]) - result = pow(2, 24 - maskBits); - if (result > 0) - [supernetMaxCombo selectItemWithObjectValue: [NSString stringWithFormat: @"%u", result]]; - else - [supernetMaxCombo selectItemWithObjectValue: @"1"]; - result = pow(2, 32 - maskBits) - 2; - [supernetMaxAddr selectItemWithObjectValue: [NSString stringWithFormat: @"%u", result]]; - [supernetRoute setStringValue: [ipsc supernetRoute: maskBits]]; - [supernetAddrRange setStringValue: [ipsc supernetAddrRange: maskBits]]; - result = pow(2, 32 - maskBits); - [supernetMaxSubnetsCombo selectItemWithObjectValue: [NSString stringWithFormat: @"%u", result]]; - } -} - -- (IBAction)changeSupernetMaskBits:(id)sender -{ - [self doSupernetCalc: [[sender objectValueOfSelectedItem] intValue]]; -} - -- (IBAction)changeSupernetMask:(id)sender -{ - unsigned int mask; - - mask = [IPSubnetCalc numberize: [[sender objectValueOfSelectedItem] cStringUsingEncoding: NSASCIIStringEncoding]]; - [self doSupernetCalc: [IPSubnetCalc countOnBits: mask]]; -} - -- (IBAction)changeSupernetMax:(id)sender -{ - if (ipsc) - { - if ([[ipsc networkClass] isEqualToString: @"A"]) - [self doSupernetCalc: 8 - (int)[sender indexOfSelectedItem]]; - else if ([[ipsc networkClass] isEqualToString: @"B"]) - [self doSupernetCalc: 16 - (int)[sender indexOfSelectedItem]]; - else if ([[ipsc networkClass] isEqualToString: @"C"]) - [self doSupernetCalc: 24 - (int)[sender indexOfSelectedItem]]; - } -} - -- (IBAction)changeSupernetMaxAddr:(id)sender -{ - [self changeSupernetMax: sender]; -} - -- (IBAction)changeSupernetMaxSubnets:(id)sender -{ - [self doSupernetCalc: (32 - (int)[sender indexOfSelectedItem])]; -} - -- (int)numberOfRowsInTableView:(NSTableView *)aTableView -{ - if (ipsc) - { - if ([ipsc classless] == YES) - return (pow(2, ([[ipsc maskBits] intValue] - NETWORK_BITS_MIN_CLASSLESS))); - else - return ([[ipsc subnetMax] intValue]); - } - return 0; -} - -//Display all subnets info in the TableView Subnet/Hosts -- (id)tableView:(NSTableView *)aTableView -objectValueForTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex -{ - IPSubnetCalc *ipsc_tmp; - unsigned int mask; - - ipsc_tmp = [[IPSubnetCalc alloc] init]; - if (ipsc_tmp && ipsc) - { - mask = rowIndex; - mask <<= (32 - [ipsc maskBitsIntValue]); - [ipsc_tmp initAddressAndMaskWithUnsignedInt:([ipsc netIdIntValue] | mask) mask: [ipsc subnetMaskIntValue]]; - if ([[aTableColumn identifier] isEqualToString: @"numCol"]) - return ([NSNumber numberWithInt: rowIndex + 1]); - else if ([[aTableColumn identifier] isEqualToString: @"rangeCol"]) - return ([ipsc_tmp subnetHostAddrRange]); - else if ([[aTableColumn identifier] isEqualToString: @"subnetCol"]) - return ([ipsc_tmp subnetId]); - else if ([[aTableColumn identifier] isEqualToString: @"broadcastCol"]) - return ([ipsc_tmp subnetBroadcast]); - } - return (nil); -} - -- (void)printAllSubnets -{ - IPSubnetCalc *ipsc_tmp; - unsigned int mask; - unsigned int i; - - if (ipsc) - { - for (i = 0; i < [[ipsc subnetMax] unsignedIntValue]; i++) - { - mask = i; - mask <<= (32 - [ipsc maskBitsIntValue]); - ipsc_tmp = [[IPSubnetCalc alloc] init]; - [ipsc_tmp initAddressAndMaskWithUnsignedInt:([ipsc netIdIntValue] | mask) mask: [ipsc subnetMaskIntValue]]; - NSLog(@"# : %d", i + 1); - NSLog(@"Subnet ID : %@", [ipsc_tmp subnetId]); - NSLog(@"IP Range : %@", [ipsc_tmp subnetHostAddrRange]); - NSLog(@"Broadcast : %@", [ipsc_tmp subnetBroadcast]); - } - } -} - -- (void)tableView:(NSTableView *)aTableView - setObjectValue:(id)anObject - forTableColumn:(NSTableColumn *)aTableColumn - row:(int)rowIndex -{ -} - -- (void)bitsOnSlidePos -{ - NSRect coordLabel, coordSlider; - - coordLabel = [bitsOnSlide frame]; - coordSlider = [subnetBitsSlide frame]; - coordLabel.origin.x = coordSlider.origin.x - (coordLabel.size.width / 2) + ([subnetBitsSlide knobThickness] / 2) + (((coordSlider.size.width - ([subnetBitsSlide knobThickness] / 2)) / [subnetBitsSlide numberOfTickMarks]) * ([subnetBitsSlide floatValue] - 1.0)); - //NSLog(@"slide x : %f label width : %f slide knob : %f slide width : %f n tick marks : %d slide value : %f x coord %f", coordSlider.origin.x, coordLabel.size.width, [subnetBitsSlide knobThickness], coordSlider.size.width, (int)[subnetBitsSlide numberOfTickMarks], [subnetBitsSlide floatValue], coordLabel.origin.x); - [bitsOnSlide setFrame: coordLabel]; - -} - -- (IBAction)subnetBitsSlide:(id)sender -{ - unsigned int mask = -1; - - [self doIPSubnetCalc:(mask << (32 - [sender intValue]))]; - [subnetsHostsView reloadData]; -} - -- (IBAction)changeTableViewClass:(id)sender -{ - if ([tabViewClassLess state] == NSOnState) - { - if (ipsc) - [ipsc setClassless: YES]; - } - else - { - if (ipsc) - [ipsc setClassless: NO]; - } - [subnetsHostsView reloadData]; -} - -- (IBAction)changeWildcard:(id)sender -{ - int i; - unsigned int mask = -1; - unsigned int addr_nl; - - [subnetMaskCombo removeAllItems]; - if ([wildcard state] == NSOnState) - { - for (i = 24; i > 1; i--) - { - addr_nl = (mask << i); - [subnetMaskCombo addItemWithObjectValue: [IPSubnetCalc denumberize: ~addr_nl]]; - } - if (ipsc) - { - [subnetMaskCombo selectItemWithObjectValue: [IPSubnetCalc denumberize: ~([ipsc subnetMaskIntValue])]]; - } - else - { - [subnetMaskCombo selectItemWithObjectValue: @"0.0.0.255"]; - } - } - else - { - for (i = 24; i > 1; i--) - { - addr_nl = (mask << i); - [subnetMaskCombo addItemWithObjectValue: [IPSubnetCalc denumberize: addr_nl]]; - } - if (ipsc) - { - [subnetMaskCombo selectItemWithObjectValue: [ipsc subnetMask]]; - } - else - { - [subnetMaskCombo selectItemWithObjectValue: @"255.0.0.0"]; - } - } -} - - -- (IBAction)exportCSV:(id)sender -{ - NSSavePanel *panel; - - if (ipsc) - { - panel = [NSSavePanel savePanel]; - [panel setAllowedFileTypes:[NSArray arrayWithObject: @"csv"]]; - [panel beginWithCompletionHandler: ^(NSModalResponse result){ - if (result == NSFileHandlingPanelOKButton) - { - NSString *str_csv; - unsigned int i; - unsigned mask; - NSMutableData *data_cvs; - NSFileHandle *file_cvs; - NSFileManager *file_mgt; - IPSubnetCalc *ipsc_tmp; - unsigned int netId; - unsigned int subnetMask; - unsigned int maskBits; - unsigned int subnetMax; - - if ((file_mgt = [[NSFileManager alloc] init])) - { - [file_mgt createFileAtPath:[[panel URL] path] contents:nil attributes:nil]; - } - data_cvs = [NSMutableData dataWithCapacity: 200000000]; - file_cvs = [NSFileHandle fileHandleForWritingAtPath: [[panel URL] path]]; - if (file_cvs && data_cvs) - { - netId = [ipsc netIdIntValue]; - subnetMask = [ipsc subnetMaskIntValue]; - maskBits = [ipsc maskBitsIntValue]; - subnetMax = [[ipsc subnetMax] unsignedIntValue]; - //[self printAllSubnets]; - str_csv = @"#;Subnet ID;Range;Broadcast\n"; - [data_cvs appendData: [str_csv dataUsingEncoding: NSASCIIStringEncoding]]; - @autoreleasepool { - for (i = 0; i < subnetMax; i++) - { - mask = i; - mask <<= (32 - maskBits); - if ((ipsc_tmp = [[IPSubnetCalc alloc] init])) - { - [ipsc_tmp initAddressAndMaskWithUnsignedInt: (netId | mask) mask: subnetMask]; - if ((str_csv = [[NSString alloc] initWithFormat:@"%d;%@;%@;%@\n", i + 1, [ipsc_tmp subnetId], [ipsc_tmp subnetHostAddrRange], [ipsc_tmp subnetBroadcast]])) - { - [data_cvs appendData: [str_csv dataUsingEncoding: NSASCIIStringEncoding]]; - } - } - } - [file_cvs writeData: data_cvs]; - [file_cvs synchronizeFile]; - [file_cvs closeFile]; - } - } - } - }]; - } -} - -- (IBAction)exportClipboard:(id)sender -{ - NSPasteboard *pb = [NSPasteboard generalPasteboard]; - NSString *str; - - [pb clearContents]; - str = [[NSString alloc] init]; - if (ipsc) - { - str = [str stringByAppendingFormat: @"Address Class Type: %@\nIP Address: %@\nSubnet ID: %@\nSubnet Mask: %@\nBroadcast: %@\nIP Range: %@\nMask Bits: %@\nSubnet Bits: %@\nMax Subnets: %@\nMax Hosts / Subnet : %@\nAddress Hexa: %@\nBitMap: %@\nBinMap: %@\n", [ipsc networkClass], [IPSubnetCalc denumberize:[ipsc hostAddrIntValue]], [ipsc subnetId], [ipsc subnetMask], [ipsc subnetBroadcast], [ipsc subnetHostAddrRange], [[ipsc maskBits] stringValue], [[ipsc subnetBits] stringValue], [[ipsc subnetMax] stringValue], [[ipsc hostMax] stringValue], [ipsc hexMap], [ipsc bitMap], [ipsc binMap]]; - [pb setString: str forType:NSStringPboardType]; - } -} - -- (IBAction)darkMode:(id)sender -{ - if (@available(macOS 10.14, *)) { - if ([darkModeMenu state] == NSControlStateValueOff) - { - NSApp.appearance = [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]; - [darkModeMenu setState: NSControlStateValueOn]; - } - else if ([darkModeMenu state] == NSControlStateValueOn) - { - NSApp.appearance = nil; - [darkModeMenu setState: NSControlStateValueOff]; - } - } -} - --(NSString *)URLEncode:(NSString *)url -{ - NSString *url_encoded; - - if (url) - { - url_encoded = [[NSString alloc] initWithString: url]; - url_encoded = [url_encoded stringByReplacingOccurrencesOfString: @" " withString: @"%20"]; - url_encoded = [url_encoded stringByReplacingOccurrencesOfString: @"\n" withString: @"%0D"]; - url_encoded = [url_encoded stringByReplacingOccurrencesOfString: @"/" withString: @"%2F"]; - } - return (url_encoded); -} - -- (void)windowDidResize:(NSNotification *)notification -{ - [self bitsOnSlidePos]; -} - -- (void)windowWillClose:(NSNotification *)notif -{ - [NSApp terminate: self]; -} - -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - int i; - unsigned int mask = -1; - unsigned int addr_nl; - NSMutableAttributedString *astr; - - for (i = 24; i > 1; i--) - { - addr_nl = (mask << i); - if ([wildcard state] == NSOnState) - { - [subnetMaskCombo addItemWithObjectValue: [IPSubnetCalc denumberize: ~addr_nl]]; - } - else - { - [subnetMaskCombo addItemWithObjectValue: [IPSubnetCalc denumberize: addr_nl]]; - } - } - for (i = 8; i < 31; i++) - [maskBitsCombo addItemWithObjectValue: [NSString stringWithFormat: @"%d", i]]; - for (i = 0; i < 23; i++) - [subnetBitsCombo addItemWithObjectValue: [NSString stringWithFormat: @"%d", i]]; - for (i = 2; i < 25; i++) - { - mask = (pow(2, i) - 2); - [maxHostsBySubnetCombo addItemWithObjectValue: [NSString stringWithFormat: @"%u", mask]]; - } - for (i = 0; i < 23; i++) - { - mask = (pow(2, i)); - [maxSubnetsCombo addItemWithObjectValue: [NSString stringWithFormat: @"%u", mask]]; - } - astr = [[NSMutableAttributedString alloc] initWithString : @"nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh"]; - /* - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, 9)]; - [astr addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(9, 26)]; - */ - [classBitMap setAttributedStringValue: astr]; - [subnetMaskCombo selectItemWithObjectValue: @"255.0.0.0"]; - [maskBitsCombo selectItemWithObjectValue: @"8"]; - [subnetBitsCombo selectItemWithObjectValue: @"0"]; - //NSApp.appearance = [NSAppearance appearanceNamed: NSAppearanceNameAqua]; - [self initCIDR]; -} - -@end diff --git a/SubnetCalcAppDelegate.swift b/SubnetCalcAppDelegate.swift new file mode 100644 index 0000000..b17de97 --- /dev/null +++ b/SubnetCalcAppDelegate.swift @@ -0,0 +1,970 @@ +// +// SubnetCalcAppDelegate.swift +// SubnetCalc +// +// Created by Julien Mulot on 22/11/2020. +// + +import Foundation +import Cocoa + +@main +class SubnetCalcAppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate, NSTableViewDataSource { + private enum Constants { + static let defaultIP: String = "10.0.0.0" + static let defaultIPv6Mask: String = "64" + static let defaultIPv6to4Mask: Int = 96 + static let BUFFER_LINES:Int = 200000000 + static let NETWORK_BITS_MIN_CLASSLESS:Int = 1 + static let NETWORK_BITS_MIN:Int = 8 + static let NETWORK_BITS_MAX:Int = 32 + } + + //General UI elements + @IBOutlet var window: NSWindow! + @IBOutlet var addrField: NSTextField! + @IBOutlet var exportButton: NSPopUpButton! + @IBOutlet var tabView: NSTabView! + @IBOutlet var darkModeMenu: NSMenuItem! + @IBOutlet var NSApp: NSApplication! + + //IPv4 UI elements + @IBOutlet var classBinaryMap: NSTextField! + @IBOutlet var classBitMap: NSTextField! + @IBOutlet var classHexaMap: NSTextField! + @IBOutlet var classType: NSPopUpButton! + @IBOutlet var maskBitsCombo: NSComboBox! + @IBOutlet var maxHostsBySubnetCombo: NSComboBox! + @IBOutlet var maxSubnetsCombo: NSComboBox! + @IBOutlet var subnetBitsCombo: NSComboBox! + @IBOutlet var subnetBroadcast: NSTextField! + @IBOutlet var subnetHostAddrRange: NSTextField! + @IBOutlet var subnetId: NSTextField! + @IBOutlet var subnetMaskCombo: NSComboBox! + @IBOutlet var subnetsHostsView: NSTableView! + @IBOutlet var supernetMaskBitsCombo: NSComboBox! + @IBOutlet var supernetMaskCombo: NSComboBox! + @IBOutlet var supernetMaxCombo: NSComboBox! + @IBOutlet var supernetMaxAddr: NSComboBox! + @IBOutlet var supernetMaxSubnetsCombo: NSComboBox! + @IBOutlet var supernetRoute: NSTextField! + @IBOutlet var supernetAddrRange: NSTextField! + @IBOutlet var subnetBitsSlide: NSSlider! + @IBOutlet var bitsOnSlide: NSTextField! + @IBOutlet var tabViewClassLess: NSButton! + @IBOutlet var wildcard: NSButton! + @IBOutlet var dotted: NSButton! + + //IPv6 UI elements + @IBOutlet var ipv6Address: NSTextField! + @IBOutlet var ipv6to4Address: NSTextField! + @IBOutlet var ipv6maskBitsCombo: NSComboBox! + @IBOutlet var ipv6SubnetsCombo: NSComboBox! + @IBOutlet var ipv6maxHostsCombo: NSComboBox! + @IBOutlet var ipv6Network: NSTextField! + @IBOutlet var ipv6Range: NSTextField! + @IBOutlet var ipv6Type: NSTextField! + @IBOutlet var ipv6HexaID: NSTextField! + @IBOutlet var ipv6Decimal: NSTextField! + @IBOutlet var ipv6Arpa: NSTextField! + @IBOutlet var ipv6Compact: NSButton! + @IBOutlet var ipv6to4Box: NSBox! + + + //Private global vars + private var savedTabView: [NSTabViewItem]? //ex tab_tabView + private var ipsc: IPSubnetCalc? + + + //Private IPv4 functions + private func initCIDRTab() { + for bits in (1...32) { + supernetMaskBitsCombo.addItem(withObjectValue: String(bits)) + } + + for index in (0...31).reversed() { + supernetMaskCombo.addItem(withObjectValue: IPSubnetCalc.digitize(ipAddress: (IPSubnetCalc.Constants.addr32Full << index))) + } + for index in (0...31) { + supernetMaxCombo.addItem(withObjectValue: NSDecimalNumber(decimal: pow(2, index)).stringValue) + } + for index in (1...31) { + supernetMaxAddr.addItem(withObjectValue: NSDecimalNumber(decimal: (pow(2, index) - 2)).stringValue) + } + for index in (0...32) { + supernetMaxSubnetsCombo.addItem(withObjectValue: NSDecimalNumber(decimal: pow(2, index)).stringValue) + } + } + + private func initSubnetsTab() { + for index in (0...24).reversed() { + if (wildcard.state == NSControl.StateValue.on) { + subnetMaskCombo.addItem(withObjectValue: IPSubnetCalc.digitize(ipAddress: ~(IPSubnetCalc.Constants.addr32Full << index))) + } + else { + subnetMaskCombo.addItem(withObjectValue: IPSubnetCalc.digitize(ipAddress: (IPSubnetCalc.Constants.addr32Full << index))) + } + } + for bits in (8...32) { + maskBitsCombo.addItem(withObjectValue: String(bits)) + } + for bits in (0...24) { + subnetBitsCombo.addItem(withObjectValue: String(bits)) + } + for index in (1...24) { + maxHostsBySubnetCombo.addItem(withObjectValue: NSDecimalNumber(decimal: (pow(2, index) - 2)).stringValue) + } + for index in (0...24) { + maxSubnetsCombo.addItem(withObjectValue: NSDecimalNumber(decimal: pow(2, index)).stringValue) + } + classBitMap.stringValue = "nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh" + classBinaryMap.stringValue = "00000001.00000000.00000000.00000000" + classHexaMap.stringValue = "01.00.00.00" + } + + private func bitsOnSlidePos() + { + var coordLabel = bitsOnSlide.frame + let coordSlider = subnetBitsSlide.frame + + coordLabel.origin.x = coordSlider.origin.x - (coordLabel.size.width / 2) + (subnetBitsSlide.knobThickness / 2) + (((coordSlider.size.width - (subnetBitsSlide.knobThickness / 2)) / CGFloat(subnetBitsSlide.numberOfTickMarks)) * CGFloat(subnetBitsSlide.floatValue - 1.0)) + bitsOnSlide.frame = coordLabel + } + + private func initClassInfos(_ c: String) + { + if (c == "A") + { + classType.selectItem(at: 0) + } + else if (c == "B") + { + classType.selectItem(at: 1) + } + else if (c == "C") + { + classType.selectItem(at: 2) + } + else if (c == "D") + { + classType.selectItem(at: 3) + /* + savedTabView = tabView.tabViewItems + if (savedTabView != nil) + { + tabView.removeTabViewItem(savedTabView![1]) + tabView.removeTabViewItem(savedTabView![2]) + tabView.removeTabViewItem(savedTabView![3]) + } + */ + } + else if (c == "E") + { + classType.selectItem(at: 4) + } + } + + private func splitAddrMask(address: String) -> (String, String?) { + let ipInfo = address.split(separator: "/") + if ipInfo.count == 2 { + return (String(ipInfo[0]), String(ipInfo[1])) + } + else if ipInfo.count > 2 { + print("Bad IP format: \(ipInfo)") + return ("", nil) + } + return (address, nil) + } + + private func doAddressMap() { + if (ipsc != nil) { + self.initClassInfos(ipsc!.netClass()) + if (dotted.state == NSControl.StateValue.on) { + classBitMap.stringValue = ipsc!.bitMap(dotted: true) + classBinaryMap.stringValue = ipsc!.binaryMap(dotted: true) + classHexaMap.stringValue = ipsc!.hexaMap(dotted: true) + } + else { + classBitMap.stringValue = ipsc!.bitMap(dotted: false) + classBinaryMap.stringValue = ipsc!.binaryMap(dotted: false) + classHexaMap.stringValue = ipsc!.hexaMap(dotted: false) + } + } + } + + private func doSubnet() + { + if (ipsc != nil) { + subnetBitsCombo.selectItem(withObjectValue: String(ipsc!.subnetBits())) + maskBitsCombo.selectItem(withObjectValue: String(ipsc!.maskBits)) + maxSubnetsCombo.selectItem(withObjectValue: String(ipsc!.maxSubnets())) + maxHostsBySubnetCombo.selectItem(withObjectValue: String(ipsc!.maxHosts())) + subnetId.stringValue = ipsc!.subnetId() + subnetBroadcast.stringValue = ipsc!.subnetBroadcast() + subnetHostAddrRange.stringValue = ipsc!.subnetRange() + if (wildcard.state == NSControl.StateValue.on) { + subnetMaskCombo.selectItem(withObjectValue: ipsc!.wildcardMask()) + } + else { + subnetMaskCombo.selectItem(withObjectValue: ipsc!.subnetMask()) + } + } + } + + private func doSubnetHost() + { + if (ipsc != nil) { + bitsOnSlide.stringValue = String(ipsc!.maskBits) + subnetBitsSlide.intValue = Int32(ipsc!.maskBits) + self.bitsOnSlidePos() + subnetsHostsView.reloadData() + } + } + + private func doCIDR(maskbits: Int? = nil) + { + if (ipsc != nil) { + if (maskbits == nil) { + supernetMaskBitsCombo.selectItem(withObjectValue: String(ipsc!.maskBits)) + supernetMaskCombo.selectItem(withObjectValue: ipsc!.subnetMask()) + supernetMaxSubnetsCombo.selectItem(withObjectValue: String(ipsc!.maxCIDRSubnets())) + supernetMaxAddr.selectItem(withObjectValue: String(ipsc!.maxHosts())) + supernetMaxCombo.selectItem(withObjectValue: String(ipsc!.maxCIDRSupernet())) + supernetRoute.stringValue = ipsc!.subnetId() + "/" + String(ipsc!.maskBits) + supernetAddrRange.stringValue = ipsc!.subnetCIDRRange() + } + else { + let ipsc_tmp = IPSubnetCalc(ipAddress: ipsc!.ipv4Address, maskbits: maskbits!) + if (ipsc_tmp != nil) { + supernetMaskBitsCombo.selectItem(withObjectValue: String(ipsc_tmp!.maskBits)) + supernetMaskCombo.selectItem(withObjectValue: ipsc_tmp!.subnetMask()) + supernetMaxSubnetsCombo.selectItem(withObjectValue: String(ipsc_tmp!.maxCIDRSubnets())) + supernetMaxAddr.selectItem(withObjectValue: String(ipsc_tmp!.maxHosts())) + supernetMaxCombo.selectItem(withObjectValue: String(ipsc_tmp!.maxCIDRSupernet())) + supernetRoute.stringValue = ipsc_tmp!.subnetId() + "/" + String(ipsc_tmp!.maskBits) + supernetAddrRange.stringValue = ipsc_tmp!.subnetCIDRRange() + } + } + } + } + + private func myAlert(message: String, info: String) + { + let alert = NSAlert() + alert.addButton(withTitle: "OK") + alert.messageText = message + alert.alertStyle = NSAlert.Style.warning + alert.informativeText = info + alert.runModal() + } + + private func doIPSubnetCalc() + { + var ipaddr: String + var ipmask: String? + + if (addrField.stringValue.isEmpty) { + if (ipsc == nil) + { + addrField.stringValue = Constants.defaultIP + ipaddr = Constants.defaultIP + ipmask = nil + } + else { + addrField.stringValue = ipsc!.ipv4Address + ipaddr = ipsc!.ipv4Address + ipmask = String(ipsc!.maskBits) + } + } + else { + (ipaddr, ipmask) = splitAddrMask(address: addrField.stringValue) + addrField.stringValue = ipaddr + if (IPSubnetCalc.isValidIPv6(ipAddress: ipaddr, mask: Int(ipmask ?? Constants.defaultIPv6Mask)) == true) { + if (ipsc != nil) { + ipaddr = ipsc!.ipv4Address + } + if (ipmask != nil) { + if (Int(ipmask!)! >= (Constants.defaultIPv6to4Mask + 8)) { + ipmask = String(Int(ipmask!)! - Constants.defaultIPv6to4Mask) + } + else { + ipmask = "8" + } + } + } + if (ipmask == nil && ipsc != nil) { + ipmask = String(ipsc!.maskBits) + } + } + if (IPSubnetCalc.isValidIP(ipAddress: ipaddr, mask: ipmask) == true) { + //print("IP Address: \(ipaddr) mask: \(ipmask)") + if (ipmask == nil) { + ipsc = IPSubnetCalc(ipaddr) + } + else { + ipsc = IPSubnetCalc(ipAddress: ipaddr, maskbits: Int(ipmask!)!) + } + if (ipsc != nil) { + if (tabView.numberOfTabViewItems != 4 && savedTabView != nil) { + tabView.addTabViewItem(savedTabView![1]) + tabView.addTabViewItem(savedTabView![2]) + tabView.addTabViewItem(savedTabView![3]) + } + self.doAddressMap() + self.doSubnet() + self.doSubnetHost() + self.doCIDR() + self.doIPv6() + } + } + else { + myAlert(message: "Bad IPv4 Address", info: "Bad format: \(ipaddr)/\(ipmask ?? "")") + return + } + } + + //Private IPv6 functions + private func initIPv6Tab() { + var total = Decimal() + var number: Decimal = 2 + + for index in (1...128) { + ipv6maskBitsCombo.addItem(withObjectValue: String(index)) + } + for index in (0...127) { + NSDecimalPower(&total, &number , index, NSDecimalNumber.RoundingMode.plain) + ipv6maxHostsCombo.addItem(withObjectValue: total) + } + } + + private func doIPv6() + { + if (ipsc != nil) { + var total = Decimal() + var number: Decimal = 2 + var typeConv: String + + if (ipv6Compact.state == NSControl.StateValue.on) { + ipv6Address.stringValue = ipsc!.compactAddressIPv6(ipAddress: ipsc!.ipv6Address) + ipv6Network.stringValue = ipsc!.compactAddressIPv6(ipAddress: ipsc!.networkIPv6()) + } + else { + ipv6Address.stringValue = ipsc!.fullAddressIPv6(ipAddress: ipsc!.ipv6Address) + ipv6Network.stringValue = ipsc!.fullAddressIPv6(ipAddress: ipsc!.networkIPv6()) + } + (ipv6to4Address.stringValue, typeConv) = IPSubnetCalc.convertIPv6toIPv4(ipAddress: ipsc!.ipv6Address) + ipv6to4Box.title = "IPv4 conversion" + " (\(typeConv))" + ipv6maskBitsCombo.selectItem(withObjectValue: String(ipsc!.ipv6MaskBits)) + ipv6maxHostsCombo.selectItem(withObjectValue: ipsc!.totalIPAddrIPv6()) + ipv6Range.stringValue = ipsc!.networkRangeIPv6() + ipv6Type.stringValue = ipsc!.resBlockIPv6() ?? "None" + ipv6HexaID.stringValue = ipsc!.hexaIDIPv6() + ipv6Decimal.stringValue = ipsc!.dottedDecimalIPv6() + ipv6Arpa.stringValue = ipsc!.ip6ARPA() + ipv6SubnetsCombo.removeAllItems() + for index in (1...ipsc!.ipv6MaskBits).reversed() { + NSDecimalPower(&total, &number , ipsc!.ipv6MaskBits - index, NSDecimalNumber.RoundingMode.plain) + if (total == 1) { + ipv6SubnetsCombo.addItem(withObjectValue: "/\(index)\t\(total) network") + } + else { + ipv6SubnetsCombo.addItem(withObjectValue: "/\(index)\t\(total) networks") + } + } + ipv6SubnetsCombo.selectItem(at: 0) + } + } + + private func doIPv6SubnetCalc() + { + var ipaddr: String + var ipmask: String? + + (ipaddr, ipmask) = splitAddrMask(address: addrField.stringValue) + addrField.stringValue = ipaddr + if (IPSubnetCalc.isValidIP(ipAddress: ipaddr, mask: ipmask) == true) { + if (ipsc != nil) { + ipaddr = ipsc!.ipv6Address + //print("doIPv6SubnetCalc ipaddr to ipv6 : \(ipsc!.ipv6Address)") + } + } + if (ipmask == nil) { + if (ipsc != nil) { + ipmask = String(ipsc!.ipv6MaskBits) + //print("doIPv6SubnetCalc ipmask ipv6 : \(ipsc!.ipv6MaskBits)") + } + else { + ipmask = Constants.defaultIPv6Mask + } + } + else if (Int(ipmask!) == nil) { + myAlert(message: "Bad IPv6 mask", info: "Bad format: \(ipmask!)") + return + } + if (IPSubnetCalc.isValidIPv6(ipAddress: ipaddr, mask: Int(ipmask!)) == true) { + //print("IP Address: \(ipaddr) mask: \(ipmask)") + ipsc = IPSubnetCalc(ipv6: ipaddr, maskbits: Int(ipmask!)!) + if (ipsc != nil) { + if (tabView.numberOfTabViewItems != 4 && savedTabView != nil) { + tabView.addTabViewItem(savedTabView![1]) + tabView.addTabViewItem(savedTabView![2]) + tabView.addTabViewItem(savedTabView![3]) + } + self.doAddressMap() + self.doSubnet() + self.doSubnetHost() + self.doCIDR() + self.doIPv6() + } + } + else { + myAlert(message: "Bad IPv6 Address", info: "Bad format: \(ipaddr)/\(ipmask ?? "")") + return + } + } + + + //IPv4 UI actions + @IBAction func changeAddrClassType(_ sender: AnyObject) + { + if (tabView.numberOfTabViewItems != 4 && savedTabView != nil) { + tabView.addTabViewItem(savedTabView![1]) + tabView.addTabViewItem(savedTabView![2]) + tabView.addTabViewItem(savedTabView![3]) + } + if (sender.indexOfSelectedItem() == 0) + { + classBitMap.stringValue = "nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh" + classBinaryMap.stringValue = "00000001.00000000.00000000.00000000" + classHexaMap.stringValue = "01.00.00.00" + } + else if (sender.indexOfSelectedItem() == 1) + { + classBitMap.stringValue = "nnnnnnnn.nnnnnnnn.hhhhhhhh.hhhhhhhh" + classBinaryMap.stringValue = "10000000.00000000.00000000.00000000" + classHexaMap.stringValue = "80.00.00.00" + } + else if (sender.indexOfSelectedItem() == 2) + { + classBitMap.stringValue = "nnnnnnnn.nnnnnnnn.nnnnnnnn.hhhhhhhh" + classBinaryMap.stringValue = "11000000.00000000.00000000.00000000" + classHexaMap.stringValue = "C0.00.00.00" + } + else if (sender.indexOfSelectedItem() == 3) + { + /* + savedTabView = tabView.tabViewItems + if (savedTabView != nil) + { + tabView.removeTabViewItem(savedTabView![1]) + tabView.removeTabViewItem(savedTabView![2]) + tabView.removeTabViewItem(savedTabView![3]) + } + */ + classBitMap.stringValue = "hhhhhhhh.hhhhhhhh.hhhhhhhh.hhhhhhhh" + classBinaryMap.stringValue = "11100000.00000000.00000000.00000000" + classHexaMap.stringValue = "E0.00.00.00" + } + else if (sender.indexOfSelectedItem() == 4) + { + /* + savedTabView = tabView.tabViewItems + if (savedTabView != nil) + { + tabView.removeTabViewItem(savedTabView![1]) + tabView.removeTabViewItem(savedTabView![2]) + tabView.removeTabViewItem(savedTabView![3]) + } + */ + classBitMap.stringValue = "hhhhhhhh.hhhhhhhh.hhhhhhhh.hhhhhhhh" + classBinaryMap.stringValue = "11110000.00000000.00000000.00000000" + classHexaMap.stringValue = "F0.00.00.00" + } + } + + @IBAction func changeMaxHosts(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.indexOfSelectedItem != -1) { + ipsc!.maskBits = 31 - sender.indexOfSelectedItem() + self.doIPSubnetCalc() + } + else { + myAlert(message: "Bad Max Hosts", info: "Bad selection") + return + } + } + + @IBAction func changeMaxSubnets(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.indexOfSelectedItem != -1) { + ipsc!.maskBits = 8 + sender.indexOfSelectedItem() + self.doIPSubnetCalc() + } + else { + myAlert(message: "Bad Max Subnets", info: "Bad selection") + return + } + } + + @IBAction func changeSubnetBits(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.objectValueOfSelectedItem as? String) != nil { + ipsc!.maskBits = sender.intValue + ipsc!.netBits() + self.doIPSubnetCalc() + } + else { + myAlert(message: "Bad Subnet Bits", info: "Bad selection") + return + } + } + + @IBAction func changeSubnetMask(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + // Check cast as String needed ? + if let maskStr = sender.objectValueOfSelectedItem as? String { + let mask:UInt32 = IPSubnetCalc.numerize(ipAddress: maskStr) + if (wildcard.state == NSControl.StateValue.on) { + ipsc!.maskBits = IPSubnetCalc.maskBits(mask: ~mask) + } + else { + ipsc!.maskBits = IPSubnetCalc.maskBits(mask: mask) + //print("changeSubnetMask object value : \(str)") + } + self.doIPSubnetCalc() + } + else { + myAlert(message: "Bad Subnet Mask", info: "Bad selection") + return + } + } + + @IBAction func changeMaskBits(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.objectValueOfSelectedItem as? String) != nil { + ipsc!.maskBits = sender.intValue + self.doIPSubnetCalc() + } + else { + myAlert(message: "Bad Mask Bits", info: "Bad selection") + return + } + } + + @IBAction func changeSupernetMaskBits(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.objectValueOfSelectedItem as? String) != nil { + let classType = ipsc!.netClass() + var result: Int = -1 + + if (classType == "A") { + result = sender.intValue - 8 + } + else if (classType == "B") { + result = sender.intValue - 16 + } + else if (classType == "C") { + result = sender.intValue - 24 + } + if (result >= 0) { + ipsc!.maskBits = sender.intValue + self.doIPSubnetCalc() + } + else { + doCIDR(maskbits: sender.intValue) + } + } + else { + myAlert(message: "Bad CIDR Mask Bits", info: "Bad selection") + return + } + } + + @IBAction func changeSupernetMask(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if let maskStr = sender.objectValueOfSelectedItem as? String { + let mask:UInt32 = IPSubnetCalc.numerize(ipAddress: maskStr) + let maskbits:Int = IPSubnetCalc.maskBits(mask: mask) + let classType = ipsc!.netClass() + var result: Int = -1 + + if (classType == "A") { + result = maskbits - 8 + } + else if (classType == "B") { + result = maskbits - 16 + } + else if (classType == "C") { + result = maskbits - 24 + } + if (result >= 0) { + ipsc!.maskBits = maskbits + self.doIPSubnetCalc() + } + else { + doCIDR(maskbits: maskbits) + } + } + else { + myAlert(message: "Bad CIDR Mask", info: "Bad selection") + return + } + } + + @IBAction func changeSupernetMax(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.indexOfSelectedItem != -1) { + let classType = ipsc!.netClass() + var result: Int = -1 + + if (classType == "A") { + result = 8 - sender.indexOfSelectedItem + } + else if (classType == "B") { + result = 16 - sender.indexOfSelectedItem + } + else if (classType == "C") { + result = 24 - sender.indexOfSelectedItem + } + if (result > 0) { + doCIDR(maskbits: result) + } + else { + myAlert(message: "Bad Max Supernets", info: "Value too high") + return + } + } + else { + myAlert(message: "Bad Max Supernets", info: "Bad selection") + return + } + } + + @IBAction func changeSupernetMaxAddr(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.indexOfSelectedItem != -1) { + if ((32 - sender.indexOfSelectedItem - 1) < 32) { + doCIDR(maskbits: (32 - sender.indexOfSelectedItem - 1)) + } + else { + myAlert(message: "Bad Max Adresses", info: "Bad value") + return + } + } + else { + myAlert(message: "Bad Max Adresses", info: "Bad selection") + return + } + } + + @IBAction func changeSupernetMaxSubnets(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.indexOfSelectedItem != -1) { + if ((32 - sender.indexOfSelectedItem) <= 32) { + doCIDR(maskbits: (32 - sender.indexOfSelectedItem)) + } + else { + myAlert(message: "Bad Max Subnets", info: "Bad value") + return + } + } + else { + myAlert(message: "Bad Max Subnets", info: "Bad selection") + return + } + } + + func numberOfRows(in tableView: NSTableView) -> Int + { + if (ipsc != nil) { + if (tabViewClassLess.state == NSControl.StateValue.on) { + //print("numberOfRows: Maskbits : \(ipsc!.maskBits) Bits compute: \(ipsc!.maskBits - Constants.NETWORK_BITS_MIN_CLASSLESS) Power: \(NSDecimalNumber(decimal: pow(2, (ipsc!.maskBits - Constants.NETWORK_BITS_MIN_CLASSLESS))))") + return Int(truncating: NSDecimalNumber(decimal: pow(2, (ipsc!.maskBits - Constants.NETWORK_BITS_MIN_CLASSLESS)))) + } + else { + return (ipsc!.maxSubnets()) + } + } + return 0 + } + + //Display all subnets info in the TableView Subnet/Hosts + func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, + row: Int) -> Any? + { + if (ipsc != nil) { + let ipaddr: UInt32 = (((IPSubnetCalc.numerize(ipAddress: ipsc!.ipv4Address) & ipsc!.classMask()) >> (32 - ipsc!.maskBits)) + UInt32(row)) << (32 - ipsc!.maskBits) + let ipsc_tmp = IPSubnetCalc(ipAddress: IPSubnetCalc.digitize(ipAddress: ipaddr), maskbits: ipsc!.maskBits) + //print("tableView Row: \(row) IP num : \(ipaddr) IP: \(IPSubnetCalc.digitize(ipAddress: ipaddr)) IP Subnet: \(ipsc_tmp!.subnetId())") + if (tableColumn != nil && ipsc_tmp != nil) { + if (tableColumn!.identifier.rawValue == "numCol") { + return (row + 1) + } + else if (tableColumn!.identifier.rawValue == "subnetCol") { + return (ipsc_tmp!.subnetId()) + } + else if (tableColumn!.identifier.rawValue == "rangeCol") { + return (ipsc_tmp!.subnetRange()) + } + else if (tableColumn!.identifier.rawValue == "broadcastCol") { + return (ipsc_tmp!.subnetBroadcast()) + } + } + } + return (nil) + } + + @IBAction func subnetBitsSlide(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.intValue as Int >= Constants.NETWORK_BITS_MIN) + { + ipsc!.maskBits = sender.intValue as Int + self.doIPSubnetCalc() + //subnetsHostsView.reloadData() + } + else { + let maskbits = sender.intValue as Int + ipsc!.maskBits = Constants.NETWORK_BITS_MIN + self.doIPSubnetCalc() + if (tabViewClassLess.state == NSControl.StateValue.on) { + ipsc!.maskBits = maskbits + self.doSubnetHost() + self.doCIDR(maskbits: maskbits) + ipsc!.maskBits = Constants.NETWORK_BITS_MIN + } + } + } + + @IBAction func changeTableViewClass(_ sender: AnyObject) + { + if (tabViewClassLess.state == NSControl.StateValue.off) { + if (ipsc != nil) { + if (ipsc!.maskBits < Constants.NETWORK_BITS_MIN) { + ipsc!.maskBits = Constants.NETWORK_BITS_MIN + self.doIPSubnetCalc() + } + } + } + self.doSubnetHost() + } + + @IBAction func changeWildcard(_ sender: AnyObject) + { + subnetMaskCombo.removeAllItems() + if (wildcard.state == NSControl.StateValue.on) { + for index in (0...24).reversed() { + subnetMaskCombo.addItem(withObjectValue: IPSubnetCalc.digitize(ipAddress: ~(IPSubnetCalc.Constants.addr32Full << index))) + } + if (ipsc != nil) { + subnetMaskCombo.selectItem(withObjectValue: ipsc!.wildcardMask()) + } + } + else { + for index in (0...24).reversed() { + subnetMaskCombo.addItem(withObjectValue: IPSubnetCalc.digitize(ipAddress: (IPSubnetCalc.Constants.addr32Full << index))) + } + if (ipsc != nil) { + subnetMaskCombo.selectItem(withObjectValue: ipsc!.subnetMask()) + } + } + } + + @IBAction func changeDotted(_ sender: AnyObject) + { + self.doAddressMap() + } + + //IPv6 UI actions + @IBAction func changeIPv6Format(_ sender: AnyObject) + { + self.doIPv6() + } + + @IBAction func changeIPv6MaskBits(_ sender: AnyObject) + { + //print("changeIPv6MaskBits") + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.objectValueOfSelectedItem as? String) != nil { + ipsc!.ipv6MaskBits = sender.intValue + self.doIPv6SubnetCalc() + } + else { + myAlert(message: "Bad IPv6 Mask Bits", info: "Bad selection") + return + } + } + + @IBAction func changeIPv6Subnets(_ sender: AnyObject) + { + if (ipsc == nil ) { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + ipsc!.ipv6MaskBits -= sender.indexOfSelectedItem() + self.doIPv6SubnetCalc() + } + + @IBAction func changeIPv6MaxHosts(_ sender: AnyObject) + { + if (ipsc == nil) + { + ipsc = IPSubnetCalc(Constants.defaultIP) + } + if (sender.indexOfSelectedItem != -1) { + ipsc!.ipv6MaskBits = 128 - sender.indexOfSelectedItem() + self.doIPv6SubnetCalc() + } + else { + myAlert(message: "Bad Max Hosts", info: "Bad selection") + return + } + } + + //General UI actions + @IBAction func calc(_ sender: AnyObject) + { + if (addrField.stringValue.contains(":")) { + self.doIPv6SubnetCalc() + tabView.selectTabViewItem(at: 3) + } + else { + self.doIPSubnetCalc() + tabView.selectTabViewItem(at: 0) + } + } + + @IBAction func ipAddrEdit(_ sender: AnyObject) + { + self.calc(sender) + } + + @IBAction func exportCSV(_ sender: AnyObject) + { + if (ipsc != nil) { + let panel = NSSavePanel() + panel.allowedFileTypes = ["csv"] + panel.begin(completionHandler: { (result) in + if (result == NSApplication.ModalResponse.OK && panel.url != nil) { + var fileMgt: FileManager + if #available(OSX 10.14, *) { + fileMgt = FileManager(authorization: NSWorkspace.Authorization()) + } else { + // Fallback on earlier versions + fileMgt = FileManager.default + } + fileMgt.createFile(atPath: panel.url!.path, contents: nil, attributes: nil) + //var cvsData = NSMutableData.init(capacity: Constants.BUFFER_LINES) + var cvsData = Data(capacity: Constants.BUFFER_LINES) + let cvsFile = FileHandle(forWritingAtPath: panel.url!.path) + if (cvsFile != nil) { + var cvsStr = "#;Subnet ID;Range;Broadcast\n" + for index in (0...(self.ipsc!.maxSubnets() - 1)) { + let mask: UInt32 = UInt32(index) << (32 - self.ipsc!.maskBits) + let ipaddr = (IPSubnetCalc.numerize(ipAddress: self.ipsc!.subnetId())) | mask + let ipsc_tmp = IPSubnetCalc(ipAddress: IPSubnetCalc.digitize(ipAddress: ipaddr), maskbits: self.ipsc!.maskBits) + if (ipsc_tmp != nil) { + cvsStr.append("\(index + 1);\(ipsc_tmp!.subnetId());\(ipsc_tmp!.subnetRange());\(ipsc_tmp!.subnetBroadcast())\n") + } + } + cvsData.append(cvsStr.data(using: String.Encoding.ascii)!) + cvsFile!.write(cvsData) + cvsFile!.synchronizeFile() + cvsFile!.closeFile() + } + } + } + ) + } + } + + @IBAction func exportClipboard(_ sender: AnyObject) + { + if (ipsc != nil) { + let pb: NSPasteboard = NSPasteboard.general + pb.clearContents() + let ipv4Info = "IPv4 Address Class Type: \(ipsc!.netClass())\nIPv4 Address: \(ipsc!.ipv4Address)\nIPv4 Subnet ID: \(ipsc!.subnetId())\nIPv4 Subnet Mask: \(ipsc!.subnetMask())\nIPv4 Broadcast: \(ipsc!.subnetBroadcast())\nIPv4 Address Range: \(ipsc!.subnetRange())\nIPv4 Mask Bits: \(ipsc!.maskBits)\nIPv4 Subnet Bits: \(ipsc!.subnetBits())\nMax IPv4 Subnets: \(ipsc!.maxSubnets())\nIPv4 Max Hosts / Subnet: \(ipsc!.maxHosts())\nIPv4 Address Hexa: \(ipsc!.hexaMap())\nIPv4 Bit Map: \(ipsc!.bitMap())\nIPv4 Binary Map: \(ipsc!.binaryMap())\n" + let ipv6Info = "\nIPv6 Address: \(ipsc!.ipv6Address)\nLong IPv6 Address: \(ipsc!.fullAddressIPv6(ipAddress: ipsc!.ipv6Address))\nShort IPv6 Address: \(ipsc!.compactAddressIPv6(ipAddress: ipsc!.ipv6Address))\nIPv6-to-IPv4: \(IPSubnetCalc.convertIPv6toIPv4(ipAddress: ipsc!.ipv6Address))\nIPv6 Mask Bits: \(ipsc!.ipv6MaskBits)\nIPv6 Max Hosts / Subnet: \(ipsc!.totalIPAddrIPv6())\nNetwork: \(ipsc!.compactAddressIPv6(ipAddress: ipsc!.networkIPv6()))\nIPv6 Address Range: \(ipsc!.networkRangeIPv6())\nIPv6 Address Type: \(ipsc!.resBlockIPv6() ?? "None")\nIPv6 Address Hexa: \(ipsc!.hexaIDIPv6())\nIPv6 Address Dotted Decimal: \(ipsc!.dottedDecimalIPv6())\nIP6.ARPA: \(ipsc!.ip6ARPA())\n" + pb.setString(ipv4Info + ipv6Info, forType: NSPasteboard.PasteboardType.string) + } + } + + @IBAction func darkMode(_ sender: AnyObject) + { + if #available(OSX 10.14, *) { + if (darkModeMenu!.state == NSControl.StateValue.off) { + NSApp.appearance = NSAppearance(named: NSAppearance.Name.darkAqua) + darkModeMenu.state = NSControl.StateValue.on + } + else if (darkModeMenu!.state == NSControl.StateValue.on) { + NSApp!.appearance = nil + darkModeMenu.state = NSControl.StateValue.off + } + } + } + + func windowDidResize(_ notification: Notification) + { + bitsOnSlidePos() + } + + func windowWillClose(_ notification: Notification) + { + NSApp.terminate(self) + } + + func applicationDidFinishLaunching(_ aNotification: Notification) { + // Insert code here to initialize your application + initSubnetsTab() + initCIDRTab() + initIPv6Tab() + } + + func applicationWillTerminate(_ aNotification: Notification) { + // Insert code here to tear down your application + } +} diff --git a/SubnetCalc.xctestplan b/SubnetCalcUITests/SubnetCalc.xctestplan similarity index 92% rename from SubnetCalc.xctestplan rename to SubnetCalcUITests/SubnetCalc.xctestplan index 6d9a760..a72304e 100644 --- a/SubnetCalc.xctestplan +++ b/SubnetCalcUITests/SubnetCalc.xctestplan @@ -19,7 +19,7 @@ "testTargets" : [ { "skippedTests" : [ - "SubnetCalcUITests\/testLaunchPerformance" + "SubnetCalcUITests" ], "target" : { "containerPath" : "container:SubnetCalc.xcodeproj", diff --git a/SubnetCalcUITests/SubnetCalcUITest.swift b/SubnetCalcUITests/SubnetCalcUITest.swift new file mode 100644 index 0000000..f4a17bc --- /dev/null +++ b/SubnetCalcUITests/SubnetCalcUITest.swift @@ -0,0 +1,251 @@ +// +// SubnetCalcUITest.swift +// SubnetCalcUITests +// +// Created by Julien Mulot on 01/12/2020. +// + +import XCTest + +class SubnetCalcUITest: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + + let subnetcalcWindow = XCUIApplication().windows["SubnetCalc"] + let ipaddrfieldTextField = subnetcalcWindow.textFields["ipaddrfield"] + + subnetcalcWindow.tabs["IPv4"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeText("10.32.2.52/30\r") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetbitscombo"].value as! String, "22") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maskbitscombo"].value as! String, "30") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetmaskcombo"].value as! String, "255.255.255.252") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxsubnetcombo"].value as! String, "4194304") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxhostscombo"].value as! String, "2") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetrangetext"].value as! String, "10.32.2.53 - 10.32.2.54") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetidtext"].value as! String, "10.32.2.52") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetbroadcasttext"].value as! String, "10.32.2.55") + XCTAssertEqual(subnetcalcWindow.popUpButtons["addrclasstypecell"].value as! String, "Class A: 1.0.0.0 - 126.255.255.255") + XCTAssertEqual(subnetcalcWindow.staticTexts["classbitmap"].value as! String, "nnnnnnnn.ssssssss.ssssssss.sssssshh") + XCTAssertEqual(subnetcalcWindow.staticTexts["binarymap"].value as! String, "00001010.00100000.00000010.00110100") + XCTAssertEqual(subnetcalcWindow.staticTexts["hexamap"].value as! String, "0A.20.02.34") + subnetcalcWindow.tabs["CIDR"].click() + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaskbits"].value as! String, "30") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmask"].value as! String, "255.255.255.252") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsubnets"].value as! String, "4") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxaddr"].value as! String, "2") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsupernets"].value as! String, "1") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrnetwork"].value as! String, "10.32.2.52/30") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrrange"].value as! String, "10.32.2.52 - 10.32.2.55") + + subnetcalcWindow.tabs["IPv4"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("192.168.254.129/12\r") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetbitscombo"].value as! String, "0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maskbitscombo"].value as! String, "12") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetmaskcombo"].value as! String, "255.240.0.0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxsubnetcombo"].value as! String, "1") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxhostscombo"].value as! String, "1048574") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetrangetext"].value as! String, "192.160.0.1 - 192.175.255.254") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetidtext"].value as! String, "192.160.0.0") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetbroadcasttext"].value as! String, "192.175.255.255") + XCTAssertEqual(subnetcalcWindow.popUpButtons["addrclasstypecell"].value as! String, "Class C: 192.0.0.0 - 223.255.255.255") + XCTAssertEqual(subnetcalcWindow.staticTexts["classbitmap"].value as! String, "nnnnnnnn.nnnnhhhh.hhhhhhhh.hhhhhhhh") + XCTAssertEqual(subnetcalcWindow.staticTexts["binarymap"].value as! String, "11000000.10101000.11111110.10000001") + XCTAssertEqual(subnetcalcWindow.staticTexts["hexamap"].value as! String, "C0.A8.FE.81") + subnetcalcWindow.tabs["CIDR"].click() + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaskbits"].value as! String, "12") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmask"].value as! String, "255.240.0.0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsubnets"].value as! String, "1048576") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxaddr"].value as! String, "1048574") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsupernets"].value as! String, "4096") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrnetwork"].value as! String, "192.160.0.0/12") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrrange"].value as! String, "192.160.0.0 - 192.175.255.255") + + subnetcalcWindow.tabs["IPv4"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("10.2.255.130/32\r") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetbitscombo"].value as! String, "24") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maskbitscombo"].value as! String, "32") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetmaskcombo"].value as! String, "255.255.255.255") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxsubnetcombo"].value as! String, "16777216") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxhostscombo"].value as! String, "0") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetrangetext"].value as! String, "10.2.255.130 - 10.2.255.130") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetidtext"].value as! String, "10.2.255.130") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetbroadcasttext"].value as! String, "10.2.255.130") + XCTAssertEqual(subnetcalcWindow.popUpButtons["addrclasstypecell"].value as! String, "Class A: 1.0.0.0 - 126.255.255.255") + XCTAssertEqual(subnetcalcWindow.staticTexts["classbitmap"].value as! String, "nnnnnnnn.ssssssss.ssssssss.ssssssss") + XCTAssertEqual(subnetcalcWindow.staticTexts["binarymap"].value as! String, "00001010.00000010.11111111.10000010") + XCTAssertEqual(subnetcalcWindow.staticTexts["hexamap"].value as! String, "0A.02.FF.82") + subnetcalcWindow.tabs["CIDR"].click() + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaskbits"].value as! String, "32") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmask"].value as! String, "255.255.255.255") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsubnets"].value as! String, "1") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxaddr"].value as! String, "0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsupernets"].value as! String, "1") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrnetwork"].value as! String, "10.2.255.130/32") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrrange"].value as! String, "10.2.255.130 - 10.2.255.130") + + subnetcalcWindow.tabs["IPv4"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("242.2.255.130/28\r") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetbitscombo"].value as! String, "0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maskbitscombo"].value as! String, "28") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetmaskcombo"].value as! String, "255.255.255.240") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxsubnetcombo"].value as! String, "1") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxhostscombo"].value as! String, "14") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetrangetext"].value as! String, "242.2.255.129 - 242.2.255.142") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetidtext"].value as! String, "242.2.255.128") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetbroadcasttext"].value as! String, "242.2.255.143") + XCTAssertEqual(subnetcalcWindow.popUpButtons["addrclasstypecell"].value as! String, "Class E/Reserved: 240.0.0.0 - 255.255.255.255") + XCTAssertEqual(subnetcalcWindow.staticTexts["classbitmap"].value as! String, "hhhhhhhh.hhhhhhhh.hhhhhhhh.hhhhhhhh") + XCTAssertEqual(subnetcalcWindow.staticTexts["binarymap"].value as! String, "11110010.00000010.11111111.10000010") + XCTAssertEqual(subnetcalcWindow.staticTexts["hexamap"].value as! String, "F2.02.FF.82") + subnetcalcWindow.checkBoxes["wildcardmask"].click() + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetmaskcombo"].value as! String, "0.0.0.15") + subnetcalcWindow.checkBoxes["dottedipv4"].click() + XCTAssertEqual(subnetcalcWindow.staticTexts["classbitmap"].value as! String, "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh") + XCTAssertEqual(subnetcalcWindow.staticTexts["binarymap"].value as! String, "11110010000000101111111110000010") + XCTAssertEqual(subnetcalcWindow.staticTexts["hexamap"].value as! String, "F202FF82") + subnetcalcWindow.tabs["CIDR"].click() + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaskbits"].value as! String, "28") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmask"].value as! String, "255.255.255.240") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsubnets"].value as! String, "16") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxaddr"].value as! String, "14") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsupernets"].value as! String, "1") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrnetwork"].value as! String, "242.2.255.128/28") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrrange"].value as! String, "242.2.255.128 - 242.2.255.143") + subnetcalcWindow.tabs["IPv4"].click() + subnetcalcWindow.checkBoxes["wildcardmask"].click() + subnetcalcWindow.checkBoxes["dottedipv4"].click() + + subnetcalcWindow.tabs["IPv4"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("172.16.242.132/8\r") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetbitscombo"].value as! String, "0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maskbitscombo"].value as! String, "8") + XCTAssertEqual(subnetcalcWindow.comboBoxes["subnetmaskcombo"].value as! String, "255.0.0.0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxsubnetcombo"].value as! String, "1") + XCTAssertEqual(subnetcalcWindow.comboBoxes["maxhostscombo"].value as! String, "16777214") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetrangetext"].value as! String, "172.0.0.1 - 172.255.255.254") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetidtext"].value as! String, "172.0.0.0") + XCTAssertEqual(subnetcalcWindow.staticTexts["subnetbroadcasttext"].value as! String, "172.255.255.255") + XCTAssertEqual(subnetcalcWindow.popUpButtons["addrclasstypecell"].value as! String, "Class B: 128.0.0.0 - 191.255.255.255") + XCTAssertEqual(subnetcalcWindow.staticTexts["classbitmap"].value as! String, "nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh") + XCTAssertEqual(subnetcalcWindow.staticTexts["binarymap"].value as! String, "10101100.00010000.11110010.10000100") + XCTAssertEqual(subnetcalcWindow.staticTexts["hexamap"].value as! String, "AC.10.F2.84") + subnetcalcWindow.tabs["CIDR"].click() + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaskbits"].value as! String, "8") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmask"].value as! String, "255.0.0.0") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsubnets"].value as! String, "16777216") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxaddr"].value as! String, "16777214") + XCTAssertEqual(subnetcalcWindow.comboBoxes["cidrmaxsupernets"].value as! String, "256") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrnetwork"].value as! String, "172.0.0.0/8") + XCTAssertEqual(subnetcalcWindow.staticTexts["cidrrange"].value as! String, "172.0.0.0 - 172.255.255.255") + + subnetcalcWindow.menuButtons["exportbutton"].click() + subnetcalcWindow.menuItems["exportClipboard:"].click() + let pb: NSPasteboard = NSPasteboard.general + let pbContent = pb.string(forType: NSPasteboard.PasteboardType.string) + let validContent = "IPv4 Address Class Type: B\nIPv4 Address: 172.16.242.132\nIPv4 Subnet ID: 172.0.0.0\nIPv4 Subnet Mask: 255.0.0.0\nIPv4 Broadcast: 172.255.255.255\nIPv4 Address Range: 172.0.0.1 - 172.255.255.254\nIPv4 Mask Bits: 8\nIPv4 Subnet Bits: 0\nMax IPv4 Subnets: 1\nIPv4 Max Hosts / Subnet: 16777214\nIPv4 Address Hexa: AC.10.F2.84\nIPv4 Bit Map: nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh\nIPv4 Binary Map: 10101100.00010000.11110010.10000100\n\nIPv6 Address: 0:0:0:0:0:ffff:ac10:f284\nLong IPv6 Address: 0000:0000:0000:0000:0000:ffff:ac10:f284\nShort IPv6 Address: ::ffff:ac10:f284\nIPv6-to-IPv4: (\"172.16.242.132\", \"IPv4-Mapped\")\nIPv6 Mask Bits: 104\nIPv6 Max Hosts / Subnet: 16777216\nNetwork: ::ffff:ac00:0\nIPv6 Address Range: 0000:0000:0000:0000:0000:ffff:ac00:0000 - 0000:0000:0000:0000:0000:ffff:acff:ffff\nIPv6 Address Type: None\nIPv6 Address Hexa: 0x00000000000000000000ffffac10f284\nIPv6 Address Dotted Decimal: 0.0.0.0.0.0.0.0.0.0.255.255.172.16.242.132\nIP6.ARPA: 4.8.2.f.0.1.c.a.f.f.f.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa\n" + XCTAssertEqual(pbContent,validContent) + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("2001:0db8:0000:85a3:0000:0000:ac1f:8001/127\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "2001:db8:0:85a3::ac1f:8001") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv4addrconvtext"].value as! String, "172.31.128.1") + XCTAssertEqual(subnetcalcWindow.comboBoxes["ipv6maskbitscombo"].value as! String, "127") + XCTAssertEqual(subnetcalcWindow.comboBoxes["ipv6maxsubnetscombo"].value as! String, "/127\t1 network") + XCTAssertEqual(subnetcalcWindow.comboBoxes["ipv6maxhostscombo"].value as! String, "2") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6networktext"].value as! String, "2001:db8:0:85a3::ac1f:8000") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6rangetext"].value as! String, "2001:0db8:0000:85a3:0000:0000:ac1f:8000 - 2001:0db8:0000:85a3:0000:0000:ac1f:8001") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6typetext"].value as! String, "None") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6hexatext"].value as! String, "0x20010db8000085a300000000ac1f8001") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6decimaltext"].value as! String, "32.1.13.184.0.0.133.163.0.0.0.0.172.31.128.1") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6arpatext"].value as! String, "1.0.0.8.f.1.c.a.0.0.0.0.0.0.0.0.3.a.5.8.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa") + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("2001:0000:0000:85a3:0000:0000:ac1f:0801\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "2001::85a3:0:0:ac1f:801") + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("2001:0000:0000:85a3:0000:0000:ac1f:0000\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "2001::85a3:0:0:ac1f:0") + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("2001:0db8:0000:85a3:0200:0000:ac1f:0000\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "2001:db8:0:85a3:200:0:ac1f:0") + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("2001:0db8:0000:85a3:0200:0020:0000:0000\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "2001:db8:0:85a3:200:20::") + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("0000:0000:0000:0000:0000:0000:0000:0001\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "::1") + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("0000:0000:0000:0000:0000:0000:0000:0000\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "::") + + subnetcalcWindow.tabs["IPv6"].click() + ipaddrfieldTextField.click() + ipaddrfieldTextField.typeKey("a", modifierFlags:.command) + ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + ipaddrfieldTextField.typeText("0:0:0::\r") + XCTAssertEqual(subnetcalcWindow.staticTexts["ipv6addrtext"].value as! String, "::") + + //ipaddrfieldTextField.typeKey(.delete, modifierFlags:[]) + + //subnetcalcWindow.buttons["Calc"].click() + ipaddrfieldTextField.typeKey("q", modifierFlags:.command) + } + +} diff --git a/SubnetCalcUITests/SubnetCalcUITests.m b/SubnetCalcUITests/SubnetCalcUITests.m deleted file mode 100644 index 1721b48..0000000 --- a/SubnetCalcUITests/SubnetCalcUITests.m +++ /dev/null @@ -1,149 +0,0 @@ -// -// SubnetCalcUITests.m -// SubnetCalcUITests -// -// Created by Julien Mulot on 18/11/2020. -// - -#import - -@interface SubnetCalcUITests : XCTestCase - -@end - -@implementation SubnetCalcUITests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - self.continueAfterFailure = NO; - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testExample { - // UI tests must launch the application that they test. - XCUIApplication *app = [[XCUIApplication alloc] init]; - [app launch]; - - // Use recording to get started writing UI tests. - // Use XCTAssert and related functions to verify your tests produce the correct results. - - XCUIElement *subnetcalcWindow = [[XCUIApplication alloc] init].windows[@"SubnetCalc"]; - - XCUIElement *iptextfieldcellTextField = subnetcalcWindow.textFields[@"ipaddrfield"]; - [iptextfieldcellTextField click]; - [iptextfieldcellTextField typeText:@"10.32.2.52/30\r"]; - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"subnetbitscombo"] value], @"22"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maskbitscombo"] value], @"30"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"subnetmaskcombo"] value], @"255.255.255.252"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maxsubnetcombo"] value], @"4194304"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maxhostscombo"] value], @"2"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetrangetext"] value], @"10.32.2.53 - 10.32.2.54"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetidtext"] value], @"10.32.2.52"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetbroadcasttext"] value], @"10.32.2.55"); - [subnetcalcWindow.tabs[@"CIDR"] click]; - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaskbits"] value], @"30"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmask"] value], @"255.255.255.252"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxsubnets"] value], @"4"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxaddr"] value], @"2"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxsupernets"] value], @"1"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"cidrnetwork"] value], @"10.32.2.52"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"cidrrange"] value], @"10.32.2.52 - 10.32.2.55"); - [subnetcalcWindow.tabs[@"Address"] click]; - XCTAssertEqualObjects([subnetcalcWindow.popUpButtons[@"addrclasstypecell"] value], @"Class A : 1.0.0.0 - 126.255.255.255"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"classbitmap"] value], @"nnnnnnnn.ssssssss.ssssssss.sssssshh"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"binarymap"] value], @"00001010.00100000.00000010.00110100"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"hexamap"] value], @"0A.20.02.34"); - - [iptextfieldcellTextField click]; - [iptextfieldcellTextField doubleClick]; - [iptextfieldcellTextField typeText:@"192.168.254.129/12\r"]; - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"subnetbitscombo"] value], @"0"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maskbitscombo"] value], @"12"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"subnetmaskcombo"] value], @"255.240.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maxsubnetcombo"] value], @"1"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maxhostscombo"] value], @"1048574"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetrangetext"] value], @"192.160.0.1 - 192.175.255.254"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetidtext"] value], @"192.160.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetbroadcasttext"] value], @"192.175.255.255"); - [subnetcalcWindow.tabs[@"CIDR"] click]; - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaskbits"] value], @"12"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmask"] value], @"255.240.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxsubnets"] value], @"1048576"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxaddr"] value], @"1048574"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxsupernets"] value], @"4096"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"cidrnetwork"] value], @"192.160.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"cidrrange"] value], @"192.160.0.0 - 192.175.255.255"); - [subnetcalcWindow.tabs[@"Address"] click]; - XCTAssertEqualObjects([subnetcalcWindow.popUpButtons[@"addrclasstypecell"] value], @"Class C : 192.0.0.0 - 223.255.255.255"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"classbitmap"] value], @"nnnnnnnn.nnnnhhhh.hhhhhhhh.hhhhhhhh"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"binarymap"] value], @"11000000.10101000.11111110.10000001"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"hexamap"] value], @"C0.A8.FE.81"); - - [iptextfieldcellTextField click]; - [iptextfieldcellTextField doubleClick]; - [iptextfieldcellTextField typeText:@"172.16.242.132/8\r"]; - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"subnetbitscombo"] value], @"0"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maskbitscombo"] value], @"8"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"subnetmaskcombo"] value], @"255.0.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maxsubnetcombo"] value], @"1"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"maxhostscombo"] value], @"16777214"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetrangetext"] value], @"172.0.0.1 - 172.255.255.254"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetidtext"] value], @"172.0.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"subnetbroadcasttext"] value], @"172.255.255.255"); - [subnetcalcWindow.tabs[@"CIDR"] click]; - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaskbits"] value], @"8"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmask"] value], @"255.0.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxsubnets"] value], @"16777216"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxaddr"] value], @"16777214"); - XCTAssertEqualObjects([subnetcalcWindow.comboBoxes[@"cidrmaxsupernets"] value], @"256"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"cidrnetwork"] value], @"172.0.0.0"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"cidrrange"] value], @"172.0.0.0 - 172.255.255.255"); - [subnetcalcWindow.tabs[@"Address"] click]; - XCTAssertEqualObjects([subnetcalcWindow.popUpButtons[@"addrclasstypecell"] value], @"Class B : 128.0.0.0 - 191.255.255.255"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"classbitmap"] value], @"nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"binarymap"] value], @"10101100.00010000.11110010.10000100"); - XCTAssertEqualObjects([subnetcalcWindow.staticTexts[@"hexamap"] value], @"AC.10.F2.84"); - - - [[subnetcalcWindow childrenMatchingType:XCUIElementTypeMenuButton].element click]; - [subnetcalcWindow/*@START_MENU_TOKEN@*/.menuItems[@"exportClipboard:"]/*[[".menuButtons",".menus",".menuItems[@\"Export Clipboard\"]",".menuItems[@\"exportClipboard:\"]"],[[[-1,3],[-1,2],[-1,1,2],[-1,0,1]],[[-1,3],[-1,2],[-1,1,2]],[[-1,3],[-1,2]]],[0]]@END_MENU_TOKEN@*/ click]; - - NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; - NSString *pastecontent = [pasteboard stringForType: NSPasteboardTypeString]; - NSString *validcontent = @"Address Class Type: B\n\ -IP Address: 172.16.242.132\n\ -Subnet ID: 172.0.0.0\n\ -Subnet Mask: 255.0.0.0\n\ -Broadcast: 172.255.255.255\n\ -IP Range: 172.0.0.1 - 172.255.255.254\n\ -Mask Bits: 8\n\ -Subnet Bits: 0\n\ -Max Subnets: 1\n\ -Max Hosts / Subnet : 16777214\n\ -Address Hexa: AC.10.F2.84\n\ -BitMap: nnnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh\n\ -BinMap: 10101100.00010000.11110010.10000100\n"; - XCTAssertEqualObjects(pastecontent, validcontent); - - //XCTAssert([subnetcalcWindow.popUpButtons[@"addrclasstypecell"] exists]); - //[subnetcalcWindow/*@START_MENU_TOKEN@*/.tabs[@"Subnets"]/*[[".tabGroups.tabs[@\"Subnets\"]",".tabs[@\"Subnets\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/ click]; - [iptextfieldcellTextField typeKey:@"q" modifierFlags:XCUIKeyModifierCommand]; -} - -- (void)testLaunchPerformance { - if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { - // This measures how long it takes to launch your application. - [self measureWithMetrics:@[[[XCTApplicationLaunchMetric alloc] init]] block:^{ - [[[XCUIApplication alloc] init] launch]; - }]; - } -} - -@end diff --git a/SubnetCalc_Prefix.pch b/SubnetCalc_Prefix.pch deleted file mode 100644 index 60aacad..0000000 --- a/SubnetCalc_Prefix.pch +++ /dev/null @@ -1,7 +0,0 @@ -// -// Prefix header for all source files of the 'SubnetCalc' target in the 'SubnetCalc' project -// - -#ifdef __OBJC__ - #import -#endif diff --git a/main.m b/main.m deleted file mode 100644 index bd19ef2..0000000 --- a/main.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// main.m -// SubnetCalc -// -// Created by Julien Mulot on 04/01/11. -// Copyright 2011 mulot.net. All rights reserved. -// - -#import - -int main(int argc, char *argv[]) -{ - return NSApplicationMain(argc, (const char **) argv); -}