calculando rede e broadcast com python
Publicado; março 18, 2008 Arquivado em: programação, python, rede | Tags: cálculo, inet_aton, máscara, python, rede, socket, struct 1 comentárioTalvez você esteja se perguntando: por que em C é tão simples e com python o inet_aton() não retorna nada útil para ser usado com & (and)? hehe. É que o inet_aton() do python retorna uma string, e com o módulo struct você poderá obter o long int que tanto deseja.
Imagino que seja isso que você procura:
$ ./netcalc.py use: netcalc.py ip/[mask|cidr] $ ./netcalc.py 192.168.0.200/25 cidr=25, effective networks=2, effective hosts=126 address : 192.168.0.200 (11000000.10101000.00000000.11001000) netmask : 255.255.255.128 (11111111.11111111.11111111.10000000) network : 192.168.0.128 (11000000.10101000.00000000.10000000) broadcast : 192.168.0.255 (11000000.10101000.00000000.11111111) $ ./netcalc.py 192.168.0.100/255.255.255.240 cidr=28, effective networks=16, effective hosts=14 address : 192.168.0.100 (11000000.10101000.00000000.01100100) netmask : 255.255.255.240 (11111111.11111111.11111111.11110000) network : 192.168.0.96 (11000000.10101000.00000000.01100000) broadcast : 192.168.0.111 (11000000.10101000.00000000.01101111)
Bom, pra facilitar sua vida, já escrevi o código. Ele é bem simples – chega a ser tosco – e não faz nenhum tipo de validação nos endereços IP. na verdade, ele usa que o inet_aton() retorna – isso significa que se você usar o IP 100.200.300 e o inet_aton() permitir, o programa vai retornar algo inesperado.
Este programa usa o módulo bitprint que já postei aqui, pra imprimir o conteúdo binário dos endereços. O cálculo do endereço de rede e broadcast é simples e genérico:
network = ip & netmask broadcast = ~network ^ netmaskEnfim, segue aí o código:
#!/usr/bin/env python # coding: utf-8 # netcalc.py 20080318 AF import sys, bitprint from struct import pack, unpack from socket import inet_ntoa, inet_aton mask = 1L<<31 xnet = (1L<<32)-1 cidr_range = range(9, 32) def bp(addr): buff = [] bits = str(bitprint.XBits(addr)) for n in range(4): pos = n*8 buff.append(bits[pos:pos+8]) return '.'.join(buff) def cidr_to_netmask(cidr): return ((1L<<cidr)-1)<<(32-cidr) def netmask_to_cidr(netmask): cidr = 0 mm = mask for n in range(32): if netmask & mm: cidr+=1 mm>>=1 return cidr if __name__ == '__main__': try: ip_s, temp = sys.argv[1].split('/') except: print 'use: %s ip/[mask|cidr]' % sys.argv[0] sys.exit(1) if temp.isdigit(): cidr = long(temp) if cidr not in cidr_range: print 'cidr inválido: %d' % cidr sys.exit(1) nm = cidr_to_netmask(cidr) else: nm = unpack('>L', inet_aton(temp))[0] cidr = netmask_to_cidr(nm) ip = unpack('>L', inet_aton(ip_s))[0] nw = ip & nm bc = (~nw ^ nm) & xnet nets = pow(2, cidr%8) hosts = pow(2, 32-cidr)-2 print 'cidr=%d, effective networks=%d, effective hosts=%d\n' % (cidr, nets, hosts) print 'address : % 16s (%s)' % (ip_s, bp(ip)) print 'netmask : % 16s (%s)' % (inet_ntoa(pack('>L', nm)), bp(nm)) print 'network : % 16s (%s)' % (inet_ntoa(pack('>L', nw)), bp(nw)) print 'broadcast : % 16s (%s)' % (inet_ntoa(pack('>L', bc)), bp(bc))
Divirta-se!
Olá,
saberia me dizer como eu faria para saber se um IP pertence a uma rede ou não?
preciso de um programinha em python que veja o IP da máquina local(DHCP) e verifique com um IP que eu vou definir se esse IP que eu definir pertence a sub-rede do DHCP. Finalidade evitar conflitos de IP de rede local com IP de VPN.
Obrigado,
Lucas.