#include <CoreFoundation/CoreFoundation.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_fw.h>
#include <netinet6/ip6_fw.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
#define RULE_0 10
#define RULE_1 2000
#define RULE_2 2010
#define RULE_3 2020
#define RULE_4 2030
#define RULE_5 2040
#define RULE_6 2050
#define RULE_7 2060
#define RULE_8 12180
#define RULE_9 12190
#define ICMPECHOREQRULE 20000
#define RULE_D 65535
#define NUM_DEFAULT 9
#define UDPRULEDNS 20310
#define UDPRULEBOOTP 20320
#define UDPRULEBOOTSERVER 20321
#define UDPRULEMDNSRESPONSE 20322
#define UDPRULENTP 20330
#define UDPRULESMB 20340
#define UDPRULESRVLOC 20350
#define UDPRULEIPP 20360
#define UDPRULEMDNS 20370
#define UDPRPCRULESTART 20400
#define UDPUSERDEFINEDSTARTS 22000
#define UDPRULECHECKSTATE 30500
#define UDPRULEKEEPSTATE 30510
#define UDPRULEDEFAULTFRAG 30520
#define UDPRULEDEFAULTDENY 35000
#define DNSPORT 53
#define BOOTSERVERPORT 67
#define BOOTPCLIENTPPORT 68
#define RPCPORT 111
#define NTPPORT 123
#define SMBPORT 137
#define SRVLOCPORT 427
#define IPPPORT 631
#define MDNSPORT 5353
#define ARDPORT 3283
#define RSTPCLIENTPORT 6970 #6970-6980
#define kFirewallKey CFSTR("firewall")
#define kStateKey CFSTR("state")
#define kEnableKey CFSTR("enable")
#define kPortKey CFSTR("port")
#define kAllPortsKey CFSTR("allports")
#define kFirewallAppSignature CFSTR("com.apple.sharing.firewall")
#define kUDPEnableKey CFSTR("udpenabled")
#define kLogEnableKey CFSTR("loggingenabled")
#define kStealthEnableKey CFSTR("stealthenabled")
#define kUDPPortKey CFSTR("udpport")
#define RULE_START 2070
#define SUCCESS 0
#define ERROR 1
#define SIGNAL_FTP -1
#define kAppleRule 0
#define kOneRule -1
#define kThirdPartyRule -2
#define kError ERROR
#define LOGDEFAULTVALUE 0 // default value for logging when the key is missing
#define STEALTHDEFAULTVALUE 0 // default value for stealth mode when the key is missing
#define MAXDEFAULTUDPRULES 6 // needs to be updated whenever DEFAULTUDPSET changes
#define LOGGERPROGPATH "/usr/libexec/ipfwloggerd"
#define LOGGERPIDPATH "/var/run/ipfwlogger.pid"
typedef struct DEFAULTUDPRULETYPE {
int theport;
int therule;
} DEFAULTUDPRULETYPE;
typedef struct DEFAULTUDPRULESET{
DEFAULTUDPRULETYPE set[MAXDEFAULTUDPRULES];
}DEFAULTUDPRULESET;
struct DEFAULTUDPRULESET DEFAULTUDPSET={
{
{ DNSPORT , UDPRULEDNS},
{ BOOTPCLIENTPPORT , UDPRULEBOOTP},
{ SMBPORT , UDPRULESMB},
{ SRVLOCPORT , UDPRULESRVLOC},
{ IPPPORT , UDPRULEIPP},
{ MDNSPORT , UDPRULEMDNS}
}
};
int ReadFile(CFPropertyListRef *dictionaryRef, CFPropertyListRef *stateRef, Boolean *UDPenabled, Boolean *LOGGINGenabled, Boolean *STEALTHenabled);
int DoV4Firewall(CFPropertyListRef dictionaryRef, CFPropertyListRef stateRef, Boolean udpenabled, Boolean loggingenabled, Boolean stealthenabled);
int DoV6Firewall(CFPropertyListRef dictionaryRef, CFPropertyListRef stateRef, Boolean udpenabled, Boolean loggingenabled, Boolean stealthenabled);
int FlushOldRules(int controlSocket);
int FlushOldRulesV6(int controlSocket);
int WriteRulesToSockets(int controlSocket, CFPropertyListRef dictionaryRef, Boolean isV6, Boolean udpenabled, Boolean loggingenabled, Boolean stealthenabled);
int AddDefaultRules(int controlSocket, Boolean doUDP, Boolean loggingenabled, Boolean stealthenabled);
int AddDefaultRulesV6(int controlSocket, Boolean doUDP, Boolean loggingenabled, Boolean stealthenabled);
int AddDefaultRule1LoopBack(int controlSocket);
int AddDefaultRule1LoopBackV6(int controlSocket);
int AddDefaultRule2DiscardLoopbackIn(int controlSocket);
int AddDefaultRule2DiscardLoopbackInV6(int controlSocket);
int AddDefaultRule3DiscardLoopbackOut(int controlSocket);
int AddDefaultRule3DiscardLoopbackOutV6(int controlSocket);
int AddDefaultRule4DiscardBroadcastMulticast(int controlSocket);
int AddDefaultRule4DiscardBroadcastMulticastV6(int controlSocket);
int AddDefaultRule5DiscardTCPBroadcastMulticast(int controlSocket);
int AddDefaultRule5DiscardTCPBroadcastMulticastV6(int controlSocket);
int AddDefaultRule6OutboundOK(int controlSocket);
int AddDefaultRule6OutboundOKV6(int controlSocket);
int AddDefaultRule7KeepEstablished(int controlSocket);
int AddDefaultRule7KeepEstablishedV6(int controlSocket);
int AddDefaultRule9DenyTCP(int controlSocket, Boolean loggingenabled);
int AddDefaultRule9DenyTCPV6(int controlSocket, Boolean loggingenabled);
int AddDefaultUDPRULE(int controlSocket, int udpport, int rulenumber );
int AddDefaultUDPBootServer(int controlSocket );
int AddDefaultUDPMDNS( int controlSocket);
int AddDefaultUDPCheckState(int controlSocket);
int AddDefaultUDPKeepState(int controlSocket);
int AddDefaultUDPFRAG(int controlSocket );
int AddDefaultUDPDeny(int controlSocket, Boolean loggingenabled );
int AddDefaultUDPRPCRULE(int controlSocket, Boolean isV6 );
int AddDefaultUDPRULEV6(int controlSocket, int udpport, int rulenumber );
int AddDefaultUDPV6BootServer(int controlSocket );
int AddDefaultUDPCheckStateV6(int controlSocket);
int AddDefaultUDPKeepStateV6(int controlSocket);
int AddDefaultUDPFRAGV6(int controlSocket );
int AddDefaultUDPDenyV6(int controlSocket, Boolean loggingenabled );
int AddICMPRule( int controlSocket, Boolean loggingenabled );
int AddICMPRuleV6( int controlSocket, Boolean loggingenabled );
boolean_t checklist( long unsigned *udpportlist, long unsigned theport, int max );
int AddUserDefinedRule(int controlSocket, int ruleNumber, SInt32 start, SInt32 end, boolean_t useRange, boolean_t doUDP);
int AddUserDefinedRuleV6(int controlSocket, int ruleNumber, SInt32 start, SInt32 end, boolean_t useRange, boolean_t doUDP);
int WriteOutInternetSharingRule(int controlSocket, struct ip_fw *rule);
boolean_t isInternetSharingRunning(int controlSocket, struct ip_fw *rule);
boolean_t IsExpectedCFType(CFPropertyListRef variableInQuestion, CFTypeID expectedType);
int GetPortRange(CFStringRef portString, SInt32 *start, SInt32 *end, boolean_t *useRange);
void EnableLogging(boolean_t enable);
void EnableBlackHole(boolean_t enable);
void KillLogDaemon();
int DoCheckApplerules();
int SetFirewallRules();
int checkV4Firewall( CFBooleanRef state);
int checkV6Firewall( CFBooleanRef state);
int compareRulesToFile( struct ip_fw *rules, int numRules, int numExpected);
int compareV6RulesToFile( struct ip6_fw *rules, int numRules, int numExpected);
int UnblockPort( int controlSocket, CFDictionaryRef portDict, int *ruleNumber, Boolean isV6, Boolean doUDP );
int main(int argc, char *argv[])
{
int error = SUCCESS;
int c;
boolean_t checkapplerules = false;
while ((c = getopt(argc, argv, "a")) != EOF) {
switch (c) {
case 'a':
checkapplerules = true;
break;
default:
error = 99;
break;
}
}
if ( checkapplerules )
{
error = DoCheckApplerules();
exit( error );
}
else if ( error == 99 )
{
exit( 1 ); }
error = SetFirewallRules();
return error;
}
int DoCheckApplerules()
{
int returncode;
CFBooleanRef state = (CFBooleanRef)CFPreferencesCopyValue(
(CFStringRef)kStateKey,
(CFStringRef)kFirewallAppSignature,
(CFStringRef)kCFPreferencesAnyUser,
(CFStringRef)kCFPreferencesCurrentHost);
returncode = checkV4Firewall( state );
if ( returncode == kAppleRule )
{
returncode = checkV6Firewall( state );
}
return returncode;
}
int checkV4Firewall( CFBooleanRef state)
{
int returncode = kError;
struct ip_fw *rules = NULL;
int dataSize = 0;
int actualDataSize = 0;
int numRules = 0;
int controlSocket, i;
int iterations = 1;
int internetSharingRunning = false;
int numRulesExpected = 1;
int num = 0;
controlSocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if( controlSocket < 0 )
{
printf("Firewall Tool: Error opening socket!\n");
return kError;
}
do
{
dataSize = (sizeof(struct ip_fw) * 10) * iterations;
rules = (struct ip_fw *)realloc(rules, dataSize);
if (rules == NULL )
{
printf("Firewall Tool: Error getting rules! Realloc Failed!\n");
return kError;
}
rules->version = IP_FW_CURRENT_API_VERSION;
actualDataSize = dataSize;
i = getsockopt(controlSocket, IPPROTO_IP, IP_FW_GET, rules, &actualDataSize);
if( i < 0 )
{
printf("Firewall Tool: Error getting rules! Not written into structure...\n");
free(rules);
return kError;
}
iterations++;
}while( dataSize == actualDataSize );
numRules = actualDataSize/sizeof(struct ip_fw);
while (rules[num].fw_number < RULE_D)
num++;
num++;
if (num * sizeof (rules[0]) != actualDataSize) {
numRules = num;
}
internetSharingRunning = isInternetSharingRunning( controlSocket, rules);
if( internetSharingRunning )
numRulesExpected = 2;
if( state == NULL ) {
returncode = (numRules == 1 || numRules == numRulesExpected) ? kOneRule : kThirdPartyRule;
if( returncode == kThirdPartyRule )
printf("Firewall Tool: ThirdPartyRule NumRules != 1. State is not defined!\n");
}
else if( CFGetTypeID(state) != CFBooleanGetTypeID() )
{
returncode = (numRules == 1 || numRules == numRulesExpected) ? kOneRule : kError;
if( returncode == kError )
printf("Firewall Tool: Corrupted File! State is not of type Boolean!\n");
}
else if( state == kCFBooleanFalse ) {
returncode = (numRules == 1 || numRules == numRulesExpected) ? kAppleRule : kThirdPartyRule;
if( returncode == kThirdPartyRule )
printf("Firewall Tool: Apple Firewall is off, but there are %d rules in IP Firewall!\n", numRules);
}
else if( state == kCFBooleanTrue && (numRules == 1 || numRules == numRulesExpected) )
{
returncode = kOneRule; printf("Firewall Tool: Apple Firewall is on, but the rules aren't there!\n");
}
else {
returncode = compareRulesToFile( rules, numRules, numRulesExpected);
}
if( rules )
free(rules);
close(controlSocket);
return returncode;
}
int checkV6Firewall( CFBooleanRef state)
{
int returncode = kError;
struct ip6_fw *rules = NULL;
int dataSize = 0;
int actualDataSize = 0;
int numRules = 0;
int controlSocket, i;
int iterations = 1;
int numRulesExpected = 1;
controlSocket = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
if( controlSocket < 0 )
{
printf("Firewall: Error opening V6 socket!\n");
return kError;
}
do
{
dataSize = (sizeof(struct ip6_fw) * 10) * iterations;
rules = (struct ip6_fw *)realloc(rules, dataSize);
if (rules == NULL )
{
printf("Firewall: Error getting V6 rules! Realloc Failed!\n");
return kError;
}
rules->version = IPV6_FW_CURRENT_API_VERSION;
actualDataSize = dataSize;
i = getsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_GET, rules, &actualDataSize);
if( i < 0 )
{
printf("Firewall: Error getting V6 rules! Not written into structure...\n");
free(rules);
return kError;
}
iterations++;
}while( dataSize == actualDataSize );
numRules = actualDataSize/sizeof(struct ip6_fw);
if( state == NULL ) {
returncode = (numRules == 1 || numRules == numRulesExpected) ? kOneRule : kThirdPartyRule;
if( returncode == kThirdPartyRule )
printf("ThirdParty: NumRules V6 != 1. State is not defined!");
}
else if( CFGetTypeID(state) != CFBooleanGetTypeID() )
{
returncode = (numRules == 1 || numRules == numRulesExpected) ? kOneRule : kError;
if( returncode == kError )
printf("Corrupted File! State V6 is not of type Boolean!");
}
else if( state == kCFBooleanFalse ) {
returncode = (numRules == 1 || numRules == numRulesExpected) ? kAppleRule : kThirdPartyRule;
if( returncode == kThirdPartyRule )
printf("Apple Firewall is off, but there are %d rules in IP V6 Firewall!", numRules);
}
else if( state == kCFBooleanTrue && (numRules == 1 || numRules == numRulesExpected) )
{
returncode = kOneRule; printf("Apple Firewall is on, but the V6 rules aren't there!");
}
else {
returncode = compareV6RulesToFile( rules, numRules, numRulesExpected);
}
if( rules )
free(rules);
close(controlSocket);
return returncode;
}
int compareRulesToFile( struct ip_fw *rules, int numRules, int numExpected)
{
int returncode = kAppleRule;
int i;
#ifdef oldcode
int defaultRulesFound = 0;
#endif
int defaultExpected = NUM_DEFAULT;
boolean_t nonapple = false;
if( numExpected == 2 ) defaultExpected+=1;
CFPropertyListRef ports = CFPreferencesCopyValue(
(CFStringRef)kAllPortsKey,
(CFStringRef)kFirewallAppSignature,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
if( ports == NULL )
{
returncode = (numRules == 1 || numRules == numExpected ) ? kOneRule : kError;
if( returncode == kError )
printf("Firewall Tool: Corrupted File! No Port List defined!\n");
}
else if( CFGetTypeID(ports) != CFArrayGetTypeID() ) {
returncode = (numRules == 1 || numRules == numExpected ) ? kOneRule : kError;
if( returncode == kError )
printf("Firewall Tool: Corrupted File! Port List is not of type Array!\n");
}
for( i = 0; i < numRules; i++ )
{
int ruleNumber = rules[i].fw_number;
int signature = (int)rules[i].context;
if ( (signature != 'AAPL') && (ruleNumber != RULE_D))
{
if ((rules[i].fw_flg & IP_FW_F_COMMAND) == IP_FW_F_DIVERT)
{
continue;
}
nonapple = true;
break;
}
#ifdef oldcode
if( ruleNumber == RULE_1 || ruleNumber == RULE_2 || ruleNumber == RULE_3 ||
ruleNumber == RULE_4 || ruleNumber == RULE_5 || ruleNumber == RULE_6 ||
ruleNumber == RULE_7 || ruleNumber == RULE_9 ||
ruleNumber == RULE_D || ruleNumber == RULE_0)
{
defaultRulesFound++;
}else
{
if( (ruleNumber < RULE_1 || ruleNumber > RULE_9) && ruleNumber != RULE_D && ruleNumber != RULE_0 )
{
returnString = kThirdPartyString;
printf("Firewall: Non recognized rule: %d", ruleNumber);
break;
}
else {
NSString *portString = NULL;
int startVal = rules[i].fw_uar.fw_pts[0];
int endVal = rules[i].fw_uar.fw_pts[1];
if( !endVal )
{
portString = [NSString stringWithFormat: @"%d", startVal];
}
else
{
portString = [NSString stringWithFormat: @"%d-%d", startVal, endVal];
}
if( [(NSArray *)ports indexOfObject: portString] == NSNotFound )
{
returnString = kThirdPartyRule;
printf("Firewall: Non recognized rule: %d Port: %@", ruleNumber, portString);
break;
}
}
}#endif
}
#ifdef oldcode
if( defaultRulesFound != defaultExpected )
{
printf("Apple firewall is supposed to be on but we only found %d defaultRules!", defaultRulesFound);
returnString = kThirdPartyString;
}
#endif
if ( nonapple )
{
returncode = kThirdPartyRule;
}
if( ports != NULL )
CFRelease(ports);
return returncode;
}
int compareV6RulesToFile( struct ip6_fw *rules, int numRules, int numExpected)
{
int returncode = kAppleRule;
int i;
#ifdef oldcode
int defaultRulesFound = 0;
#endif
int defaultExpected = NUM_DEFAULT;
boolean_t nonapple = false;
if( numExpected == 2 ) defaultExpected+=1;
CFPropertyListRef ports = CFPreferencesCopyValue(
(CFStringRef)kAllPortsKey,
(CFStringRef)kFirewallAppSignature,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
if( ports == NULL )
{
returncode = (numRules == 1 || numRules == numExpected ) ? kOneRule : kError;
if( returncode == kError )
printf("Firewall Tool: Corrupted File! No V6 Port List defined!");
}
else if( CFGetTypeID(ports) != CFArrayGetTypeID() ) {
returncode = (numRules == 1 || numRules == numExpected ) ? kOneRule : kError;
if( returncode == kError )
printf("Firewall Tool: Corrupted File! V6 Port List is not of type Array!");
}
for( i = 0; i < numRules; i++ )
{
int ruleNumber = rules[i].fw_number;
int signature = (int)rules[i].context;
if ( (signature != 'AAPL') && (ruleNumber != RULE_D))
{
if ((rules[i].fw_flg & IP_FW_F_COMMAND) == IP_FW_F_DIVERT)
{
continue;
}
nonapple = true;
break;
}
#ifdef oldcode
if( ruleNumber == RULE_1 || ruleNumber == RULE_2 || ruleNumber == RULE_3 ||
ruleNumber == RULE_4 || ruleNumber == RULE_5 || ruleNumber == RULE_6 ||
ruleNumber == RULE_7 || ruleNumber == RULE_9 ||
ruleNumber == RULE_D || ruleNumber == RULE_0)
{
defaultRulesFound++;
}else
{
if( (ruleNumber < RULE_1 || ruleNumber > RULE_9) && ruleNumber != RULE_D && ruleNumber != RULE_0 )
{
returncode = kThirdPartyRule;
printf("Firewall: Non recognized rule: %d", ruleNumber);
break;
}
else {
NSString *portString = NULL;
int startVal = rules[i].fw_pts[0];
int endVal = rules[i].fw_pts[1];
if( !endVal )
{
portString = [NSString stringWithFormat: @"%d", startVal];
}
else
{
portString = [NSString stringWithFormat: @"%d-%d", startVal, endVal];
}
if( [(NSArray *)ports indexOfObject: portString] == NSNotFound )
{
returncode = kThirdPartyRule;
printf("Firewall: Non recognized rule: %d Port: %@", ruleNumber, portString);
break;
}
}
}#endif
}
#ifdef oldcode
if( defaultRulesFound != defaultExpected )
{
printf("Apple firewall is supposed to be on but we only found %d defaultRules!", defaultRulesFound);
returncode = kThirdPartyRule;
}
#endif
if ( nonapple )
{
returncode = kThirdPartyRule;
}
if( ports != NULL )
CFRelease(ports);
return returncode;
}
void KillLogDaemon()
{
pid_t pid;
FILE *fp;
fp = fopen(LOGGERPIDPATH, "r");
if (fp != NULL) {
fscanf(fp, "%d", &pid);
fclose(fp);
if ( kill( pid, SIGKILL ))
printf("cannot kill logger daemon pid %d errno = %d\n", (int)pid, errno);
unlink( LOGGERPIDPATH );
}
}
int SetFirewallRules()
{
CFPropertyListRef dictionaryRef = NULL;
CFPropertyListRef stateRef = NULL;
int error = SUCCESS;
Boolean udpenabled;
Boolean loggingenabled;
Boolean stealthenabled;
char *argv[2];
struct stat sb;
do
{
error = ReadFile(&dictionaryRef, &stateRef, &udpenabled, &loggingenabled, &stealthenabled );
if( error != SUCCESS )
{
printf("Firewall Tool: Error, Error reading in file!\n");
break;
}
if ( stateRef == kCFBooleanTrue )
{
EnableBlackHole( stealthenabled );
EnableLogging( loggingenabled );
if( loggingenabled )
{
pid_t pid;
if ( stat(LOGGERPIDPATH, &sb) )
{
if (errno == ENOENT)
{
pid = fork();
switch (pid) {
case -1 : {
printf("fork() failed, cannot start up logger daemon %d\n", errno);
break;
}
case 0: {
argv[0]=LOGGERPROGPATH;
argv[1]=NULL;
(void)execv( LOGGERPROGPATH, argv);
printf("child::execv failed, cannot start up logger daemon errno = %d\n", errno);
exit(1);
}
default:
waitpid( pid, NULL, 0);
break;
}
}
}
}else
KillLogDaemon();
}else
{
EnableLogging( false );
EnableBlackHole( false );
stealthenabled = false;
KillLogDaemon();
}
error = DoV4Firewall(dictionaryRef, stateRef, udpenabled, loggingenabled, stealthenabled);
if( error != SUCCESS )
{
printf("Firewall Tool: Error %d, Error setting up V4 Firewall!\n", error);
}
error = DoV6Firewall(dictionaryRef, stateRef, udpenabled, loggingenabled, stealthenabled);
if( error != SUCCESS )
{
printf("Firewall Tool: Error %d, Error setting up V6 Firewall!\n", error);
}
}while(false);
if( dictionaryRef )
CFRelease(dictionaryRef);
if( stateRef )
CFRelease(stateRef);
return error;
}
int DoV4Firewall(CFPropertyListRef dictionaryRef, CFPropertyListRef stateRef, Boolean udpenabled, Boolean loggingenabled, Boolean stealthenabled)
{
int controlSocket;
int error = SUCCESS;
boolean_t internetSharingOn = false;
struct ip_fw rule;
do
{
controlSocket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if( controlSocket < 0 )
{
printf("Firewall Tool: Error opening socket\n");
error = ERROR;
break;
}
memset(&rule, 0, sizeof(rule));
internetSharingOn = isInternetSharingRunning( controlSocket, &rule);
error = FlushOldRules(controlSocket);
if( error != SUCCESS )
{
printf("Firewall Tool: Error Flusing Old Rules!\n");
break;
}
if( internetSharingOn )
error = WriteOutInternetSharingRule(controlSocket, &rule);
if( stateRef == kCFBooleanTrue )
error = WriteRulesToSockets(controlSocket, dictionaryRef, false, udpenabled, loggingenabled, stealthenabled);
if( error != SUCCESS )
{
printf("Firewall Tool: Error writing out rules! Attempting to Flush...\n");
FlushOldRules(controlSocket); break;
}
}while(false);
if( controlSocket >= 0 )
close(controlSocket);
return error;
}
int DoV6Firewall(CFPropertyListRef dictionaryRef, CFPropertyListRef stateRef, Boolean udpenabled, Boolean loggingenabled, Boolean stealthenabled)
{
int controlSocket;
int error = SUCCESS;
do
{
controlSocket = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
if( controlSocket < 0 )
{
printf("Firewall Tool: Error opening socket for V6!\n");
error = ERROR;
break;
}
error = FlushOldRulesV6(controlSocket);
if( error != SUCCESS )
{
printf("Firewall Tool: Error Flusing Old V6 Rules!\n");
break;
}
if( stateRef == kCFBooleanTrue )
error = WriteRulesToSockets(controlSocket, dictionaryRef, true, udpenabled, loggingenabled, stealthenabled);
if( error != SUCCESS )
{
printf("Firewall Tool: Error writing out V6 rules! Attempting to Flush...\n");
FlushOldRulesV6(controlSocket); break;
}
}while(false);
if( controlSocket >= 0 )
close(controlSocket);
return error;
}
int FlushOldRules(int controlSocket)
{
int i;
struct ip_fw rule;
rule.version = IP_FW_CURRENT_API_VERSION;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_FLUSH, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error flushing rules\n");
return ERROR;
}
return SUCCESS;
}
int FlushOldRulesV6(int controlSocket)
{
int i;
struct ip6_fw rule;
rule.version = IPV6_FW_CURRENT_API_VERSION;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_FLUSH, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error flushing rules (V6) \n");
return ERROR;
}
return SUCCESS;
}
int ReadFile(CFPropertyListRef *dictionaryRef, CFPropertyListRef *stateRef, Boolean *UDPenabled, Boolean *LOGGINGenabled, Boolean *STEALTHenabled )
{
CFPropertyListRef udpenabledRef, logenabledRef, stealthenabledRef;
int value;
*dictionaryRef = NULL;
*stateRef = NULL;
logenabledRef = NULL;
udpenabledRef = NULL;
stealthenabledRef = NULL;
*UDPenabled = false; *LOGGINGenabled = LOGDEFAULTVALUE; *STEALTHenabled = STEALTHDEFAULTVALUE;
*dictionaryRef = CFPreferencesCopyValue( kFirewallKey,
kFirewallAppSignature,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
if( !IsExpectedCFType(*dictionaryRef, CFDictionaryGetTypeID()) )
{
printf("Firewall Tool: Error, kFirewallKey does not return a CFDictionary\n");
return ERROR;
}
*stateRef = CFPreferencesCopyValue( kStateKey,
kFirewallAppSignature,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
if( !IsExpectedCFType(*stateRef, CFBooleanGetTypeID()) )
{
printf("Firewall Tool: Error, kStateKey does not return a CFBoolean\n");
return ERROR;
}
logenabledRef = CFPreferencesCopyValue( kLogEnableKey,
kFirewallAppSignature,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
if ( logenabledRef != NULL )
{
if( !IsExpectedCFType( logenabledRef, CFNumberGetTypeID()) )
{
printf("Firewall Tool: Error, logenabledRef does not return the correct type.\n");
return ERROR;
}
if( !CFNumberGetValue((CFNumberRef)logenabledRef, kCFNumberIntType, &value) )
{
printf("Firewall Tool: Error, could not convert CFNumber to LOGGINGenabled value\n");
}
else if ( value == 0 )
*LOGGINGenabled = false;
else if ( value == 1 )
*LOGGINGenabled = true;
CFRelease(logenabledRef);
}
stealthenabledRef = CFPreferencesCopyValue( kStealthEnableKey,
kFirewallAppSignature,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
if ( stealthenabledRef != NULL )
{
if( !IsExpectedCFType( stealthenabledRef, CFNumberGetTypeID()) )
{
printf("Firewall Tool: Error, stealthenabledRef does not return the correct type.\n");
return ERROR;
}
if( !CFNumberGetValue((CFNumberRef)stealthenabledRef, kCFNumberIntType, &value) )
{
printf("Firewall Tool: Error, could not convert CFNumber to STEALTHenabled value\n");
}
else if ( value == 0 )
*STEALTHenabled = false;
else if ( value == 1 )
*STEALTHenabled = true;
CFRelease(stealthenabledRef);
}
udpenabledRef = CFPreferencesCopyValue( kUDPEnableKey,
kFirewallAppSignature,
kCFPreferencesAnyUser,
kCFPreferencesCurrentHost);
if ( udpenabledRef != NULL )
{
if( !IsExpectedCFType( udpenabledRef, CFNumberGetTypeID()) )
{
printf("Firewall Tool: Error, udpenabledRef does not return the correct type.\n");
return ERROR;
}
if( !CFNumberGetValue((CFNumberRef)udpenabledRef, kCFNumberIntType, &value) )
{
printf("Firewall Tool: Error, could not convert CFNumber to UDPenabled value\n");
}
else if ( value == 1 )
*UDPenabled = true;
CFRelease(udpenabledRef);
}
return SUCCESS;
}
int UnblockPort( int controlSocket, CFDictionaryRef portDict, int *ruleNumber, Boolean isV6, Boolean doUDP )
{
CFPropertyListRef arrayOfPorts = NULL;
CFPropertyListRef portString = NULL;
SInt32 start, end;
boolean_t useRange;
int j, portCount = 0;
if ( doUDP )
arrayOfPorts = CFDictionaryGetValue(portDict, kUDPPortKey);
else
arrayOfPorts = CFDictionaryGetValue(portDict, kPortKey);
if ( arrayOfPorts == NULL ) return SUCCESS;
if( !IsExpectedCFType(arrayOfPorts, CFArrayGetTypeID()) )
{
printf("Firewall Tool: Error, kPortKey did not return a CFArray\n");
return ERROR;
}
if( arrayOfPorts )
portCount = CFArrayGetCount((CFArrayRef)arrayOfPorts);
for( j = 0; j < portCount; j++)
{
portString = CFArrayGetValueAtIndex((CFArrayRef)arrayOfPorts, j);
if( !IsExpectedCFType(portString, CFStringGetTypeID()) )
{
printf("Firewall Tool: Error, port array did not return a CFString value\n");
return ERROR;
}
if( GetPortRange((CFStringRef)portString, &start, &end, &useRange) == SUCCESS )
{
if( !isV6 ) {
if( AddUserDefinedRule(controlSocket, *ruleNumber, start, end, useRange, doUDP) != SUCCESS)
{
printf("Firewall Tool: Error, could not add user defined rule!\n");
return ERROR;
}
}
else {
if( AddUserDefinedRuleV6(controlSocket, *ruleNumber, start, end, useRange, doUDP) != SUCCESS)
{
printf("Firewall Tool: Error, could not add user defined rule!\n");
return ERROR;
}
}
*ruleNumber+=10;
}
portString = NULL;
}
return SUCCESS;
}
int WriteRulesToSockets(int controlSocket, CFPropertyListRef dictionaryRef, Boolean isV6, Boolean udpenabled, Boolean loggingenabled, Boolean stealthenabled)
{
int i;
CFIndex count = 0;
CFDictionaryRef *values = NULL;
int error;
int ruleNumber = RULE_START;
int udpruleNumber = UDPUSERDEFINEDSTARTS;
if( !isV6 )
error = AddDefaultRules(controlSocket, udpenabled, loggingenabled, stealthenabled);
else
error = AddDefaultRulesV6(controlSocket, udpenabled, loggingenabled, stealthenabled);
if( error != SUCCESS )
{
printf("Firewall Tool: Error adding default rules!\n");
return ERROR;
}
if( dictionaryRef ) count = CFDictionaryGetCount(dictionaryRef);
if( count > 0 )
{
values = CFAllocatorAllocate(NULL, count * sizeof(CFDictionaryRef), 0);
if( values == NULL )
{
printf("Firewall Tool: CFAllocatorAllocate failed!\n");
return ERROR;
}
else
{
CFDictionaryGetKeysAndValues(dictionaryRef, NULL, (const void **)values);
}
}
for( i = 0; i < count; i++)
{
CFDictionaryRef portDict = values[i];
CFPropertyListRef enabled;
int value;
enabled = CFDictionaryGetValue(portDict, kEnableKey);
if( !IsExpectedCFType(enabled, CFNumberGetTypeID()) )
{
printf("Firewall Tool: Error, kEnableKey did not return a CFNumber\n");
CFAllocatorDeallocate(NULL, values);
return ERROR;
}
if( !CFNumberGetValue((CFNumberRef)enabled, kCFNumberIntType, &value) )
{
printf("Firewall Tool: Error, could not convert CFNumber to enabled value\n");
CFAllocatorDeallocate(NULL, values);
return ERROR;
}
if ( value )
{
if ( UnblockPort( controlSocket, portDict, &ruleNumber, isV6, false )) {
CFAllocatorDeallocate(NULL, values);
return ERROR;
}
if ( udpenabled )
{
if ( UnblockPort( controlSocket, portDict, &udpruleNumber, isV6, true )) {
CFAllocatorDeallocate(NULL, values);
return ERROR;
}
}
}
}
CFAllocatorDeallocate(NULL, values);
return SUCCESS;
}
int AddDefaultRules(int controlSocket, Boolean doUDP, Boolean loggingenabled, Boolean stealthenabled)
{
int error = SUCCESS;
int i;
do
{
error = AddDefaultRule1LoopBack(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule2DiscardLoopbackIn(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule3DiscardLoopbackOut(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule4DiscardBroadcastMulticast(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule5DiscardTCPBroadcastMulticast(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule6OutboundOK(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule7KeepEstablished(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule9DenyTCP(controlSocket, loggingenabled);
if( error != SUCCESS ) break;
if ( stealthenabled )
{
error = AddICMPRule( controlSocket, loggingenabled );
if( error != SUCCESS ) break;
}
if ( doUDP )
{
for ( i= 0; i < MAXDEFAULTUDPRULES; i++ ){
error = AddDefaultUDPRULE( controlSocket, DEFAULTUDPSET.set[i].theport, DEFAULTUDPSET.set[i].therule);
if ( error != SUCCESS ) break;
}
error = AddDefaultUDPBootServer( controlSocket);
if ( error != SUCCESS ) break;
error = AddDefaultUDPMDNS( controlSocket);
if ( error != SUCCESS ) break;
error = AddDefaultUDPKeepState( controlSocket);
if ( error != SUCCESS ) break;
error = AddDefaultUDPFRAG( controlSocket );
if ( error != SUCCESS ) break;
#ifdef doRPC
error = AddDefaultUDPRPCRULE( controlSocket, false);
if ( error != SUCCESS ) break;
#endif
error = AddDefaultUDPDeny( controlSocket, loggingenabled );
if ( error != SUCCESS ) break;
}
}while(false);
return error;
}
int AddDefaultRulesV6(int controlSocket, Boolean doUDP, Boolean loggingenabled, Boolean stealthenabled)
{
int error = SUCCESS;
int i;
do
{
error = AddDefaultRule1LoopBackV6(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule2DiscardLoopbackInV6(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule3DiscardLoopbackOutV6(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule4DiscardBroadcastMulticastV6(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule5DiscardTCPBroadcastMulticastV6(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule6OutboundOKV6(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule7KeepEstablishedV6(controlSocket);
if( error != SUCCESS ) break;
error = AddDefaultRule9DenyTCPV6(controlSocket, loggingenabled);
if( error != SUCCESS ) break;
if ( stealthenabled )
{
error = AddICMPRuleV6( controlSocket, loggingenabled );
if( error != SUCCESS ) break;
}
if ( doUDP )
{
for ( i= 0; i < MAXDEFAULTUDPRULES; i++ ){
error = AddDefaultUDPRULEV6( controlSocket, DEFAULTUDPSET.set[i].theport, DEFAULTUDPSET.set[i].therule);
if ( error != SUCCESS ) break;
}
#ifdef later
error = AddDefaultUDPV6BootServer( controlSocket);
if ( error != SUCCESS ) break;
error = AddDefaultUDPCheckStateV6( controlSocket);
if ( error != SUCCESS ) break;
error = AddDefaultUDPKeepStateV6( controlSocket);
if ( error != SUCCESS ) break;
#endif
error = AddDefaultUDPFRAGV6( controlSocket );
if ( error != SUCCESS ) break;
#ifdef doRPC
error = AddDefaultUDPRPCRULE( controlSocket, true );
if ( error != SUCCESS ) break;
#endif
error = AddDefaultUDPDenyV6( controlSocket, loggingenabled );
if ( error != SUCCESS ) break;
}
}while(false);
return error;
}
int AddDefaultRule1LoopBack(int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = RULE_1; rule.fw_flg |= IP_FW_F_ACCEPT; rule.fw_prot = IPPROTO_IP;
strcpy(rule.fw_in_if.fu_via_if.name, "lo"); rule.fw_in_if.fu_via_if.unit = -1;
strcpy(rule.fw_out_if.fu_via_if.name, "lo");
rule.fw_out_if.fu_via_if.unit = -1;
rule.fw_flg |= (IP_FW_F_IIFACE | IP_FW_F_OIFACE); rule.fw_flg |= (IP_FW_F_IIFNAME | IP_FW_F_OIFNAME); rule.fw_flg |= (IP_FW_F_OUT | IP_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_1);
return i;
}
return SUCCESS;
}
int AddDefaultRule1LoopBackV6(int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_1; rule.fw_flg |= IPV6_FW_F_ACCEPT; rule.fw_prot = IPPROTO_IPV6;
strcpy(rule.fw_in_if.fu_via_if.name, "lo"); rule.fw_in_if.fu_via_if.unit = -1;
strcpy(rule.fw_out_if.fu_via_if.name, "lo");
rule.fw_out_if.fu_via_if.unit = -1;
rule.fw_flg |= (IPV6_FW_F_IIFACE | IPV6_FW_F_OIFACE); rule.fw_flg |= (IPV6_FW_F_IIFNAME | IPV6_FW_F_OIFNAME); rule.fw_flg |= (IPV6_FW_F_OUT | IPV6_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding V6 rule: %d\n", RULE_1);
return i;
}
return SUCCESS;
}
int AddDefaultRule2DiscardLoopbackIn(int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_2; rule.fw_flg |= IP_FW_F_DENY; rule.fw_prot = IPPROTO_IP;
rule.fw_src.s_addr = htonl(0x7F000000); rule.fw_smsk.s_addr = htonl(0xFF000000);
rule.fw_flg |= IP_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_2);
return i;
}
return SUCCESS;
}
int AddDefaultRule2DiscardLoopbackInV6(int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_2; rule.fw_flg |= IPV6_FW_F_DENY; rule.fw_prot = IPPROTO_IPV6;
rule.fw_src.__u6_addr.__u6_addr8[0] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[1] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[2] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[3] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[4] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[5] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[6] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[7] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[8] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[9] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[10] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[11] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[12] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[13] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[14] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[15] = 0x01;
rule.fw_smsk.__u6_addr.__u6_addr8[0] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[1] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[2] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[3] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[4] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[5] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[6] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[7] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[8] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[9] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[10] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[11] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[12] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[13] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[14] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[15] = 0xFF;
rule.fw_flg |= IPV6_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_2);
return i;
}
return SUCCESS;
}
int AddDefaultRule3DiscardLoopbackOut(int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = RULE_3; rule.fw_flg |= IP_FW_F_DENY; rule.fw_prot = IPPROTO_IP;
rule.fw_dst.s_addr = htonl(0x7F000000); rule.fw_dmsk.s_addr = htonl(0xFF000000);
rule.fw_flg |= IP_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_3);
return i;
}
return SUCCESS;
}
int AddDefaultRule3DiscardLoopbackOutV6(int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_3; rule.fw_flg |= IPV6_FW_F_DENY; rule.fw_prot = IPPROTO_IPV6;
rule.fw_dst.__u6_addr.__u6_addr8[0] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[1] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[2] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[3] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[4] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[5] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[6] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[7] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[8] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[9] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[10] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[11] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[12] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[13] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[14] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[15] = 0x01;
rule.fw_dmsk.__u6_addr.__u6_addr8[0] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[1] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[2] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[3] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[4] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[5] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[6] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[7] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[8] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[9] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[10] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[11] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[12] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[13] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[14] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[15] = 0xFF;
rule.fw_flg |= IPV6_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_3);
return i;
}
return SUCCESS;
}
int AddDefaultRule4DiscardBroadcastMulticast(int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = RULE_4; rule.fw_flg |= IP_FW_F_DENY; rule.fw_prot = IPPROTO_IP;
rule.fw_src.s_addr = htonl(0xE0000000); rule.fw_smsk.s_addr = htonl(0xE0000000);
rule.fw_flg |= IP_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_4);
return i;
}
return SUCCESS;
}
int AddDefaultRule4DiscardBroadcastMulticastV6(int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_4; rule.fw_flg |= IPV6_FW_F_DENY; rule.fw_prot = IPPROTO_IPV6;
rule.fw_src.__u6_addr.__u6_addr8[0] = 0xFF;
rule.fw_src.__u6_addr.__u6_addr8[1] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[2] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[3] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[4] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[5] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[6] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[7] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[8] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[9] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[10] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[11] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[12] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[13] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[14] = 0x00;
rule.fw_src.__u6_addr.__u6_addr8[15] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[0] = 0xFF;
rule.fw_smsk.__u6_addr.__u6_addr8[1] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[2] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[3] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[4] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[5] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[6] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[7] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[8] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[9] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[10] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[11] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[12] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[13] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[14] = 0x00;
rule.fw_smsk.__u6_addr.__u6_addr8[15] = 0x00;
rule.fw_flg |= IPV6_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_4);
return i;
}
return SUCCESS;
}
int AddDefaultRule5DiscardTCPBroadcastMulticast(int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = RULE_5; rule.fw_flg |= IP_FW_F_DENY; rule.fw_prot = IPPROTO_TCP;
rule.fw_dst.s_addr = htonl(0xE0000000); rule.fw_dmsk.s_addr = htonl(0xE0000000);
rule.fw_flg |= IP_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_5);
return i;
}
return SUCCESS;
}
int AddDefaultRule5DiscardTCPBroadcastMulticastV6(int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_5; rule.fw_flg |= IPV6_FW_F_DENY; rule.fw_prot = IPPROTO_TCP;
rule.fw_dst.__u6_addr.__u6_addr8[0] = 0xFF;
rule.fw_dst.__u6_addr.__u6_addr8[1] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[2] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[3] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[4] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[5] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[6] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[7] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[8] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[9] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[10] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[11] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[12] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[13] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[14] = 0x00;
rule.fw_dst.__u6_addr.__u6_addr8[15] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[0] = 0xFF;
rule.fw_dmsk.__u6_addr.__u6_addr8[1] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[2] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[3] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[4] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[5] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[6] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[7] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[8] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[9] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[10] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[11] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[12] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[13] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[14] = 0x00;
rule.fw_dmsk.__u6_addr.__u6_addr8[15] = 0x00;
rule.fw_flg |= IPV6_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_5);
return i;
}
return SUCCESS;
}
int AddDefaultRule6OutboundOK(int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_6; rule.fw_flg |= IP_FW_F_ACCEPT; rule.fw_prot = IPPROTO_TCP;
rule.fw_flg |= IP_FW_F_OUT;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_6);
return i;
}
return SUCCESS;
}
int AddDefaultRule6OutboundOKV6(int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_6; rule.fw_flg |= IPV6_FW_F_ACCEPT; rule.fw_prot = IPPROTO_TCP;
rule.fw_flg |= IPV6_FW_F_OUT;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding V6 rule: %d\n", RULE_6);
return i;
}
return SUCCESS;
}
int AddDefaultRule7KeepEstablished(int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = RULE_7; rule.fw_flg |= IP_FW_F_ACCEPT; rule.fw_prot = IPPROTO_TCP;
#ifdef IP_FW_IF_TCPEST
rule.fw_ipflg = IP_FW_IF_TCPEST; #endif
rule.fw_flg |= (IP_FW_F_OUT | IP_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_7);
return i;
}
return SUCCESS;
}
int AddDefaultRule7KeepEstablishedV6(int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION;
rule.context = (void*)'AAPL';
rule.fw_number = RULE_7; rule.fw_flg |= IPV6_FW_F_ACCEPT; rule.fw_prot = IPPROTO_TCP;
rule.fw_ipflg = IPV6_FW_IF_TCPEST;
rule.fw_flg |= (IPV6_FW_F_OUT | IPV6_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding V6 rule: %d\n", RULE_7);
return i;
}
return SUCCESS;
}
int AddDefaultRule9DenyTCP(int controlSocket, Boolean loggingenabled)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = RULE_9; rule.fw_flg |= IP_FW_F_DENY; if ( loggingenabled )
rule.fw_flg |= IP_FW_F_PRN; rule.fw_prot = IPPROTO_TCP;
rule.fw_flg |= (IP_FW_F_OUT | IP_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_9);
return i;
}
return SUCCESS;
}
int AddDefaultRule9DenyTCPV6(int controlSocket, Boolean loggingenabled)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = RULE_9; rule.fw_flg |= IPV6_FW_F_DENY; if ( loggingenabled )
rule.fw_flg |= IPV6_FW_F_PRN; rule.fw_prot = IPPROTO_TCP;
rule.fw_flg |= (IPV6_FW_F_OUT | IPV6_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding V6 rule: %d\n", RULE_9);
return i;
}
return SUCCESS;
}
int AddDefaultUDPRULE(int controlSocket, int udpport, int rulenumber )
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = rulenumber;
rule.fw_flg |= IP_FW_F_ACCEPT;
rule.fw_prot = IPPROTO_UDP;
rule.fw_uar.fw_pts[0] = udpport;
IP_FW_SETNDSTP(&rule, 1);
rule.fw_flg |= IP_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", rulenumber, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPBootServer( int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEBOOTSERVER; rule.fw_flg |= IP_FW_F_ACCEPT; rule.fw_prot = IPPROTO_UDP; rule.fw_uar.fw_pts[0] = BOOTSERVERPORT;
IP_FW_SETNSRCP(&rule, 1);
rule.fw_flg |= (IP_FW_F_DME | IP_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEBOOTSERVER, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPMDNS( int controlSocket)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEMDNSRESPONSE; rule.fw_flg |= IP_FW_F_ACCEPT; rule.fw_prot = IPPROTO_UDP; rule.fw_uar.fw_pts[0] = MDNSPORT;
IP_FW_SETNSRCP(&rule, 1);
rule.fw_flg |= (IP_FW_F_DME | IP_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEMDNSRESPONSE, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPCheckState(int controlSocket )
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULECHECKSTATE; rule.fw_flg |= (IP_FW_F_CHECK_S | IP_FW_F_ACCEPT); rule.fw_prot = IPPROTO_UDP;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULECHECKSTATE, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPKeepState(int controlSocket )
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEKEEPSTATE; rule.fw_flg |= (IP_FW_F_KEEP_S | IP_FW_F_ACCEPT); rule.fw_prot = IPPROTO_UDP;
rule.fw_flg |= (IP_FW_F_SME | IP_FW_F_OUT);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEKEEPSTATE, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPFRAG(int controlSocket )
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEDEFAULTFRAG; rule.fw_flg |= IP_FW_F_ACCEPT; rule.fw_prot = IPPROTO_UDP;
rule.fw_flg |= (IP_FW_F_IN | IP_FW_F_FRAG);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEDEFAULTFRAG, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPDeny(int controlSocket, Boolean loggingenabled )
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEDEFAULTDENY; rule.fw_flg |= IP_FW_F_DENY; if (loggingenabled)
rule.fw_flg |= IP_FW_F_PRN; rule.fw_prot = IPPROTO_UDP;
rule.fw_flg |= IP_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEDEFAULTDENY, errno);
return i;
}
return SUCCESS;
}
boolean_t checklist( long unsigned *udpportlist, long unsigned theport, int max )
{
int i;
for ( i=0; i<max; i++)
{
if ( *udpportlist++ == theport)
return false;
}
return true;
}
int AddDefaultUDPRPCRULE(int controlSocket, Boolean isV6 )
{
#define MAXRPCUDPPORT 80
int i;
struct sockaddr_in server_addr;
struct pmaplist *head = NULL;
unsigned long udpportlist[MAXRPCUDPPORT];
int index=0;
int error = SUCCESS;
bzero((char *)&server_addr, sizeof server_addr);
server_addr.sin_family = AF_INET;
*( (u_int32_t*)&server_addr.sin_addr) = INADDR_LOOPBACK;
server_addr.sin_len = sizeof( u_int32_t );
server_addr.sin_port = htons(PMAPPORT);
head = pmap_getmaps( &server_addr);
for (; head != NULL; head = head->pml_next) {
if (head->pml_map.pm_prot == IPPROTO_UDP)
{
if ( checklist( udpportlist, head->pml_map.pm_port, index ))
{
udpportlist[index++] = head->pml_map.pm_port;
}
}
}
if ( isV6 )
{
for ( i = 0; i < index; i++){
error = AddDefaultUDPRULEV6( controlSocket, udpportlist[i], UDPRPCRULESTART+i);
if ( error != SUCCESS ) break;
}
}
else
{
for ( i = 0; i < index; i++){
error = AddDefaultUDPRULE( controlSocket, udpportlist[i], UDPRPCRULESTART+i);
if ( error != SUCCESS ) break;
}
}
return error;
}
int AddICMPRule( int controlSocket, Boolean loggingenabled)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = ICMPECHOREQRULE; rule.fw_flg |= IP_FW_F_DENY; if ( loggingenabled )
rule.fw_flg |= IP_FW_F_PRN; rule.fw_prot = IPPROTO_ICMP;
rule.fw_uar.fw_icmptypes[ICMP_ECHO / (sizeof(unsigned) * 8)] |=
1 << (ICMP_ECHO % (sizeof(unsigned) * 8));
rule.fw_flg |= IP_FW_F_ICMPBIT; rule.fw_flg |= (IP_FW_F_IN | IP_FW_F_DME);
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", RULE_9);
return i;
}
return SUCCESS;
}
int AddDefaultUDPRULEV6(int controlSocket, int udpport, int rulenumber )
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = rulenumber;
rule.fw_flg |= IPV6_FW_F_ACCEPT;
rule.fw_prot = IPPROTO_UDP;
rule.fw_pts[0] = udpport;
IPV6_FW_SETNDSTP(&rule, 1);
rule.fw_flg |= IPV6_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", rulenumber, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPV6BootServer( int controlSocket)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEBOOTSERVER; rule.fw_flg |= IPV6_FW_F_ACCEPT; rule.fw_prot = IPPROTO_UDP; rule.fw_pts[0] = BOOTSERVERPORT;
IPV6_FW_SETNSRCP(&rule, 1);
rule.fw_flg |= ( IPV6_FW_F_IN);
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEBOOTSERVER, errno);
return i;
}
return SUCCESS;
}
#ifdef later
int AddDefaultUDPCheckStateV6(int controlSocket )
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULECHECKSTATE;
rule.fw_flg |= (IPV6_FW_F_CHECK_S | IPV6_FW_F_ACCEPT); rule.fw_prot = IPPROTO_UDP;
i = setsockopt(controlSocket, IPPROTO_IPV6, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULECHECKSTATE, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPKeepStateV6(int controlSocket )
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEKEEPSTATE;
rule.fw_flg |= (IPV6_FW_F_KEEP_S | IPV6_FW_F_ACCEPT); rule.fw_prot = IPPROTO_UDP;
rule.fw_flg |= (IPV6_FW_F_SME | IPV6_FW_F_OUT);
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEKEEPSTATE, errno);
return i;
}
return SUCCESS;
}
#endif
int AddDefaultUDPFRAGV6(int controlSocket )
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEDEFAULTFRAG; rule.fw_flg |= IPV6_FW_F_ACCEPT; rule.fw_prot = IPPROTO_UDP;
rule.fw_flg |= (IPV6_FW_F_IN | IPV6_FW_F_FRAG);
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEDEFAULTFRAG, errno);
return i;
}
return SUCCESS;
}
int AddDefaultUDPDenyV6(int controlSocket, Boolean loggingenabled )
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = UDPRULEDEFAULTDENY; rule.fw_flg |= IPV6_FW_F_DENY; if ( loggingenabled )
rule.fw_flg |= IPV6_FW_F_PRN; rule.fw_prot = IPPROTO_UDP;
rule.fw_flg |= IPV6_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d, errno = %d\n", UDPRULEDEFAULTDENY, errno);
return i;
}
return SUCCESS;
}
int AddUserDefinedRule(int controlSocket, int ruleNumber, SInt32 start, SInt32 end, boolean_t useRange, boolean_t doUDP)
{
struct ip_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IP_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = ruleNumber;
rule.fw_flg |= IP_FW_F_ACCEPT;
if (doUDP)
rule.fw_prot = IPPROTO_UDP;
else
rule.fw_prot = IPPROTO_TCP;
if( !doUDP && (start == SIGNAL_FTP && end == SIGNAL_FTP && useRange) ) {
rule.fw_uar.fw_pts[0] = 21;
IP_FW_SETNDSTP(&rule, 1);
rule.fw_flg |= IP_FW_F_IN;
}
else {
rule.fw_uar.fw_pts[0] = start;
IP_FW_SETNDSTP(&rule, 1);
rule.fw_flg |= IP_FW_F_IN;
if( useRange ) {
rule.fw_uar.fw_pts[1] = end;
IP_FW_SETNDSTP(&rule, 2);
rule.fw_flg |= IP_FW_F_DRNG;
}
}
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", ruleNumber);
return i;
}
return SUCCESS;
}
int AddUserDefinedRuleV6(int controlSocket, int ruleNumber, SInt32 start, SInt32 end, boolean_t useRange, boolean_t doUDP)
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = ruleNumber;
rule.fw_flg |= IPV6_FW_F_ACCEPT;
if (doUDP)
rule.fw_prot = IPPROTO_UDP;
else
rule.fw_prot = IPPROTO_TCP;
if( !doUDP && (start == SIGNAL_FTP && end == SIGNAL_FTP && useRange) ) {
rule.fw_pts[0] = 21;
IPV6_FW_SETNDSTP(&rule, 1);
rule.fw_flg |= IPV6_FW_F_IN;
}
else {
rule.fw_pts[0] = start;
IPV6_FW_SETNDSTP(&rule, 1);
rule.fw_flg |= IPV6_FW_F_IN;
if( useRange ) {
rule.fw_pts[1] = end;
IPV6_FW_SETNDSTP(&rule, 2);
rule.fw_flg |= IPV6_FW_F_DRNG;
}
}
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding V6 rule: %d\n", ruleNumber);
return i;
}
return SUCCESS;
}
int AddICMPRuleV6( int controlSocket, Boolean loggingenabled )
{
struct ip6_fw rule;
int i;
memset(&rule, 0, sizeof(rule));
rule.version = IPV6_FW_CURRENT_API_VERSION; rule.context = (void*)'AAPL';
rule.fw_number = ICMPECHOREQRULE; rule.fw_flg |= IPV6_FW_F_DENY; if ( loggingenabled )
rule.fw_flg |= IPV6_FW_F_PRN; rule.fw_prot = IPPROTO_ICMPV6;
rule.fw_icmp6types[ICMP6_ECHO_REQUEST / (sizeof(unsigned) * 8)] |=
1 << (ICMP6_ECHO_REQUEST % (sizeof(unsigned) * 8));
rule.fw_flg |= IPV6_FW_F_ICMPBIT ; rule.fw_flg |= IPV6_FW_F_IN;
i = setsockopt(controlSocket, IPPROTO_IPV6, IPV6_FW_ADD, &rule, sizeof(rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d\n", ICMPECHOREQRULE);
return i;
}
return SUCCESS;
}
int WriteOutInternetSharingRule(int controlSocket, struct ip_fw *rule)
{
int i;
i = setsockopt(controlSocket, IPPROTO_IP, IP_FW_ADD, rule, sizeof(*rule));
if( i )
{
printf("Firewall Tool: Error adding rule: %d (Internet Sharing)\n", RULE_0);
return i;
}
return SUCCESS;
}
int GetPortRange(CFStringRef portString, SInt32 *start, SInt32 *end, boolean_t *useRange)
{
char buffer[256];
if( portString == NULL )
return ERROR;
if( CFStringGetLength(portString) == 0 )
return ERROR;
if( CFStringGetCString(portString, buffer, 256, kCFStringEncodingMacRoman) )
{
char *ptr = NULL;
char bufferCopy[256];
strcpy(bufferCopy, buffer);
ptr = strtok(bufferCopy, "-");
if( ptr ) {
if( strcmp(ptr, "*") == 0 ) {
*start = SIGNAL_FTP;
*end = SIGNAL_FTP;
*useRange = true;
return SUCCESS;
}else
{
int startVal = strtol(ptr, (char**)NULL, 10);
if( startVal > 0 && startVal <= 65535 && startVal != LONG_MAX && startVal != LONG_MIN )
{
*start = startVal;
}
else
{
printf("Firewall Tool: Error, Start Port (%d) invalid!\n", startVal);
return ERROR;
}
}
}else
{
printf("Firewall Tool: Error, No Start Port defined!\n");
return ERROR;
}
ptr = strtok(NULL, "\0");
if( ptr )
{
int endVal = strtol(ptr, (char**)NULL, 10);
if( endVal > 0 && endVal <= 65535 && endVal != LONG_MAX && endVal != LONG_MIN )
{
*end = endVal;
*useRange = true;
}
else
{
printf("Firewall Tool: Error, End Port (%d) invalid!\n", endVal);
return ERROR;
}
}else
{
*end = 0;
*useRange = false;
}
return SUCCESS;
}else
{
return ERROR;
}
}
boolean_t isInternetSharingRunning(int controlSocket, struct ip_fw *rule)
{
struct ip_fw *rules = NULL;
int dataSize = 0;
int actualDataSize = 0;
int numRules = 0;
int iterations = 1;
int i, j;
do
{
dataSize = (sizeof(struct ip_fw) * 10) * iterations;
rules = (struct ip_fw *)realloc(rules, dataSize);
if (rules == NULL )
{
printf("Firewall Tool: Error getting rules! Realloc Failed!\n");
return false;
}
rules->version = IP_FW_CURRENT_API_VERSION;
actualDataSize = dataSize;
i = getsockopt(controlSocket, IPPROTO_IP, IP_FW_GET, rules, &actualDataSize);
if( i < 0 )
{
printf("Firewall Tool: Error getting rules! Not written into structure...\n");
free(rules);
return false;
}
iterations++;
}while( dataSize == actualDataSize );
numRules = actualDataSize/sizeof(struct ip_fw);
for( j = 0; j < numRules; j++ )
{
int ruleNumber = rules[i].fw_number;
if( ruleNumber == RULE_0 )
{
rule = memcpy(rule, &rules[i], sizeof(struct ip_fw));
return true;
}
}
if( rules )
free( rules );
return false;
}
void EnableLogging(boolean_t enable)
{
int newValue = enable ? 2 : 0;
int errorCode;
errorCode = sysctlbyname("net.inet.ip.fw.verbose", NULL, NULL, &newValue, sizeof(newValue));
if( errorCode < 0 )
{
printf("Firewall Tool: Error, sysctlbyname returned: %d\n", errorCode);
}
}
boolean_t IsExpectedCFType(CFPropertyListRef variableInQuestion, CFTypeID expectedType)
{
if( variableInQuestion == NULL ) {
printf("Firewall Tool: Error, IsExpectedCFType(variableInQuestion) variable == NULL!\n");
return false;
}
else if( CFGetTypeID(variableInQuestion) == expectedType )
{
return true;
}
else
{
return false;
}
}
void EnableBlackHole(boolean_t enable)
{
int lognewValue = enable ? 3 : 0;
int newValue = enable ? 1 : 0;
int errorCode;
errorCode = sysctlbyname("net.inet.tcp.blackhole", NULL, NULL, &newValue, sizeof(newValue));
if( errorCode < 0 )
{
printf("Firewall Tool: Error, sysctlbyname(net.inet.tcp.blackhole): %d\n", errno);
}
errorCode = sysctlbyname("net.inet.tcp.log_in_vain", NULL, NULL, &lognewValue, sizeof(newValue));
if( errorCode < 0 )
{
printf("Firewall Tool: Error, sysctlbyname(net.inet.tcp.log_in_vain): %d\n", errno);
}
errorCode = sysctlbyname("net.inet.udp.blackhole", NULL, NULL, &newValue, sizeof(newValue));
if( errorCode < 0 )
{
printf("Firewall Tool: Error, sysctlbyname(net.inet.udp.blackhole): %d\n", errno);
}
errorCode = sysctlbyname("net.inet.udp.log_in_vain", NULL, NULL, &lognewValue, sizeof(newValue));
if( errorCode < 0 )
{
printf("Firewall Tool: Error, sysctlbyname(net.inet.udp.log_in_vain): %d\n", errno);
}
}