test_ip.py

#!/usr/bin/python
# coding: utf-8

import sys
import re
from netaddr import *
import socket
import argparse

def apache_to_verbose(abbrev_cidr):
    """
    Funkcja bazująca na cidr_abbrev_to_verbose z python-netaddr służąca parsowaniu apachowego niepełnego zapisu sieci IP
    """
    start = ''
    tokens = []
    prefix = 32

    if abbrev_cidr == '':
        return abbrev_cidr
    if ':' in abbrev_cidr:
        return abbrev_cidr
    if '/' in abbrev_cidr:
        return abbrev_cidr

    if '.' in abbrev_cidr:
        tokens = abbrev_cidr.split('.')
    else:
        tokens = [abbrev_cidr]
    
    if 1 <= len(tokens) <= 4:
        for i in range(4 - len(tokens)):
            tokens.append('0')
            prefix=prefix-8
    else:
        #   Not a recognisable format.
        return abbrev_cidr

    if prefix is None:
        try:
            prefix = nprefix
        except ValueError:
            return abbrev_cidr

    return "%s%s/%s" % (start, '.'.join(tokens), prefix)

    
def test_ip(net, ip, verbose=False, net_txt=None):
    """
    Funkcja sprawdzajaca czy podany zakres adresów ip (ip) zawiera się w badanym zakresie adresów IP (net)
    
    :param net:     sieć w której szukamy podanego adresu ip / podsieci (string)
    :param ip:      szukany adres ip / podsieci (IPSet)
    :param verbose: (opcjonalny) decyduje o tym czy wypisujemy zawsze czy tylgo gdy zawiera się
    """
    ipnet = IPNetwork(apache_to_verbose(net))
    ipset = IPSet([ ipnet ])
    r = ipset.issuperset(ip)
    if r or verbose:
        if net_txt is None:
            net_txt = net
        print "{} ({}) {}" .format(str(ipnet), net_txt, r) 

        
def check_and_test_ip(net, ip, verbose=False, resolve_dns=True):
    # if entry is ip address
    if re.match("^[0-9:./]*$", net):
            test_ip(net, ip, verbose)
    # otherwise try resolve as DNS name
    else:
        try:
            dns_addrs = socket.getaddrinfo(net, 0);
            for dns_addr in dns_addrs:
                test_ip(dns_addr[4][0], ip, verbose, net)
        except:
            pass



# parser agumentów linii poleceń
# do argumentów można się też dostawać bezpośrednio poprzez sys.argv:
#   len(sys.argv) - ilość elementów tej tablicy
#   str(sys.argv[0]) - napis odpowiadający nazwie wywołania programuz
#   str(sys.argv[1]) - napis odpowiadający pierwszemu argumentoi progrumu

parser = argparse.ArgumentParser(description='Looking for a matching network (from input file or STDIN, \
                                              using apache network notation for allow/deny rules) for the specified IP')
parser.add_argument('IP', help='search IP address')
parser.add_argument('-a', "--apache", action="store_true",
                    help='use apache config file format as input (parse only "allow from" rules')
parser.add_argument('-n', "--numeric_only", action="store_true", help='don\'t resolve DNS from input')
parser.add_argument('-v', "--verbose", action="store_true", help='print all input entry')
parser.add_argument('-i', "--input", action="store", metavar='FILE', help='input file (if not specified STDIN)')
args = parser.parse_args()


# parsowanie szukanego adresu IP do formy IPSet
testipnet = IPNetwork( str(args.IP) )
testipset = IPSet([ testipnet ])


# ustalenie źródła z którego czytane są sieci
if args.input:
    print "Find for {} ({}) in {}" .format(str(testipnet), str(args.IP), str(args.input)) 
    nets_input = open(str(args.input), 'r')
else:
    print "Find for {} ({}) in {}" .format(str(testipnet), str(args.IP), "STDIN") 
    nets_input = sys.stdin


# ustalenie formatu źródła sieci
if args.apache:
     for line in nets_input:
        if re.match("^allow\s*from", line, re.IGNORECASE):
            # podział linii na listę słów przy pomocy dowolnego białego znaku
            # poprzez line.split(None,2) możemy podzielić na 2 pierwszych separatorach
            # poprzez line.split("SEP") możemy określić separator
            # poprzez re.split("REGEXP", line) możemy dzieć wg wyrażenia regularnego
            nets = line.split();
            
            # usuwamy z listy dwa pierwsze argumentu (lista nadal numerowana jest od zera)
            del nets[1], nets[0];
            
            # przetwarzamy każdy element pozostały na liście słów
            for net in nets:
                check_and_test_ip(net, testipset, args.verbose, args.numeric_only)
else:
    for line in nets_input:
        check_and_test_ip(line.strip(), testipset, args.verbose, args.numeric_only)

XHTML generated by highlight (http://www.andre-simon.de/) from test_ip.py



Copyright (c) 1999-2015, Robert Paciorek (http://www.opcode.eu.org/), BSD/MIT-type license


Redystrybucja wersji źródłowych i wynikowych, po lub bez dokonywania modyfikacji JEST DOZWOLONA, pod warunkiem zachowania niniejszej informacji o prawach autorskich. Autor NIE ponosi JAKIEJKOLWIEK odpowiedzialności za skutki użytkowania tego dokumentu/programu oraz za wykorzystanie zawartych tu informacji.

This text/program is free document/software. Redistribution and use in source and binary forms, with or without modification, ARE PERMITTED provided save this copyright notice. This document/program is distributed WITHOUT any warranty, use at YOUR own risk.

Valid XHTML 1.1 Dokument ten (URL: http://www.opcode.eu.org/programing/python/test_ip.py) należy do serwisu OpCode. Autorem tej strony jest Robert Paciorek, wszelkie uwagi proszę kierować na adres e-mail serwisu: webmaster@opcode.eu.org.
Data ostatniej modyfikacji artykulu: '2014-01-07 19:27:41 (UTC)' (data ta może być zafałszowana niemerytorycznymi modyfikacjami artykułu).