Exemple #1
0
class SecurityExtension(scapy.Packet):
    name = "SCION Security Extension"
    fields_desc = [
        scapy.BitEnumField('next_hdr', None, 8, scapy.IP_PROTOS),
        scapy.ByteField('hdr_len', None),
        scapy.XByteField('extType', 0x2),
        scapy.ByteEnumField("secMode", 0x0, {
            0x0: "AES-CMAC",
            0x1: "HMAC_SHA256",
            0x2: "Ed25519",
            0x3: "GCM_AES128"
        }),
        scapy.XBitField('metadata', 0xffffffff, 4 * 8),
        scapy.MultipleTypeField([
            (scapy.XBitField('authenticator', None,
                             16 * 8), lambda pkt: pkt.secMode == 0x0),
            (scapy.XBitField('authenticator', None,
                             32 * 8), lambda pkt: pkt.secMode == 0x1),
            (scapy.XBitField('authenticator', None,
                             64 * 8), lambda pkt: pkt.secMode == 0x2),
            (scapy.XBitField('authenticator', None,
                             16 * 8), lambda pkt: pkt.secMode == 0x3),
        ], scapy.StrField("authenticator", None)),
    ]

    def extract_padding(self, p):
        # TODO fix when removing hard-coded v4
        return "", p

    def post_build(self, pkt, pay):
        if self.hdr_len == None:
            self.hdr_len = len(pkt)
            pkt = pkt[:1] + struct.pack('B', int(self.hdr_len / 8)) + pkt[2:]
        return pkt + pay
Exemple #2
0
class CIP_RespAttributesAll(scapy_all.Packet):
    """Content of Get_Attribute_All response"""
    fields_desc = [
        scapy_all.StrField("value", None),
    ]
Exemple #3
0
class CIP_RespAttributesList(scapy_all.Packet):
    """List of attributes in Get_Attribute_List responses

    There are "count" attributes in the "content" field, in the following format:
        * attribute ID (INT, LEShortField)
        * status (INT, LEShortField, 0 means success)
        * value, type and length depends on the attribute and thus can not be known here
    """
    fields_desc = [
        scapy_all.LEShortField("count", 0),
        scapy_all.StrField("content", ""),
    ]

    def split_guess(self, attr_list, verbose=False):
        """Split the content of the Get_Attribute_List response with the known attribute list

        Return a list of (attr, value) tuples, or None if an error occured
        """
        content = self.content
        offset = 0
        idx = 0
        result = []
        while offset < len(content):
            attr, status = struct.unpack("<HH", content[offset:offset + 4])
            if attr not in attr_list:
                if verbose:
                    sys.stderr.write("Error: Get_Attribute_List response contains an unknown attribute\n")
                    sys.stderr.write("... all attrs " + ','.join(hex(a) for a in attr_list) + '\n')
                    sys.stderr.write(utils.hexdump(content[offset:], indentlvl="... ") + "\n")
                return
            if attr != attr_list[idx]:
                if verbose:
                    sys.stderr.write("Error: attr {:#x} not in position {} of attr list\n".format(attr, idx))
                    sys.stderr.write("... all attrs " + ','.join(hex(a) for a in attr_list) + '\n')
                return
            offset += 4
            attr_len = None
            if idx == len(attr_list) - 1:
                # Last attribute
                attr_len = len(content) - offset
            else:
                # Find next attribute header
                nexthdr = struct.pack('<HH', attr_list[idx + 1], 0)
                for i in range(offset + 1, len(content) - 4):
                    if content[i:i + 4] == nexthdr:
                        attr_len = i - offset
                        break
            if attr_len is None:
                if verbose:
                    sys.stderr.write("Error: length not found. Here is the remaining\n")
                    sys.stderr.write("... all attrs " + ','.join(hex(a) for a in attr_list) + '\n')
                    sys.stderr.write(utils.hexdump(content[offset:], indentlvl="... ") + "\n")
                return
            result.append((attr, content[offset:offset + attr_len]))
            offset += attr_len
            idx += 1
        return result

    def split_guess_todict(self, attr_list, verbose=False):
        """Same as split_guess, but return a dict instead of a list of tuples"""
        result = self.split_guess(attr_list, verbose)
        if result is None:
            return
        # assert unicity of attributes IDs
        assert len(frozenset(x[0] for x in result)) == len(result)
        return dict(result)
Exemple #4
0
class CIP_RespSingleAttribute(scapy_all.Packet):
    """An attribute... not much information about it"""
    fields_desc = [scapy_all.StrField("value", None)]