| 477 | |
| 478 | |
| 479 | class RuleEngine2: |
| 480 | |
| 481 | # replaces the self keyword, but could be expanded to any keyword replacement |
| 482 | def _replace_self(self, ips): |
| 483 | # Deal with the user putting "self" in a rule (helpful if you don't know your IP) |
| 484 | for ip in ips: |
| 485 | if ip.lower() == 'self': |
| 486 | try: |
| 487 | self_ip = socket.gethostbyname(socket.gethostname()) |
| 488 | except socket.error: |
| 489 | print(">> Could not get your IP address from your " \ |
| 490 | "DNS Server.") |
| 491 | self_ip = '127.0.0.1' |
| 492 | ips[ips.index(ip)] = self_ip |
| 493 | return ips |
| 494 | |
| 495 | |
| 496 | def __init__(self, file_): |
| 497 | """ |
| 498 | Parses the DNS Rulefile, validates the rules, replaces keywords |
| 499 | """ |
| 500 | |
| 501 | # track DNS requests here |
| 502 | self.match_history = {} |
| 503 | |
| 504 | self.rule_list = [] |
| 505 | |
| 506 | # A lol.com IP1,IP2,IP3,IP4,IP5,IP6 rebind_threshold%Rebind_IP1,Rebind_IP2 |
| 507 | with open(file_, 'r') as rulefile: |
| 508 | rules = rulefile.readlines() |
| 509 | lineno = 0 # keep track of line number for errors |
| 510 | |
| 511 | for rule in rules: |
| 512 | |
| 513 | # ignore blank lines or lines starting with hashmark (coments) |
| 514 | if len(rule.strip()) == 0 or rule.lstrip()[0] == "#" or rule == '\n': |
| 515 | # thank you to github user cambid for the comments suggestion |
| 516 | continue |
| 517 | |
| 518 | # Confirm that the rule has at least three columns to it |
| 519 | if len(rule.split()) < 3: |
| 520 | raise RuleError_BadFormat(lineno) |
| 521 | |
| 522 | # break the rule out into its components |
| 523 | s_rule = rule.split() |
| 524 | rule_type = s_rule[0].upper() |
| 525 | domain = s_rule[1] |
| 526 | ips = s_rule[2].split(',') # allow multiple ip's thru commas |
| 527 | |
| 528 | # only try this if the rule is long enough |
| 529 | if len(s_rule) == 4: |
| 530 | rebinds = s_rule[3] |
| 531 | # handle old rule style (maybe someone updated) |
| 532 | if '%' in rebinds: |
| 533 | rebind_threshold,rebinds = rebinds.split('%') |
| 534 | rebinds = rebinds.split(',') |
| 535 | rebind_threshold = int(rebind_threshold) |
| 536 | else: |