public bool IsIPAddressBlocked(string ipAddress, out string ruleName, int port = -1) { ruleName = null; if (!IPAddress.TryParse(ipAddress, out IPAddress ipAddressObj)) { return(false); } lock (this) { if (ipAddressObj.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { uint ipv4 = ipAddressObj.ToUInt32(); if (allowRule.Contains(ipv4)) { return(false); } foreach (KeyValuePair <string, MemoryFirewallRule> rule in blockRules) { if (rule.Value.Contains(ipv4)) { ruleName = rule.Key; return(true); } } foreach (KeyValuePair <string, MemoryFirewallRuleRanges> rule in blockRulesRanges) { if (rule.Value.Contains(ipv4, port)) { ruleName = rule.Key; return(true); } } } else { UInt128 ipv6 = ipAddressObj.ToUInt128(); if (allowRule.Contains(ipv6)) { return(false); } foreach (KeyValuePair <string, MemoryFirewallRule> rule in blockRules) { if (rule.Value.Contains(ipv6)) { ruleName = rule.Key; return(true); } } foreach (KeyValuePair <string, MemoryFirewallRuleRanges> rule in blockRulesRanges) { if (rule.Value.Contains(ipv6, port)) { ruleName = rule.Key; return(true); } } } } return(false); }
public bool Remove(UInt128 ipv6UInt128) { return(ipv6.Remove(ipv6UInt128)); }
public bool Contains(UInt128 ipv6UInt128) { return(ipv6.Contains(ipv6UInt128)); }
// deleteRule will drop the rule and matching set before creating the rule and set, use this is you don't care to update the rule and set in place private HashSet <UInt128> UpdateRule(string ruleName, string action, IEnumerable <string> ipAddresses, HashSet <UInt128> existingIPAddresses, string hashType, int maxCount, bool deleteRule, IEnumerable <PortRange> allowPorts, CancellationToken cancelToken, out bool result) { string ipFile = GetSetFileName(ruleName); string ipFileTemp = ipFile + ".tmp"; HashSet <UInt128> newIPAddressesUInt128 = new HashSet <UInt128>(); UInt128 value = 0; // add and remove the appropriate ip addresses from the set using (StreamWriter writer = File.CreateText(ipFileTemp)) { if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } writer.WriteLine($"create {ruleName} hash:{hashType} family {inetFamily} hashsize {hashSize} maxelem {maxCount} -exist"); foreach (string ipAddress in ipAddresses) { if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } value = 0; if (IPAddressRange.TryParse(ipAddress, out IPAddressRange range) && range.Begin.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6 && range.End.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6 && // if deleting the rule, don't track the UInt128 value (!deleteRule || (value = IPBanFirewallUtility.ParseIPV6(ipAddress)) != 0)) { try { if (range.Begin.Equals(range.End)) { writer.WriteLine($"add {ruleName} {range.Begin} -exist"); } else { writer.WriteLine($"add {ruleName} {range.ToCidrString()} -exist"); } if (!deleteRule) { newIPAddressesUInt128.Add((value == 0 ? IPBanFirewallUtility.ParseIPV6(ipAddress) : value)); } } catch { // ignore invalid cidr ranges } } } // if the rule was deleted, no need to add del entries if (!deleteRule) { // for ip that dropped out, remove from firewall foreach (UInt128 droppedIP in existingIPAddresses.Where(e => newIPAddressesUInt128.Contains(e))) { writer.WriteLine($"del {ruleName} {droppedIP.ToIPAddress()} -exist"); } } } if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } else { // TODO: Is there an easier way to move to a file that exists? if (File.Exists(ipFile)) { DeleteFile(ipFile); } File.Move(ipFileTemp, ipFile); if (deleteRule) { DeleteRule(ruleName); } // restore the file to get the set updated result = (RunProcess("ipset", true, $"restore < \"{ipFile}\"") == 0); // ensure rule exists for the set CreateOrUpdateRule(ruleName, action, hashType, maxCount, allowPorts, cancelToken); } return(newIPAddressesUInt128); }