from myip import CamadaRede class CamadaEnlace: def __init__(self): self.callback = None self.fila = [] def registrar_recebedor(self, callback): self.callback = callback def enviar(self, datagrama, next_hop): self.fila.append((datagrama, next_hop)) def rand_ip(): return '%d.%d.%d.%d'%tuple(random.randint(1, 255) for i in range(4)) enlace = CamadaEnlace() rede = CamadaRede(enlace) def enviar_datagrama(dest): datagrama = b'E\x00\x00\x14\x00\x00\x00\x00@\x06\x00\x00\x01\x02\x03\x04' + str2addr(dest) assert len(datagrama) == 20 enlace.callback(datagrama[:-10] + struct.pack('!H',calc_checksum(datagrama)) + datagrama[-8:]) assert len(enlace.fila) == 1, 'Só foi recebido um datagrama, mas foi encaminhado mais de um' datagrama, next_hop = enlace.fila.pop() assert len(datagrama) == 20, 'O tamanho mudou ao ser encaminhado' dscp, ecn, identification, flags, frag_offset, ttl, proto, \ src_addr, dst_addr, payload = read_ipv4_header(datagrama, verify_checksum=True) assert dscp == 0 and ecn == 0 and identification == 0 and flags == 0 and frag_offset == 0 and \ ttl in {63, 64} and proto == IPPROTO_TCP and src_addr=='1.2.3.4' and dst_addr==dest and \ len(payload) == 0, 'Foram alteradas informações do datagrama original' return next_hop
import asyncio from camadaenlace import CamadaEnlaceLinux from mytcp import Servidor # copie o arquivo da Etapa 2 from myip import CamadaRede def dados_recebidos(conexao, dados): if dados == b'': conexao.fechar() else: conexao.enviar(dados) # envia de volta def conexao_aceita(conexao): conexao.registrar_recebedor( dados_recebidos) # usa esse mesmo recebedor para toda conexão aceita enlace = CamadaEnlaceLinux() rede = CamadaRede(enlace) rede.definir_endereco_host( '192.168.0.123' ) # consulte o endereço IP da sua máquina com o comando: ip addr rede.definir_tabela_encaminhamento([ ('0.0.0.0/0', '192.168.0.1' ) # consulte sua rota padrão com o comando: ip route | grep default ]) servidor = Servidor(rede, 7000) servidor.registrar_monitor_de_conexoes_aceitas(conexao_aceita) asyncio.get_event_loop().run_forever()
self.callback = None self.fila = [] def registrar_recebedor(self, callback): self.callback = callback def enviar(self, datagrama, next_hop): self.fila.append((datagrama, next_hop)) def rand_ip(): return '%d.%d.%d.%d' % tuple(random.randint(1, 255) for i in range(4)) enlace = CamadaEnlace() rede = CamadaRede(enlace) def enviar_datagrama(dest): datagrama = b'E\x00\x00\x14\x00\x00\x00\x00@\x06\x00\x00\x01\x02\x03\x04' + str2addr( dest) assert len(datagrama) == 20 enlace.callback(datagrama[:-10] + struct.pack('!H', calc_checksum(datagrama)) + datagrama[-8:]) assert len( enlace.fila ) == 1, 'Só foi recebido um datagrama, mas foi encaminhado mais de um' datagrama, next_hop = enlace.fila.pop() assert len(datagrama) == 20, 'O tamanho mudou ao ser encaminhado' dscp, ecn, identification, flags, frag_offset, ttl, proto, \
server = Server() # Integração com as demais camadas driver = ZyboSerialDriver() linha_serial = driver.obter_porta(4) pty = driver.expor_porta_ao_linux(5) outra_ponta = '192.168.123.1' nossa_ponta = '192.168.123.2' porta_tcp = 7000 print('Conecte o RX da porta 4 com o TX da porta 5 e vice-versa.') print('Para conectar a outra ponta da camada física, execute:') print() print('sudo slattach -vLp slip {}'.format(pty.pty_name)) print('sudo ifconfig sl0 {} pointopoint {} mtu 1500'.format( outra_ponta, nossa_ponta)) print() print('Acesse o serviço com o comando: nc {} {}'.format(nossa_ponta, porta_tcp)) print() enlace = CamadaEnlace({outra_ponta: linha_serial}) rede = CamadaRede(enlace) rede.definir_endereco_host(nossa_ponta) rede.definir_tabela_encaminhamento([ ('0.0.0.0/0', outra_ponta) ]) tcp = Tcp(rede, porta_tcp) tcp.registrar_monitor_de_conexoes_aceitas(server.conexao_aceita) asyncio.get_event_loop().run_forever()
print() print('sudo slattach -vLp slip {}'.format(pty1.pty_name)) print('sudo slattach -vLp slip {}'.format(pty2.pty_name)) print('sudo slattach -vLp slip {}'.format(pty3.pty_name)) print() # Os endereços IP que especificamos abaixo são os endereços da outra ponta do # enlace. No caso do teste montado de acordo as mensagens acima, são os # endereços atribuídos às interface de rede do Linux. enlace = CamadaEnlace({ '192.168.123.1': serial1, '192.168.124.1': serial2, '192.168.125.1': serial3 }) rede = CamadaRede(enlace) # Este é o endereço IP do nosso roteador. Como os enlaces são ponto-a-ponto, # ele não precisa estar em uma mesma subrede que os endereços IP atribuídos # às interfaces do Linux. rede.definir_endereco_host('192.168.122.1') # A tabela de encaminhamento define através que qual enlace o nosso # roteador pode alcançar cada faixa de endereços IP. rede.definir_tabela_encaminhamento([ ('192.168.123.0/24', '192.168.123.1'), ('192.168.124.0/24', '192.168.124.1'), ('192.168.125.0/24', '192.168.125.1'), ]) asyncio.get_event_loop().run_forever()