Exemple #1
0
    def __raw_recv(self, datagrama):
        dscp, ecn, identification, flags, frag_offset, ttl, proto, \
           src_addr, dst_addr, payload = read_ipv4_header(datagrama)
        if dst_addr == self.meu_endereco:
            # atua como host
            if proto == IPPROTO_TCP and self.callback:
                self.callback(src_addr, dst_addr, payload)
        else:
            # atua como roteador
            next_hop = self._next_hop(dst_addr)
            # TODO: Trate corretamente o campo TTL do datagrama
            vihl, dscpecn, total_len, identification, flagsfrag, ttl, proto, \
                checksum, src_addr, dest_addr = \
                struct.unpack('!BBHHHBBHII', datagrama[:20])
            ttl -= 1

            datagrama2 = struct.pack('!BBHHHBBH', (4 << 4) + 5, 0,
                                     len(datagrama[20:]) + 20, 0, 0, ttl, 6,
                                     0) + datagrama[12:16] + datagrama[16:20]
            data_checksum = mytcputils.calc_checksum(datagrama2)
            print(ttl)
            if ttl > 0:

                datagrama2 = struct.pack(
                    '!BBHHHBBH', (4 << 4) + 5, 0,
                    len(datagrama[20:]) + 20, 0, 0, ttl, 6,
                    data_checksum) + datagrama[12:16] + datagrama[16:20]

                self.enlace.enviar(datagrama2, next_hop)

            else:
                #print(self.meu_endereco)
                #print(addr2str(datagrama[12:16]))
                #print(addr2str(datagrama[16:20]))
                #mytcputils.str2addr(self.meu_endereco)

                datafake = struct.pack('!BBHHHBBH', (4 << 4) + 5, 0, 20 + 8 + max(28, len(datagrama[20:])), 0, 0, 64, 1, 0) + \
                    mytcputils.str2addr(self.meu_endereco) + datagrama[12:16]

                data_checksum = mytcputils.calc_checksum(datafake)

                outro_checksum = mytcputils.calc_checksum(
                    struct.pack('BBHI', 11, 0, 0, 0) + datagrama[:28])
                print(outro_checksum)

                print(struct.pack('!BBHI', 11, 0, outro_checksum, 0))
                datafake = struct.pack('!BBHHHBBH',  (4 << 4) + 5, 0, 20 + 8 + max(28, len(datagrama[20:])), 0, 0, 64, 1, data_checksum) + \
                    mytcputils.str2addr(self.meu_endereco) + datagrama[12:16] + struct.pack('!BBHI', 11, 0, outro_checksum, 0) + datagrama[:28]
                print(len(datafake))
                self.enlace.enviar(datafake, next_hop)
Exemple #2
0
def make_ipv4_header(src_addr, dest_addr, payload):
    # https://en.wikipedia.org/wiki/IPv4#Header
    # min header size = 16 octets / 126 bytes
    # Default values
    # 1st octet
    ver = (4 << 4)
    ihl = 5
    # 2nd octet
    dscp = ecn = 0
    # 3rd octet
    header_len = 20 + len(payload)
    # 4th octet
    identification = 0
    # 5th octet
    flags = (0 << 13)
    # 6th octet
    ttl = 64
    # 7th octet
    proto = IPPROTO_TCP
    # 8th & 9th octet
    checksum = 0
    # 10th to 12th octet
    src_addr = socket.inet_aton(src_addr)
    # 13th to 16th octet
    dest_addr = socket.inet_aton(dest_addr)
    pseudo = struct.pack('!BBHHHBBH4s4s', ver + ihl, dscp + ecn, header_len, identification, \
        flags, ttl, proto, checksum, src_addr, dest_addr)
    checksum = calc_checksum(pseudo[:4*ihl])
    pack = struct.pack('!BBHHHBBH4s4s', ver + ihl, dscp + ecn, header_len, identification, \
        flags, ttl, proto, checksum, src_addr, dest_addr) + payload
    return pack
