def EnviaMensagem(self, Destino, Mensagem): nBytesMensagem = len(Mensagem) * 4 nPacotes = int(nBytesMensagem / 32) i = 0 j = 8 round(nPacotes + 0, 5) while (nPacotes >= 0): frame = Mensagem[i:j] if (nPacotes == 0): Pac = Pacote(self._MAC, Destino, frame, True) else: Pac = Pacote(self._MAC, Destino, frame, False) self._Camada_Rede.Envia_Dados(Pac) nPacotes += -1 i = j j += 8
def fechar_conexao(self, sock, ip, porta): self.sock = sock tupla_conn = (ip, porta) print("Enviando pacote para fim da conexão.") pacote = Pacote() pacote.set([['fin', 1]]) raw_pacote = json.dumps(pacote.conteudo) self.sock.sendto(raw_pacote, tupla_conn) while True: try: raw_pacote, conn = self.sock.recvfrom(self.MTU) break except: print("Tempo limite atingido, reenviando pacote FIN") self.sock.sendto(raw_pacote, tupla_conn) if pacote.conteudo['flags']['fin'] == 1: self.sock.close() print("Conexão finalizada.") else: print("O servidor não respondeu corretamente ao requerimento FIN.") print("Deseja forçar a interrupção [s/N]?") if (input().lower() == 's'): self.sock.close() print("Conexão terminada a força.") else: print("Tentando finalizar a conexão novamente...") self.fechar_conexao(sock, ip, porta)
def arpSolicita(self, quadro): # Guarda o quadro self.__quadroRecebido.append(quadro) pacote = quadro.getDados() # Cria pacote ARP-Solicita pacote_ARP = Pacote(pacote.getIPOrigem(), 12) pacote_ARP.setIPDestino(pacote.getIPDestino()) pacote_ARP.setDados("ARP-Solicita") # Cria quadro ARP-Solicita # Retorna Quadro ARP-Solicita montado return self.__host.constroiQuadro(24, "FFFFFFFFFFFF", pacote_ARP)
def enviaICMP(self, ipDest): # Make ICMP packet pacote_ICMP = Pacote(self.__host.getIP(),self.__ping.getTamanho()) pacote_ICMP.setIPDestino(ipDest) PacPing = PacotePing("request",0) # PING frame TTL PacPing.setTtl(self.__quadroTTL) pacote_ICMP.setDados(PacPing) # Make ICMP frame Quadro_ICMP = self.__host.constroiQuadro(self.__ping.getTamanho(), "000000000000", pacote_ICMP) Quadro_ICMP.setTipo(2) # Return ICMP frame ready return Quadro_ICMP
def respondeICMP(self, ipDest, macDest, ttl): # Make ICMP answer packet pacote_ICMP = Pacote(self.__host.getIP(),self.__ping.getTamanho()) pacote_ICMP.setIPDestino(ipDest) # Make ping answer packet PacPing = PacotePing("reply",8) PacPing.setTtl(ttl) pacote_ICMP.setDados(PacPing) # Make ICMP frame Quadro_ICMP = self.__host.constroiQuadro(self.__ping.getTamanho(), "000000000000", pacote_ICMP) Quadro_ICMP.setDestino(macDest) Quadro_ICMP.setTipo(2) # Return ICMP frame set return Quadro_ICMP
def Cliente(args): ''' Envia acks e recebe arquivos do servidor ''' if len(args) != 4: print 'Entrada errada. execucao se da por:\n\tpython receptor.py <hostname> <porta> <nome_arquivo>' sys.exit() pacoteEnviar = Pacote() pacoteRecebido = Pacote() arquivoRecebido = "" s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #recebe ip, porta e nome do arquivo pela linha de comando host = args[1] port = int(args[2]) arq_name = args[3] #Numero de pacotes que podem ser enviados sem confirmação janela = 3 numeroSequenciaEsperado = 0 numeroSequenciaAntigo = 0 pacoteRecebido.data = arq_name while(True): try: EnviaAck(s, pacoteRecebido, host, port) pacoteRecebido, addr = RecebePacote(s) except socket.timeout: enviocorreto = 0 envioCorreto = VerificaPacote(pacoteRecebido) sleep(0.2) if envioCorreto and numeroSequenciaEsperado==pacoteRecebido.numeroSequencia: #muda os parametros do pacote pra pedir o proximo e salva o texto recebido arquivoRecebido += pacoteRecebido.data EnviaAck(s, pacoteRecebido, host, port) numeroSequenciaEsperado += 1 if pacoteRecebido.sair == 1: break else: EnviaAck(s, pacoteRecebido, host, port) print "recebi errado, esperava ",numeroSequenciaEsperado #Cliente aceita encerrar e acaba a comunicacao s.close() print arquivoRecebido if arquivoRecebido: EscreveArquivo(arquivoRecebido) else: print 'Não foi recebido nenhum arquivo, talvez o arquivo pedido não exista'
def Cliente(args): ''' Envia acks e recebe arquivos do servidor ''' if len(args) != 4: print 'Entrada errada. execucao se da por:\n\tpython receptor.py <hostname> <porta> <nome_arquivo>' sys.exit() pacoteEnviar = Pacote() pacoteRecebido = Pacote() arquivoRecebido = "" s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #recebe ip, porta e nome do arquivo pela linha de comando host = args[1] port = int(args[2]) arq_name = args[3] #Numero de pacotes que podem ser enviados sem confirmação janela = 3 numeroSequenciaEsperado = 0 numeroSequenciaAntigo = 0 pacoteRecebido.data = arq_name while (True): try: EnviaAck(s, pacoteRecebido, host, port) pacoteRecebido, addr = RecebePacote(s) except socket.timeout: enviocorreto = 0 envioCorreto = VerificaPacote(pacoteRecebido) sleep(0.2) if envioCorreto and numeroSequenciaEsperado == pacoteRecebido.numeroSequencia: #muda os parametros do pacote pra pedir o proximo e salva o texto recebido arquivoRecebido += pacoteRecebido.data EnviaAck(s, pacoteRecebido, host, port) numeroSequenciaEsperado += 1 if pacoteRecebido.sair == 1: break else: EnviaAck(s, pacoteRecebido, host, port) print "recebi errado, esperava ", numeroSequenciaEsperado #Cliente aceita encerrar e acaba a comunicacao s.close() print arquivoRecebido if arquivoRecebido: EscreveArquivo(arquivoRecebido) else: print 'Não foi recebido nenhum arquivo, talvez o arquivo pedido não exista'
def __init__(self, MTU=1500): self.sock = socket(AF_INET, SOCK_DGRAM) self.MTU = MTU # Criando pacote padrão para definir dinamicamente o MSS pacote = Pacote() pacote.set([['porta_orig', 65536], ['porta_dest', 65536], ['seq', 999999], ['ack_n', 999999], ['RTT', time.time()], ['ack', 1], ['syn', 1], ['fin', 1]]) self.MSS = MTU - len(json.dumps(pacote.conteudo)) self.cwnd = 1 # Variavel que determina se o crescimento da cwnd será exponencial ou linear self.exponencial = True self.seq = np.random.randint(100) # Buffer de envio self.buffer = [] self.indiceBuffer = 0 self.listaACKs = [] self.timeout = 0 self.ssthresh = 64 * 1024
def RecebeMensagem(self, Pacote, Origem, Rota): Dados = Pacote.GetDados(self, self._MAC) flag = Pacote.GetFlag(self) #Guarda o frame self._bufferMsg.append(Dados) if(flag == True): Mensagem = [''.join(self._bufferMsg)] print(" ") print("MAC :", self._MAC, "| Mensagem recebida de ", Origem, "Mensagem:", Mensagem) print("Rota do pacote", Rota) print(" ") del self._bufferMsg[:]
def abrir_conexao(self, ip, porta): tupla_conn = (ip, porta) pacote = Pacote() pacote.set([['porta_dest', porta], ['syn', 1], ['seq', self.seq], ['RTT', time.time()]]) raw_pacote = json.dumps(pacote.conteudo) print("Tentando se conectar a %s:%d." % (ip, porta)) # Enviando requisição SYN self.sock.sendto(raw_pacote, tupla_conn) self.sock.settimeout(5.0) # Caso o pacote se perca o client tenta reenviar a requisição while True: try: raw_pacote, conn = self.sock.recvfrom(self.MTU) break except: self.sock.sendto(raw_pacote, tupla_conn) print("Não houve resposta do servidor, tentando novamente.") print("Pacote de resposta recebido.") pacote.conteudo = json.loads(raw_pacote) if pacote.conteudo['flags']['syn'] and pacote.conteudo['flags']['ack']: print("O servidor enviou SYN ACK. Enviando ACK.") self.timeout = min(8, pacote.conteudo['RTT']) self.sock.settimeout(self.timeout) # Caso haja resposta o RTT é calculado e além disso uma resposta é gerada e enviada self.ack = pacote.conteudo['seq'] + 1 pacote.set([['porta_orig', pacote.conteudo['porta_dest']], ['porta_dest', porta], ['syn', 0], ['seq', self.seq], ['ack_n', self.ack], ['RTT', time.time()]]) raw_pacote = json.dumps(pacote.conteudo) self.sock.sendto(raw_pacote, tupla_conn) print("Conexão Estabelecida.") # O socket e as informações de conexão são retornadas para o client return self.sock, tupla_conn else: # Caso o servidor rejeite a conexão há uma opção de tentar novamente ou abandonar a conexão print("O servidor não quis estabelecer conexão.") print("Tentar novamente? [S/n]") if input().lower() == "n": print("Adeus.") return False else: print("Tentando novamente...") self.abrir_conexao(ip, porta)
def enviaICMP(self, ipDest): # Make ICMP packet pacote_ICMP = Pacote(self.__host.getIP(), self.__ping.getTamanho()) pacote_ICMP.setIPDestino(ipDest) PacPing = PacotePing("request", 0) # PING frame TTL PacPing.setTtl(self.__quadroTTL) pacote_ICMP.setDados(PacPing) # Make ICMP frame Quadro_ICMP = self.__host.constroiQuadro(self.__ping.getTamanho(), "000000000000", pacote_ICMP) Quadro_ICMP.setTipo(2) # Return ICMP frame ready return Quadro_ICMP
def multiplexacao(self, dados, porta, segmento=False): pacote = Pacote() if segmento: pacote.set([['ack', 0], ['seq', self.seq], ['ack_n', -1], ['dados', dados], ['porta_dest', porta], ['RTT', time.time()]]) self.seq += len(dados) self.buffer.append(pacote.conteudo) else: pacote.set([['seq', self.seq], ['dados', dados], ['porta_dest', porta], ['ack', 1], ['ack_n', self.ack], ['RTT', time.time()]]) self.seq += len(dados) self.buffer.append(pacote.conteudo)
def preencher_pacote(): nome_dest = (input('\nInforme o nome do destinatario: ')) d = True while (d): cpf_dest = (input('\nInforme o CPF do destinatario: ')) d = Regex.valida_cpf(cpf_dest) peso = (input('\nInforme o peso: ')) cubagem = (input('\nInforme a cubagem: ')) logradouro = (input('\nInforme o logradouro do destinatario: ')) numero = (input('\nInforme o numero do destinatario: ')) bairro = (input('\nInforme o bairro do destinatario: ')) cep = (input('\nInforme o cep do destinatario: ')) cidade = (input('\nInforme a cidade do destinatario: ')) uf = (input('\nInforme o estado do destinatario: ')) complemento = (input('\nInforme o complemento do destinatario: ')) a = True while (a): cpf_cliente = (input('\nInforme o CPF do Cliente/Remetente: ')) a = ValidaRelacoes.valida_cpf_cliente(cpf_cliente) nome_cliente = ValidaRelacoes.preenche_nome_cliente(cpf_cliente) b = True while (b): cnpj_agencia = (input('\nInforme o CNPJ da Agência: ')) b = ValidaRelacoes.valida_cnpj_agencia(cnpj_agencia) nome_agencia = ValidaRelacoes.preenche_nome_agencia(cnpj_agencia) c = True while (c): n_matricula_op = ( input('\nInforme o numero de matricula do operador: ')) c = ValidaRelacoes.valida_n_matricula_operador(n_matricula_op) nome_op = ValidaRelacoes.preenche_nome_operador(n_matricula_op) relacoes = Relacao_Pacote_Operador_Agencia_Cliente( cpf_cliente, nome_cliente, cnpj_agencia, nome_agencia, n_matricula_op, nome_op) pacote = Pacote(nome_dest, cpf_dest, peso, cubagem, logradouro, numero, bairro, cep, cidade, uf, complemento, relacoes) return pacote
def respondeICMP(self, ipDest, macDest, ttl): # Make ICMP answer packet pacote_ICMP = Pacote(self.__host.getIP(), self.__ping.getTamanho()) pacote_ICMP.setIPDestino(ipDest) # Make ping answer packet PacPing = PacotePing("reply", 8) PacPing.setTtl(ttl) pacote_ICMP.setDados(PacPing) # Make ICMP frame Quadro_ICMP = self.__host.constroiQuadro(self.__ping.getTamanho(), "000000000000", pacote_ICMP) Quadro_ICMP.setDestino(macDest) Quadro_ICMP.setTipo(2) # Return ICMP frame set return Quadro_ICMP
def consulta_pacote(): print('=================================') print("--> 1 - Consulta por CPF do Cliente") print("--> 2 - Consulta por ID") print("--> 3 - Listar Todos os Pacotes") opcao = int(input("Digite a opção desejada: ")) print('=================================') if opcao == 1: from Pacote import Pacote cpf = str(input("\nInforme o CPF do cliente: ")) Pacote.cons_pacote_cpf_cliente(cpf) pacote_opcao() if opcao == 2: from Pacote import Pacote id = str(input("\nInforme o ID do Pacote: ")) Pacote.cons_id_pacote(id) pacote_opcao() if opcao == 3: from Pacote import Pacote Pacote.listar_pacote() pacote_opcao() if opcao != 1 and opcao != 2 and opcao != 3: print("=====Digite uma opção valida=====") consulta_pacote()
class Host(EquipamentoRede): def __init__(self): EquipamentoRede.__init__(self) self.__ARP = ARP(self) self.__ICMP = ICMP(self) self.__novoQuadro = None self.__novoPacote = None self.__hostNic = [] self.__hostListaQuadros = [] self.__listaARP = [] self.__ip = "" self.__mascara = "" "@param ip: Host IP" def setIP(self, ip): self.__ip = ip def getIP(self): return self.__ip "@param mascara: Host Subnet mask" def setMascara(self, mascara): self.__mascara = mascara def getMascara(self): return self.__mascara def getMAC(self): self.__hostNic = self.getNicLista() return self.__hostNic[0].getMac() "@param tamanho: frame size" "@param destino: destination MAC" "@param pacote: packet to be send" def constroiQuadro(self, tamanho, destino, pacote): self.__novoQuadro = Quadro(self.getMAC(), tamanho) self.__novoQuadro.setDados(pacote) self.__novoQuadro.setDestino(destino) return self.__novoQuadro "@param quadro: frame to be send" def enviarQuadro(self, quadro): self.__hostNic = self.getNicLista() # Test if it's on if self.__hostNic[0].getLigado() == True: if self.__hostNic[0].getTDados() == True: # Send frame to your NIC self.__hostNic[0].recebeQuadro(quadro) # NIC Send frame to EnlacePP if self.__hostNic[0].enviaQuadroEnlace() == True: return True return False "@param quadro: received frame" "@param nic: self nic - unused" def receberQuadro(self, quadro, nic): pacote = quadro.getDados() pacPing = pacote.getDados() # Frame ARP-Solicita (ARP-Request) if pacote.getIPDestino() == self.__ip and quadro.getDestino() == "FFFFFFFFFFFF": self.enviarQuadro(self.__ARP.arpResponde(pacote.getIPOrigem(), quadro.getOrigem())) # Frame ARP-Responde (ARP-Answer) elif pacote.getIPDestino() == self.__ip and pacote.getDados() == "ARP-Responde": # Recupero meu quadro e envio para o destino com o MAC correto self.enviarQuadro(self.__ARP.recuperaQuadro(pacote.getIPOrigem(), quadro.getOrigem())) # Frame ICMP-Solicita (ICMP-Request) elif pacote.getIPDestino() == self.__ip and quadro.getTipo() == 2 and pacPing.getCodigo() == 0: self.enviarQuadro(self.__ICMP.respondeICMP(pacote.getIPOrigem(), quadro.getOrigem(), pacPing.getTtl())) # Send - PacotePing("reply",8) # Frame ICMP-Responde (ICMP-Answer) - PacotePing("request",0) elif pacote.getIPDestino() == self.__ip and quadro.getTipo() == 2 and pacPing.getCodigo() == 8: self.__ICMP.respostaPing(pacote.getIPOrigem(), pacPing.getTtl()) # Send - PacotePing("request",0) # Data frame elif pacote.getIPDestino() == self.__ip: self.__hostListaQuadros.append(quadro) # If IP and MAC origin do not empty && they are different to Host # Find out the IP and MAC origin and store in listaARP if pacote.getIPOrigem() != "" and pacote.getIPOrigem() != self.__ip and quadro.getOrigem() != "": self.setTabelaARP(pacote.getIPOrigem(), quadro.getOrigem()) #print "\n" "@param ip: new ip" "@param mac: new mac" def setTabelaARP(self, ip, mac): try: i = self.__listaARP.index(self.getTabelaARP(ip)) self.__listaARP.pop(i) self.__listaARP.insert(i, TabelaARP(ip, mac)) except: self.__listaARP.append(TabelaARP(ip, mac)) "@param ip: ip-key to search" def getTabelaARP(self, ip): for arp in self.__listaARP: if arp.getIP() == ip: return arp return None "@param ip: ip-key to remove" def removeTabelaARP(self, ip): for arp in self.__listaARP: if arp.getIP() == ip: try: self.__listaARP.remove(arp) return True except (ValueError): return False return False "@param tamanho: packet size" "@param ip: destination IP" "@param dados: data packet" def constroiPacote(self, tamanho, ip, dados): self.__novoPacote = Pacote(self.__ip, tamanho) self.__novoPacote.setIPDestino(ip) self.__novoPacote.setDados(dados) return self.__novoPacote "@param tamanho: packet size" "@param ip: destination IP" "@param dados: data packet" def enviarPacote(self, tamanho, ip, dados): # Search by IP the destination MAC in the table arpDestino = self.getTabelaARP(ip) # Make Packet pacote = self.constroiPacote(tamanho, ip, dados) # If knows origin MAC if arpDestino != None: return self.enviarQuadro(self.constroiQuadro(tamanho, arpDestino.getMAC(), pacote)) # Else is not in the list send ARP-Solicita (ARP-request) else: # Call ARP-Solicita (ARP-Request) # Make frame and send it return self.enviarQuadro(self.__ARP.arpSolicita(self.constroiQuadro(tamanho, "", pacote))) "@param ip: destination ping IP" def ping(self, ip): if self.__ip == "": return False self.__ICMP.iniciaPing(ip) return self.__ICMP.getPingResult() # return Ping final statistics def statisticsPing(self): return self.__ICMP.estatisticas() # reset Ping statistics def resetPing(self): self.__ICMP.resetStatistics()
def constroiPacote(self, tamanho, ip, dados): self.__novoPacote = Pacote(self.__ip, tamanho) self.__novoPacote.setIPDestino(ip) self.__novoPacote.setDados(dados) return self.__novoPacote
def pacote(): def pacote_opcao(): print('=================================') print("--> 1 - Voltar ao Menu Principal") print("--> 2 - Voltar ao Menu de Pacote") print("--> 3 - Encerrar Programa") opcao = int(input("Digite a opção desejada: ")) if opcao == 1: from Menu import Menu Menu.menu() if opcao == 2: pacote() if opcao == 3: exit() if opcao != 1 and opcao != 2: print("=====Digite uma opção valida=====") pacote_opcao() def consulta_pacote(): print('=================================') print("--> 1 - Consulta por CPF do Cliente") print("--> 2 - Consulta por ID") print("--> 3 - Listar Todos os Pacotes") opcao = int(input("Digite a opção desejada: ")) print('=================================') if opcao == 1: from Pacote import Pacote cpf = str(input("\nInforme o CPF do cliente: ")) Pacote.cons_pacote_cpf_cliente(cpf) pacote_opcao() if opcao == 2: from Pacote import Pacote id = str(input("\nInforme o ID do Pacote: ")) Pacote.cons_id_pacote(id) pacote_opcao() if opcao == 3: from Pacote import Pacote Pacote.listar_pacote() pacote_opcao() if opcao != 1 and opcao != 2 and opcao != 3: print("=====Digite uma opção valida=====") consulta_pacote() print('=================================') print("--> 1 - Para Cadastrar Pacote") print("--> 2 - Para Alterar Pacote") print("--> 3 - Para Excluir Pacote") print("--> 4 - Para Consultar Pacote") print("--> 5 - Para Voltar ao Menu Anterior") print("--> 6 - Encerrar o Programa") opcao = int(input("Digite a opção desejada: ")) if opcao == 1: from Pacote import Pacote Pacote.inserir_pacote(Pacote.preencher_pacote()) pacote_opcao() if opcao == 2: from Pacote import Pacote id = str(input("\nInforme o id do Pacote: ")) Pacote.atualizar_pacote(id, Pacote.preencher_pacote()) pacote_opcao() if opcao == 3: from Pacote import Pacote id = str(input("\nInforme o id do Pacote: ")) Pacote.excluir_pacote(id) pacote_opcao() if opcao == 4: consulta_pacote() if opcao == 5: from Menu import Menu Menu.menu() if opcao == 6: exit() if opcao != 1 and opcao != 2 and opcao != 3 and opcao != 4 and opcao != 5 and opcao != 6: print("=====Digite uma opção valida=====") pacote()
def enviar_dados(self, dados, sock, ip, porta): self.sock = sock tupla_conn = (ip, porta) pacote = Pacote() # Caso os dados sejam maiores que o MSS o pacote será segmentado if (len(dados) >= self.MSS): print("O pacote é muito grande e será (provavelmente) dividido em", len(dados) // self.MSS + 1, "segmentos.") self.cria_segmentos(dados, porta) else: self.multiplexacao(dados, porta) if not self.buffer: print("O buffer está vazio.") else: # Loop de envio e recebimento dos dados while self.indiceBuffer < len(self.buffer): cont = 0 if self.cwnd * self.MSS > self.ssthresh: self.exponencial = False pacotes_enviados = 0 # Loop de envio do que está no buffer de acordo com o cwnd while cont < self.cwnd: if self.indiceBuffer >= len(self.buffer): pacotes_enviados = cont break raw_pacote = json.dumps(self.buffer[self.indiceBuffer]) self.sock.sendto(raw_pacote, tupla_conn) self.indiceBuffer += 1 cont += 1 pacotes_enviados += 1 print(cont, "segmentos enviados.") cont = 0 # Loop de recebimento dos dados while cont < pacotes_enviados: while True: try: raw_pacote, conn = self.sock.recvfrom(self.MTU) break except: print("Timeout, iniciando a partida lenta") self.ssthresh = self.cwnd * self.MSS / 2 self.exponencial = True self.cwnd = 1 self.sock.sendto(raw_pacote, tupla_conn) pacote.conteudo = json.loads(raw_pacote) if self.ack - 1 == pacote.conteudo['seq']: if self.seq == pacote.conteudo['ack_n'] - 1: self.ack += len(pacote.conteudo['dados']) self.timeout = min(8, pacote.conteudo['RTT']) self.sock.settimeout(self.timeout) print("Novo valor de timeout:", self.timeout) print("ACK do pacote final recebido.") if self.exponencial: self.cwnd = self.cwnd * 2 else: self.cwnd = self.cwnd + 1 else: self.listaACKs.append(pacote.conteudo['ack_n']) if self.checaACKs(): if self.cwnd > 1: self.cwnd /= 2 self.ssthresh = self.cwnd * self.MSS / 2 self.exponencial = False for i in range(len(self.buffer)): if self.buffer[i][ 'seq'] == pacote.conteudo[ 'ack_n'] - 1: self.indiceBuffer = i break print("3 ACKs duplicados. Fast Recovery.") self.listaACKs = [] else: if self.exponencial: self.cwnd = self.cwnd * 2 else: self.cwnd = self.cwnd + 1 else: pacote.set([['ack', 1], ['ack_n', self.ack], ['seq', self.seq], ['dados', ''], ['RTT', time.time()]]) self.buffer.append(pacote.conteudo) print("Esse pacote não era esperado, enviando ACK.") cont += 1
def iniciar_servidor(self, ip, porta): tupla_conn = (ip, porta) self.sock.bind(tupla_conn) self.sock.settimeout(5) pacote = Pacote() montador = [] print("Olá! Servidor iniciando na porta", porta) # Recebe dados até que uma conexão seja estabelecida e posteriormente finalizada while True: cont = 0 # Loop que recebe os dados while cont < self.cwnd: if self.cwnd * self.MSS > self.ssthresh: self.exponencial = False while True: try: raw_pacote, conn = self.sock.recvfrom(self.MTU) break except: self.ssthresh = self.cwnd * self.MSS / 2 self.exponencial = True self.cwnd = 1 pacote.conteudo = json.loads(raw_pacote) pacote.set([['porta_orig', pacote.conteudo['porta_dest']], ['port_dest', conn[1]]]) if pacote.conteudo['flags']['syn']: print(conn[0], "deseja se conectar.") self.ack = pacote.conteudo['seq'] + 1 self.timeout = min( 8, round(4 * (time.time() - pacote.conteudo['RTT']), 4)) pacote.set([['ack', 1], ['rwnd', 32768], ['seq', self.seq], ['ack_n', self.ack], ['RTT', self.timeout]]) raw_pacote = json.dumps(pacote.conteudo) self.sock.settimeout(self.timeout) self.sock.sendto(raw_pacote, conn) print("Pacote SYN ACK enviado.") while True: try: raw_pacote, conn = self.sock.recvfrom(self.MTU) break except: print("Timeout, iniciando a partida lenta") self.ssthresh = self.cwnd * self.MSS / 2 self.exponencial = True self.cwnd = 1 self.sock.sendto(raw_pacote, tupla_conn) pacote.conteudo = json.loads(raw_pacote) if pacote.conteudo['flags']['ack'] and pacote.conteudo[ 'ack_n'] - 1 == self.seq: print("Conexão estabelecida!") else: print("Erro ao estabelecer conexão!") break elif pacote.conteudo['flags']['fin']: raw_pacote = json.dumps(pacote.conteudo) self.sock.sendto(raw_pacote, conn) print("O cliente gostaria de encerrar a conexão.") self.sock.close() print("Conexão encerrada.") exit() else: if self.ack - 1 == pacote.conteudo['seq']: print("Pacote recebido de tamanho", len(pacote.conteudo['dados'])) if pacote.conteudo['flags']['ack']: if self.seq == pacote.conteudo['ack_n'] - 1: self.ack += len(pacote.conteudo['dados']) #self.buffer.append(pacote.conteudo) montador.append(pacote.conteudo['dados']) self.timeout = min( 8, round( 4 * (time.time() - pacote.conteudo['RTT']), 4)) pacote.set([['ack', 1], ['ack_n', self.ack], ['seq', self.seq], ['dados', ''], ['RTT', self.timeout]]) self.buffer.append( pacote.conteudo) #Adicionado self.seq += len(pacote.conteudo['dados']) print("Remontando pacote.") print( "Numero de bytes após remontagem do pacote:", len("".join(montador))) # Trocar print("Primeiros 100 caracteres: ", "".join(montador)[0:100]) if self.exponencial: self.cwnd = self.cwnd * 2 else: self.cwnd = self.cwnd + 1 montador = [] break else: self.listaACKs.append(pacote.conteudo['ack_n']) if self.checaACKs() == True: if self.cwnd > 1: self.cwnd /= 2 self.ssthresh = self.cwnd * self.MSS / 2 for i in range(len(self.buffer)): if self.buffer[i][ 'ack_n'] == pacote.conteudo[ 'ack_n'] - 1: self.indiceBuffer = i print("3 ACKs duplicados. Fast Recovery.") else: self.ack += len(pacote.conteudo['dados']) montador.append(pacote.conteudo['dados']) pacote.set([['ack_n', self.ack], ['seq', self.seq], ['ack', 0], ['dados', '']]) self.buffer.append(pacote.conteudo) if self.exponencial: self.cwnd = self.cwnd * 2 else: self.cwnd = self.cwnd + 1 print( "O pacote é um segmento, esperando mais dados..." ) else: pacote.set([['ack', 1], ['ack_n', self.ack], ['seq', self.seq], ['dados', '']]) self.buffer.append(pacote.conteudo) '''raw_pacote = json.dumps(pacote.conteudo) self.sock.sendto(raw_pacote, conn)''' print("O pacote não era esperado, enviando ACK.") self.listaACKs.append(self.ack) if self.checaACKs(): if self.cwnd > 1: self.cwnd /= 2 self.ssthresh = self.cwnd * self.MSS / 2 self.exponencial = False print( "Foram enviados 3 ACKs duplicados, cortando janela." ) self.listaACKS = [] cont += 1 pacotes_recebidos = cont + 1 cont = 0 if not self.buffer: print("O buffer está vazio.") else: # Loop que envia os dados de acordo com a cwnd while self.indiceBuffer < len(self.buffer): while cont < pacotes_recebidos: if self.indiceBuffer >= len(self.buffer): break raw_pacote = json.dumps(self.buffer[self.indiceBuffer]) self.sock.sendto(raw_pacote, conn) self.indiceBuffer += 1 cont += 1 print("Enviados", cont, "ACK's")
def CriaPacotes(texto): ''' forma uma lista de pacotes que contem todos os pacotes que serao enviados ''' numeroSequencia = 0 pacotes = [] while texto: pacote = Pacote() #Forma o pacote pacote.numeroSequencia = numeroSequencia pacote.ack = 0 #Envia de 20 em 20 caracteres pacote.data = texto[:20] pacote.sair = 0 pacote.checksum = pacote.CalculaChecksum(texto[:20]) #adciona o pacote na lista de pacotes pacotes.append(pacote) texto = texto[20:] numeroSequencia += 1 #Forma o pacote para sair, a unica coisa que importa aqui é sair = 1 pacote = Pacote() pacote.numeroSequencia = numeroSequencia pacote.checksum = 0 pacote.texto = '' pacote.sair = 1 pacotes.append(pacote) return pacotes
def Servidor(args): if len(args) != 2: print 'Entrada errada. execução se da por:\n\tpython emissor.py <porta>' # <nome_arquivo>' sys.exit() #recebe a porta pela linha de comando port = int(args[1]) #Nao consegui fazer o cliente pedir o arquivo, tem que entrar com o nome #nomeArquivo = args[2] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(("", port)) pacoteEnviar = Pacote() pacoteRecebido = Pacote() janela = 3 tripleNack = [] print 'Esperando o cliente conectar' msg, addr = RecebePacote(s) print msg.data print 'Descobri o endereco do cliente: ', addr for i in range(janela): tripleNack.append(0) texto = LeArquivo(msg.data) if texto == False: print 'Arquivo não existe ou não tem permissão para leitura:\n\tVerifique se o arquivo existe\n\tTente mudar a permissao (chmod)' print 'saindo...' pacoteEnviar.sair = 1 pacotes = [] pacotes.append(pacoteEnviar) #sys.exit() else: pacotes = CriaPacotes(texto) #Descobre o endereço do cliente nackAntigo = 0 nack = 0 #Logica do rdt send while nackAntigo < len(pacotes): # Can we send a packet, do we need to send pkt if nack < janela and (nack + nackAntigo) < len(pacotes): EnviaPacote(pacotes[nackAntigo + nack], s, addr) print 'Enviando pacote ', pacotes[nackAntigo + nack].numeroSequencia nack += 1 #pacoteRecebido, addr = RecebePacote(s) sleep(0.2) else: #Espera pelos acks do cliente ready = select.select([s], [], [], TIMEOUT) if ready[0]: pacoteRecebido, addr = RecebePacote(s) else: # Janela encheu print "Atingiu tempo limite, reenviando" nack = 0 print "Número de sequencia recebido: ", pacoteRecebido.numeroSequencia, ", Ack conhecido:", nackAntigo if pacoteRecebido.numeroSequencia == nackAntigo: tripleNack[nackAntigo % janela] = 0 nackAntigo += 1 nack -= 1 else: tripleNack[nackAntigo % janela] += 1 if tripleNack[nackAntigo % janela] == 3: tripleNack[nackAntigo % janela] = 0 nack = 0 # Close server connection and exit successfully s.close() sys.exit(0)
def RecebePacote(s): ''' Recebe o pacote e coloca em um formato mais facil de trabalhar''' pacoteRecebido = Pacote() msg, addr = s.recvfrom(4096) pacoteRecebido.ToPacote(msg) return pacoteRecebido, addr
def Servidor(args): if len(args) != 2: print 'Entrada errada. execução se da por:\n\tpython emissor.py <porta>'# <nome_arquivo>' sys.exit() #recebe a porta pela linha de comando port = int(args[1]) #Nao consegui fazer o cliente pedir o arquivo, tem que entrar com o nome #nomeArquivo = args[2] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(("", port)) pacoteEnviar = Pacote() pacoteRecebido = Pacote() janela = 3 tripleNack= [] print 'Esperando o cliente conectar' msg, addr = RecebePacote(s) print msg.data print 'Descobri o endereco do cliente: ', addr for i in range(janela): tripleNack.append(0) texto = LeArquivo(msg.data) if texto == False: print 'Arquivo não existe ou não tem permissão para leitura:\n\tVerifique se o arquivo existe\n\tTente mudar a permissao (chmod)' print 'saindo...' pacoteEnviar.sair = 1 pacotes = [] pacotes.append(pacoteEnviar) #sys.exit() else: pacotes = CriaPacotes(texto) #Descobre o endereço do cliente nackAntigo = 0 nack = 0 #Logica do rdt send while nackAntigo < len(pacotes): # Can we send a packet, do we need to send pkt if nack < janela and (nack + nackAntigo) < len(pacotes): EnviaPacote(pacotes[nackAntigo + nack], s, addr) print 'Enviando pacote ', pacotes[nackAntigo + nack].numeroSequencia nack += 1 #pacoteRecebido, addr = RecebePacote(s) sleep(0.2) else: #Espera pelos acks do cliente ready = select.select([s], [], [], TIMEOUT) if ready[0]: pacoteRecebido, addr = RecebePacote(s) else: # Janela encheu print "Atingiu tempo limite, reenviando" nack = 0 print "Número de sequencia recebido: ", pacoteRecebido.numeroSequencia,", Ack conhecido:", nackAntigo if pacoteRecebido.numeroSequencia == nackAntigo: tripleNack[nackAntigo%janela]=0 nackAntigo += 1 nack -= 1 else: tripleNack[nackAntigo%janela]+=1 if tripleNack[nackAntigo%janela]==3: tripleNack[nackAntigo%janela]=0 nack = 0 # Close server connection and exit successfully s.close() sys.exit(0)
class Host(EquipamentoRede): def __init__(self): EquipamentoRede.__init__(self) self.__ARP = ARP(self) self.__ICMP = ICMP(self) self.__novoQuadro = None self.__novoPacote = None self.__hostNic = [] self.__hostListaQuadros = [] self.__listaARP = [] self.__ip = "" self.__mascara = "" "@param ip: Host IP" def setIP(self, ip): self.__ip = ip def getIP(self): return self.__ip "@param mascara: Host Subnet mask" def setMascara(self, mascara): self.__mascara = mascara def getMascara(self): return self.__mascara def getMAC(self): self.__hostNic = self.getNicLista() return self.__hostNic[0].getMac() "@param tamanho: frame size" "@param destino: destination MAC" "@param pacote: packet to be send" def constroiQuadro(self, tamanho, destino, pacote): self.__novoQuadro = Quadro(self.getMAC(), tamanho) self.__novoQuadro.setDados(pacote) self.__novoQuadro.setDestino(destino) return self.__novoQuadro "@param quadro: frame to be send" def enviarQuadro(self, quadro): self.__hostNic = self.getNicLista() # Test if it's on if self.__hostNic[0].getLigado() == True: if self.__hostNic[0].getTDados() == True: # Send frame to your NIC self.__hostNic[0].recebeQuadro(quadro) # NIC Send frame to EnlacePP if self.__hostNic[0].enviaQuadroEnlace() == True: return True return False "@param quadro: received frame" "@param nic: self nic - unused" def receberQuadro(self, quadro, nic): pacote = quadro.getDados() pacPing = pacote.getDados() # Frame ARP-Solicita (ARP-Request) if pacote.getIPDestino() == self.__ip and quadro.getDestino( ) == "FFFFFFFFFFFF": self.enviarQuadro( self.__ARP.arpResponde(pacote.getIPOrigem(), quadro.getOrigem())) # Frame ARP-Responde (ARP-Answer) elif pacote.getIPDestino() == self.__ip and pacote.getDados( ) == "ARP-Responde": # Recupero meu quadro e envio para o destino com o MAC correto self.enviarQuadro( self.__ARP.recuperaQuadro(pacote.getIPOrigem(), quadro.getOrigem())) # Frame ICMP-Solicita (ICMP-Request) elif pacote.getIPDestino() == self.__ip and quadro.getTipo( ) == 2 and pacPing.getCodigo() == 0: self.enviarQuadro( self.__ICMP.respondeICMP(pacote.getIPOrigem(), quadro.getOrigem(), pacPing.getTtl())) # Send - PacotePing("reply",8) # Frame ICMP-Responde (ICMP-Answer) - PacotePing("request",0) elif pacote.getIPDestino() == self.__ip and quadro.getTipo( ) == 2 and pacPing.getCodigo() == 8: self.__ICMP.respostaPing(pacote.getIPOrigem(), pacPing.getTtl()) # Send - PacotePing("request",0) # Data frame elif pacote.getIPDestino() == self.__ip: self.__hostListaQuadros.append(quadro) # If IP and MAC origin do not empty && they are different to Host # Find out the IP and MAC origin and store in listaARP if pacote.getIPOrigem() != "" and pacote.getIPOrigem( ) != self.__ip and quadro.getOrigem() != "": self.setTabelaARP(pacote.getIPOrigem(), quadro.getOrigem()) #print "\n" "@param ip: new ip" "@param mac: new mac" def setTabelaARP(self, ip, mac): try: i = self.__listaARP.index(self.getTabelaARP(ip)) self.__listaARP.pop(i) self.__listaARP.insert(i, TabelaARP(ip, mac)) except: self.__listaARP.append(TabelaARP(ip, mac)) "@param ip: ip-key to search" def getTabelaARP(self, ip): for arp in self.__listaARP: if arp.getIP() == ip: return arp return None "@param ip: ip-key to remove" def removeTabelaARP(self, ip): for arp in self.__listaARP: if arp.getIP() == ip: try: self.__listaARP.remove(arp) return True except (ValueError): return False return False "@param tamanho: packet size" "@param ip: destination IP" "@param dados: data packet" def constroiPacote(self, tamanho, ip, dados): self.__novoPacote = Pacote(self.__ip, tamanho) self.__novoPacote.setIPDestino(ip) self.__novoPacote.setDados(dados) return self.__novoPacote "@param tamanho: packet size" "@param ip: destination IP" "@param dados: data packet" def enviarPacote(self, tamanho, ip, dados): # Search by IP the destination MAC in the table arpDestino = self.getTabelaARP(ip) # Make Packet pacote = self.constroiPacote(tamanho, ip, dados) # If knows origin MAC if arpDestino != None: return self.enviarQuadro( self.constroiQuadro(tamanho, arpDestino.getMAC(), pacote)) # Else is not in the list send ARP-Solicita (ARP-request) else: # Call ARP-Solicita (ARP-Request) # Make frame and send it return self.enviarQuadro( self.__ARP.arpSolicita(self.constroiQuadro( tamanho, "", pacote))) "@param ip: destination ping IP" def ping(self, ip): if self.__ip == "": return False self.__ICMP.iniciaPing(ip) return self.__ICMP.getPingResult() # return Ping final statistics def statisticsPing(self): return self.__ICMP.estatisticas() # reset Ping statistics def resetPing(self): self.__ICMP.resetStatistics()