Exemple #3
0
def make_ipv4_header(size,
                     src_addr,
                     dest_addr,
                     dscp=None,
                     ecn=None,
                     identification=None,
                     flags=None,
                     frag_offset=None,
                     ttl=255,
                     proto=None,
                     verify_checksum=False):
    version = 4 << 4
    ihl = IHL
    vihl = version + ihl

    if dscp is None:
        dscp = 0 << 6
    if ecn is None:
        ecn = 0

    dscpecn = dscp + ecn

    total_length = twos_comp(size + 20, 16)

    if identification is None:
        identification = twos_comp(randint(0, 2**16), 16)

    if flags is None:
        flag_rsv = 0
        flag_dtf = 0
        flag_mrf = 0
        flags = (flag_rsv << 15) | (flag_dtf << 14) | (flag_mrf << 13)

    if frag_offset is None:
        frag_offset = 0

    flags |= frag_offset

    ttl = twos_comp(ttl, 8)

    if proto is None:
        proto = IPPROTO_TCP

    checksum = 0
    src_addr = str2addr(src_addr)
    dest_addr = str2addr(dest_addr)
    header = struct.pack('!bbhhhbbh', vihl, dscpecn, total_length,
                         identification, flags, ttl, proto,
                         checksum) + src_addr + dest_addr

    if verify_checksum:
        checksum = twos_comp(calc_checksum(header[:4 * ihl]), 16)
        header = struct.pack('!bbhhhbbh', vihl, dscpecn, total_length,
                             identification, flags, ttl, proto,
                             checksum) + src_addr + dest_addr

    return header
Exemple #4
0
    def _rdt_rcv(self, src_addr, dst_addr, segment):
        src_port, dst_port, seq_no, ack_no, \
            flags, _, _, _ = read_header(segment)

        if dst_port != self.porta:
            # Ignora segmentos que não são destinados à porta do nosso servidor
            return

	try:
            pseudohdr = str2addr(src_addr) + str2addr(dst_addr) + \
                struct.pack('!HH', 0x0006, len(segment))
            if calc_checksum(pseudohdr + segment) != 0:
                print('descartando segmento com checksum incorreto')
                return
Exemple #5
0
    def enviar(self, segmento, dest_addr):
        """
        Envia segmento para dest_addr, onde dest_addr é um endereço IPv4
        (string no formato x.y.z.w).
        """

        next_hop = self._next_hop(dest_addr)
        print("DEST_ADDR {0} NEXT_HOP {1} MEU_END {2}".format(
            dest_addr, next_hop, self.meu_endereco))

        dest = dest_addr.split('.')
        destino = [int(dest[0]), int(dest[1]), int(dest[2]), int(dest[3])]
        val = destino[3] << 24
        val += destino[2] << 16
        val += destino[1] << 8
        val += destino[0] << 0
        val_dst = val

        val_dst = mytcputils.str2addr(dest_addr)

        dest = self.meu_endereco.split('.')
        destino = [int(dest[0]), int(dest[1]), int(dest[2]), int(dest[3])]
        val = destino[3] << 24
        val += destino[2] << 16
        val += destino[1] << 8
        val += destino[0] << 0
        val_src = val

        val_src = mytcputils.str2addr(self.meu_endereco)

        version = 4
        ihl = 5

        datagrama = struct.pack('!BBHHHBBH', (version << 4) + ihl, 0,
                                len(segmento) + 20, 0, 0, 64, 6,
                                0) + val_src + val_dst
        data_checksum = mytcputils.calc_checksum(datagrama)
        datagrama = struct.pack('!BBHHHBBH', (version << 4) + ihl, 0,
                                len(segmento) + 20, 0, 0, 64, 6,
                                data_checksum) + val_src + val_dst + segmento

        #datagrama = ((4 << 4) + 5).to_bytes(1, 'little') + (0).to_bytes(7, 'little') + (64).to_bytes(1, 'little') + (0).to_bytes(7, 'little')  + datagrama
        # TODO: Assumindo que a camada superior é o protocolo TCP, monte o
        # datagrama com o cabeçalho IP, contendo como payload o segmento.
        self.enlace.enviar(datagrama, next_hop)
Exemple #6
0
def read_ipv4_header(datagram, verify_checksum=False):
    # https://en.wikipedia.org/wiki/IPv4#Header
    vihl, dscpecn, total_len, identification, flagsfrag, ttl, proto, \
        checksum, src_addr, dest_addr = \
        struct.unpack('!BBHHHBBHII', datagram[:20])
    version = vihl >> 4
    ihl = vihl & 0xf
    assert version == 4
    dscp = dscpecn >> 2
    ecn = dscpecn & 0b11
    flags = flagsfrag >> 13
    frag_offset = flagsfrag & 0x1fff
    src_addr = addr2str(datagram[12:16])
    dst_addr = addr2str(datagram[16:20])
    if verify_checksum:
        assert calc_checksum(datagram[:4*ihl]) == 0
    payload = datagram[4*ihl:total_len]

    return dscp, ecn, identification, flags, frag_offset, ttl, proto, \
           src_addr, dst_addr, payload