예제 #1
0
    def _dissect(self, buf):
        # update dynamic header parts. buf: 1010???? -clear reserved-> 1010 -> *4
        ol = ((buf[12] >> 4) << 2) - 20  # dataoffset - TCP-standard length

        if ol > 0:
            # parse options, add offset-length to standard-length
            opts_bytes = buf[20:20 + ol]
            self._init_triggerlist("opts", opts_bytes, self._parse_opts)
        elif ol < 0:
            raise Exception("invalid header length")

        ports = [unpack_H(buf[0:2])[0], unpack_H(buf[2:4])[0]]

        try:
            # source or destination port should match
            # logger.debug("TCP handler: %r" % self._id_handlerclass_dct[TCP])
            htype = [x for x in ports
                     if x in self._id_handlerclass_dct[TCP]][0]
            #logger.debug("TCP: trying to set handler, type: %d = %s" %
            #(type, self._id_handlerclass_dct[TCP][type]))
            self._init_handler(htype, buf[20 + ol:])
        except:
            # no type found
            pass
        return 20 + ol
예제 #2
0
		def _dissect(self, buf):
			# Withdrawn Routes
			#logger.debug("Dissecting BGP update")
			off = 4
			off_end = off + unpack_H(buf[:2])[0]

			while off < off_end:
				rlen = 3 + 0
				route = Route(buf[off:])
				self.wroutes.append(route)
				off += rlen

			# Path attributes
			off_end = off + unpack_H(buf[2:4])[0]
			#logger.debug("Unpacking attributes")

			while off < off_end:
				alen = 3 + buf[off + 2]
				#logger.debug("bytes for attribute: %r" % buf[off: off + alen])
				attr = BGP.Update.Attribute(buf[off: off + alen])
				self.pathattrs.append(attr)
				off += alen

			# Announced routes
			off_end = len(buf)
			#logger.debug("Unpacking routes")

			while off + 3 <= off_end:
				rlen = 3 + 0
				#logger.debug("bytes for route: %r" % buf[off:off + rlen])
				route = Route(buf[off: off + rlen])
				self.anncroutes.append(route)
				off += rlen
			#logger.debug("Finished, off=%d off_end=%d" % (off, off_end))
			return off
예제 #3
0
        def _dissect(self, buf):
            # withdrawn Routes
            off = 4
            off_end = off + unpack_H(buf[:2])[0]

            while off < off_end:
                rlen = 3 + 0
                route = Route(buf[off:])
                self.wroutes.append(route)
                off += rlen

            # path attributes
            off_end = off + unpack_H(buf[2:4])[0]
            #logger.debug("unpacking attributes")

            while off < off_end:
                alen = 3 + buf[off + 2]
                #logger.debug("bytes for attribute: %r" % buf[off: off + alen])
                attr = BGP.Update.Attribute(buf[off:off + alen])
                self.pathattrs.append(attr)
                off += alen

            # announced routes
            off_end = len(buf)
            #logger.debug("unpacking routes")

            while off < off_end:
                rlen = 3 + 0
                #logger.debug("bytes for route: %r" % buf[off:off + rlen])
                route = Route(buf[off:off + rlen])
                self.anncroutes.append(route)
                off += rlen
            return off
예제 #4
0
 def _dissect(self, buf):
     pnamelen = unpack_H(buf[:2])[0]
     self.pname = buf[2:2 + pnamelen]
     off_clientidlen = 2 + pnamelen + 1 + 1 + 2
     clientidlen = unpack_H(buf[off_clientidlen:off_clientidlen + 2])[0]
     off_clientid = off_clientidlen + 2
     self.clientid = buf[off_clientid:off_clientid + clientidlen]
     return 8 + pnamelen + clientidlen
예제 #5
0
파일: udp.py 프로젝트: wau/pypacker
	def _dissect(self, buf):
		ports = [unpack_H(buf[0:2])[0], unpack_H(buf[2:4])[0]]

		try:
			# source or destination port should match
			htype = [x for x in ports if x in pypacker.Packet._id_handlerclass_dct[UDP]][0]
			self._init_handler(htype, buf[8:])
		except:
			# no type found
			# logger.debug("could not parse type: %d because: %s" % (type, e))
			pass
		return 8
예제 #6
0
	def _dissect(self, buf):
		self.framectl = unpack_H(buf[0:2])[0]
		# logger.debug("ieee80211 bytes=%X, type/subtype is=%X/%X, handler=%r" %
		# 			(self.framectl, self.type, self.subtype,
		# 			 pypacker.Packet._id_handlerclass_dct[self.__class__][TYPE_FACTORS[self.type] + self.subtype]))
		self._init_handler(TYPE_FACTORS[self.type] + self.subtype, buf[4:])
		return 4
예제 #7
0
파일: lldp.py 프로젝트: wilixx/pypacker
def count_and_dissect_tlvs(buf):
    """
	Count and dissect TLVs. Return length of LLDP layer

	buf -- buffer to dissect
	return -- parsed_bytes_total, [(clz, bts), ...]
	"""
    shift = 0
    tlv_type, tlv_len = 1, 1
    clz_bts_list = []

    while (tlv_type | tlv_len) != 0:
        type_and_len = unpack_H(buf[shift:shift + TLV_HEADER_LEN])[0]
        # get tlv length and type
        tlv_type = (type_and_len & TYPE_MASK) >> LENGTH_FIELD_BITS
        tlv_len = type_and_len & LENGTH_MASK

        if tlv_type != ORG_SPEC_TYPE:
            clz = LLDP_TLV_CLS.get(tlv_type, LLDPGeneric)
        else:
            oui_subtype = unpack_I(
                buf[shift + TLV_HEADER_LEN:shift + ORG_SPEC_HEADER_LEN +
                    TLV_HEADER_LEN])[0]
            oui = (oui_subtype & OUI_MASK) >> SUBTYPE_LEN_BITS
            subtype = oui_subtype & SUBTYPE_MASK
            clz = LLDP_ORG_SPEC_TLV_CLS.get((oui, subtype), LLDPOrgSpecGeneric)
        # get body bytes
        tlv_body = buf[shift:tlv_len + shift + TLV_HEADER_LEN]
        # update shift to begin of next TLV (TLV_HEADER_LEN:2 + content:x)
        shift += TLV_HEADER_LEN + tlv_len
        clz_bts_list.append((clz, tlv_body))

    return shift, clz_bts_list
예제 #8
0
	def _dissect(self, buf):
		"""
		_dissect(...) must be overwritten if the header format can change
		from its original format. This is generally the case when
		- using TriggerLists (see ip.IP)
		- a simple field could get deactivated (see ethernet.Ethernet -> vlan)
		- using dynamic fields (see dns.DNS -> Query -> name)

		In NewProtocol idk can get deactivated, options is a TriggerList
		and yolo is a dynamic field so _dissect(...) needs to be defined.
		"""
		# Header fields are not yet accessible in _dissect(...) so basic information
		# (type info, header length, bytes of dynamic content etc) has to be parsed manually.
		# Extract type information of next layer, here it can only be 0x66 but we extract it anyway.
		higher_layer_type = buf[0]
		# logger.debug("Found type: 0x%X" % higher_layer_type)
		total_header_length = unpack_H(buf[9: 11])[0]
		yolo_len = 4 if higher_layer_type == TYPE_VALUE_IP else 5  # length of yolo is derived from type
		# logger.debug("Found length: %d, yolo=%d" % (total_header_length, yolo_len))
		tl_bts = buf[12 + yolo_len: total_header_length]  # options are the the end of the header
		# logger.debug("Bytes for TriggerList: %r" % tl_bts)
		# self._init_triggerlist(...) should be called to initiate TriggerLists,
		# otherwise the list will be empty. _parse_options(...) is a callback returning a list
		# of [raw bytes | key/value tuples | Packets] parsed from tl_bts.
		self._init_triggerlist("options", tl_bts, NewProtocol._parse_options)

		# self._init_handler(...) must be called to initiate the handler of the next
		# upper layer and makes it accessible (eg via ethernet[ip.IP]).
		# Which handler to be initialized generally depends on the type information (here higher_layer_type)
		# found in the current layer (see layer12/ethernet.Ethernet -> type).
		# Here higher_layer_type can become the value 0x66 (defined by __handler__ field) and
		# as a result ip.IP will be created as upper layer using the bytes given by "buf[total_header_length:]".
		self._init_handler(higher_layer_type, buf[total_header_length:])
		return total_header_length
예제 #9
0
def fletcher32(data_to_checksum, amount_words):
    # 1 word = 2 Bytes
    sum1 = 0xFFFF
    sum2 = 0xFFFF
    datapos = 0

    while amount_words > 0:
        tlen = 359 if amount_words > 359 else amount_words
        amount_words -= tlen

        while tlen > 0:
            # sum1 += unpack_word_be(data_to_checksum[datapos:datapos+2])[0]
            # print("%d" % sum1)
            sum1 += unpack_H(data_to_checksum[datapos:datapos + 2])[0]
            datapos += 2
            sum2 += sum1
            # print("%d" % sum1)
            # print("%d" % sum2)
            # print("--")
            tlen -= 1
        sum1 = (sum1 & 0xFFFF) + (sum1 >> 16)
        sum2 = (sum2 & 0xFFFF) + (sum2 >> 16)
    # Second reduction step to reduce sums to 16 bits
    sum1 = (sum1 & 0xFFFF) + (sum1 >> 16)
    sum2 = (sum2 & 0xFFFF) + (sum2 >> 16)
    return (sum2 << 16) | sum1
예제 #10
0
 def _dissect(self, buf):
     if buf[0] == 170:  # = 0xAA
         # SNAP is following ctrl
         htype = unpack_H(buf[5:7])[0]
         self._init_handler(htype, buf[8:])
     else:
         # deactivate SNAP
         self.snap = None
     return 8
예제 #11
0
파일: dns.py 프로젝트: oranav/pypacker
 def _dissect(self, buf):
     name_end = DNS.get_dns_length(buf)
     self.name = buf[:name_end]
     # needed set format
     start = name_end + 8
     addr_len = unpack_H(buf[start:start + 2])[0]
     self.address = buf[start + 2:start + 2 + addr_len]
     # logger.debug("address: %s" % self.address)
     return start + 2 + addr_len
예제 #12
0
    def _parse_icmp6opt(buf):
        opts = []
        off = 0

        while off < len(buf):
            optlen = unpack_H(buf[1:3])[0] * 8
            opt = ICMP6.ICMPv6Opt(buf[off:off + optlen])
            opts.append(opt)
            off += optlen
        return opts
예제 #13
0
파일: ieee80211.py 프로젝트: wau/pypacker
	def _dissect(self, buf):
		#logger.debug("Starting to dissect")
		# self.type/self.subtype use self.framectl, no unpack will happen in dissect so this has
		# to be done manually
		self.framectl = unpack_H(buf[0:2])[0]
		#logger.debug("ieee80211 bytes=%X, type/subtype is=%X/%X, handler=%r" %
		#	(self.framectl, self.type, self.subtype,
		#	pypacker.Packet._id_handlerclass_dct[self.__class__][TYPE_FACTORS[self.type] + self.subtype]))
		self._init_handler(TYPE_FACTORS[self.type] + self.subtype, buf[4:])
		#logger.debug("Finished IEEE dissect")
		return 4
예제 #14
0
파일: ssl.py 프로젝트: wilixx/pypacker
    def __parse_extension(buf):
        extensions = []
        offset = 0
        buflen = len(buf)

        while offset < buflen:
            ext_content_len = unpack_H(buf[offset + 2:offset + 4])[0]
            ext_len = 4 + ext_content_len
            extensions.append(Extension(buf[offset:offset + ext_len]))
            offset += ext_len

        return extensions
예제 #15
0
	def _dissect(self, buf):
		offset = 1
		ppp_type = buf[0]

		if buf[0] & PFC_BIT == 0:
			ppp_type = unpack_H(buf[:2])[0]
			offset = 2
			self.p.append(buf[0:2])
		else:
			self.p.append(buf[0:1])
		self._init_handler(ppp_type, buf[offset:])
		return offset
예제 #16
0
파일: sctp.py 프로젝트: wilixx/pypacker
    def _dissect(self, buf):
        # parse chunks
        chunks = []
        off = 12
        blen = len(buf)

        # logger.debug("SCTP: parsing chunks")
        chunktype = -1

        # TODO: use lazy dissect, possible?
        while off + 4 < blen:
            dlen = unpack_H(buf[off + 2:off + 4])[0]
            # check for padding (this should be a data chunk)
            if off + dlen < blen:
                self.padding = buf[off + dlen:]
                # logger.debug("found padding: %s" % self.padding)

            chunk = Chunk(buf[off:off + dlen])
            # logger.debug("SCTP: Chunk; %s " % chunk)
            chunks.append(chunk)

            # get payload chunktype from DATA chunks
            if chunk.type == 0:
                chunktype = unpack_I(buf[off + chunk.header_len + 8:off +
                                         chunk.header_len + 8 + 4])[0]
                # logger.debug("got DATA chunk, chunktype: %d" % chunktype)
                # remove data from chunk: use bytes for handler
                chunk.body_bytes = b""
                off += len(chunk)
                # assume DATA is the last chunk
                break

            off += dlen

        self.chunks.extend(chunks)

        chunktype = unpack_H(buf[2:4])[0]
        self._init_handler(chunktype, buf[off:-len(self.padding)])
        return off
예제 #17
0
파일: stun.py 프로젝트: wau/pypacker
    def __parse_attrs(buf):
        attributes = []
        off = 0

        # t:2 l:2 v:x
        while off < len(buf):
            l_content = unpack_H(buf[off + 2:off + 4])[0]
            padding = (4 - (l_content % 4)) % 4
            l_total = l_content + padding + 2 + 2
            #logger.debug("STUN attr l_content: %d, padding: %d, value: %s" %
            #	 (l_content, padding, buf[off : off + l_total]))
            attributes.append(StunAttr(buf[off:off + l_total]))
            off += l_total
        return attributes
예제 #18
0
	def _dissect(self, buf):
		hlen = 2
		opcode = unpack_H(buf[: 2])
		# logger.debug("opcode: %d" % opcode)

		if opcode in OPCODES_DATA_ACK:
			pass
		elif opcode in OPCODES_READ_WRITE:
			self.block = None
			file, ttype = split_nullbyte(buf[2:], maxsplit=2)
			# logger.debug("file/ttype = %r / %r" % (file, ttype))
			self.file = file + b"\x00"
			self.ttype = ttype + b"\x00"
			hlen = 2 + len(self.file) + len(self.ttype)
		elif opcode == OP_ERR:
			pass
		return hlen
예제 #19
0
파일: ssl.py 프로젝트: wilixx/pypacker
    def _dissect(self, buf):
        # logger.debug("parsing SSL")
        # parse all records out of message
        # possible types are Client/Sevrer Hello, Change Cipher Spec etc.
        records = []
        offset = 0
        dlen = len(buf)

        # records is the only header so it's ok to avoid lazy dissecting
        while offset < dlen:
            record_len = unpack_H(buf[offset + 3:offset + 5])[0]
            record = Record(buf[offset:offset + 5 + record_len])
            records.append(record)
            offset += 5 + record_len
        #logger.debug("adding %d records", len(records))

        self.records.extend(records)
        return dlen
예제 #20
0
 def _dissect(self, buf):
     # needed set format
     addr_len = unpack_H(buf[10:12])[0]
     self.address = buf[12:12 + addr_len]
     # logger.debug("address: %s" % self.address)
     return 12 + addr_len
예제 #21
0
 def _get_mvflen_be(self):
     return unpack_H(pack_H_le(self.mvflen))[0]
예제 #22
0
 def _set_mvflen_be(self, val):
     self.mvflen = unpack_H(pack_H_le(val))[0]
예제 #23
0
 def _get_msgtype(self):
     typetmp = self.typeinfo & MASK_MSGTYPE_LE
     return unpack_H(pack_H_le(typetmp))[0]
예제 #24
0
	def _dissect(self, buf):
		htype = unpack_H(buf[14: 16])[0]
		# logger.debug("type: %X" % type)
		self._init_handler(htype, buf[16:])
		return 16
예제 #25
0
    def _dissect(self, buf):
        hlen = 14
        # Ethernet formats:
        # RFC 894 (Ethernet II) -> type = -> value >1500
        # 802.[2,3] (LLC format) -> type = length field -> value <=1500, not supported
        eth_type = unpack_H(buf[hlen - 2:hlen])[0]

        # any VLAN tag present? in this case: type field is actually a vlan tag
        if eth_type in VLAN_TAG_START:
            # TODO: use _init_triggerlist()
            if eth_type == ETH_TYPE_8021Q:
                # logger.debug(">>> got vlan tag")
                vlan_tag = Dot1Q(buf[12:16])
                self.vlan.append(vlan_tag)
                hlen += 4
                # get real upper layer type
                eth_type = unpack_H(buf[16:18])[0]
            # 802.1ad: support up to 2 tags (double tagging aka QinQ)
            else:
                # logger.debug(">>> got vlan tag")
                vlan_tag1 = Dot1Q(buf[12:16])
                vlan_tag2 = Dot1Q(buf[16:20])
                self.vlan.extend([vlan_tag1, vlan_tag2])
                hlen += 8
                # get real upper layer type
                eth_type = unpack_H(buf[20:22])[0]

        # logger.debug("eth type is: %d" % eth_type)

        # handle ethernet-padding: remove it but save for later use
        # don't use headers for this because this is a rare situation
        dlen = len(buf) - hlen  # data length [+ padding?]

        # assume padding only present if len(upper_layer.bin()) <= 46
        if dlen <= 46:
            try:
                # this will only work on complete headers: Ethernet + IP + ...
                # handle padding using IPv4, IPv6 etc (min size "eth + ..." = 60 bytes)
                # logger.debug(">>> checking for padding")
                if eth_type == ETH_TYPE_IP:
                    dlen_ip = unpack_H(buf[hlen + 2:hlen +
                                           4])[0]  # real data length

                    if dlen_ip < dlen:
                        # padding found
                        self._padding = buf[hlen + dlen_ip:]
                        # logger.debug("got padding for IPv4: %r" % self._padding)
                        dlen = dlen_ip
                # handle padding using IPv6
                # IPv6 is a piece of sh$§! payloadlength (in header) = exclusive standard header
                # but INCLUSIVE options!
                elif eth_type == ETH_TYPE_IP6:
                    dlen_ip = unpack_H(buf[hlen + 4:hlen +
                                           6])[0]  # real data length
                    # logger.debug("eth.hlen=%d, data length based on header: %d" % (hlen, dlen_ip))

                    if 40 + dlen_ip < dlen:
                        # padding found
                        self._padding = buf[hlen + 40 + dlen_ip:]
                        # logger.debug("got padding for IPv6: %r" % self._padding)
                        dlen = 40 + dlen_ip
                elif eth_type == ETH_TYPE_LLDP:
                    # this is a bit redundant as we re-parse TLV when accessing the LLDP layer
                    dlen_lldp, _ = lldp.count_and_dissect_tlvs(buf[hlen:])
                    self._padding = buf[hlen + dlen_lldp:]
                    dlen = dlen_lldp
                elif eth_type == ETH_TYPE_SP:
                    lacppdu_len = 110
                    self._padding = buf[hlen + lacppdu_len:]
                    dlen = lacppdu_len
            except Exception as ex:
                logger.exception(
                    "could not extract padding info, assuming incomplete ethernet frame: %r",
                    ex)
        # logger.debug("len(buf)=%d, len(upper)=%d" % (len(buf), dlen))
        self._init_handler(eth_type, buf[hlen:hlen + dlen])
        return hlen
예제 #26
0
    def _dissect(self, buf):
        # unpack basic data to get things done
        quests_amount, ans_amount, authserver_amount, addreq_amount = unpack_HHHH(
            buf[4:12])
        off = 12

        # TODO: use lazy dissect, dns seems to be too shitty for this
        #
        # parse queries
        #
        #logger.debug(">>> parsing questions: %d" % quests_amount)
        while quests_amount > 0:
            # find name by 0-termination
            q_end = off + DNS.get_dns_length(buf[off:]) + 4
            #logger.debug("name is: %s" % buf[off: q_end-4])
            #logger.debug("Query is: %s" % buf[off: q_end])
            #logger.debug(len(buf[off: q_end]))
            q = DNS.Query(buf[off:q_end])
            # logger.debug("query is following..")
            #logger.debug("Query: %s" % q)
            # logger.debug("query name format: %s" % q._name_format)
            self.queries.append(q)
            off = q_end
            quests_amount -= 1

        #
        # parse answers
        #
        #logger.debug(">>> parsing answers: %d" % ans_amount)
        while ans_amount > 0:
            # find name by label/0-termination
            # DNS name:x + type:2 + class:2 + ttl:4
            a_end = off + DNS.get_dns_length(buf[off:]) + 2 + 2 + 4
            #logger.debug("name is: %s" % buf[off: a_end-8])
            dlen = unpack_H(buf[a_end:a_end + 2])[0]
            #logger.debug("dlen: %d", dlen)
            # dlen header: 2 + dlen
            a_end += (2 + dlen)
            #logger.debug("Answer is: %r" % buf[off: a_end])
            a = DNS.Answer(buf[off:a_end])
            # logger.debug("Answer: %s" % a)
            self.answers.append(a)
            off = a_end
            ans_amount -= 1

        #
        # parse authorative servers
        #
        #logger.debug(">>> parsing authorative servers: %d" % authserver_amount)
        while authserver_amount > 0:
            dlen = unpack_H(buf[off + 10:off + 12])[0]
            authlen = 12 + dlen
            # logger.debug("Auth: %r" % buf[off: off + authlen])
            a = DNS.Auth(buf[off:off + authlen])

            # logger.debug("Auth server: %s" % a)
            self.auths.append(a)
            off += authlen
            authserver_amount -= 1

        #
        # parse additional requests
        #
        #logger.debug(">>> parsing additional records: %d" % addreq_amount)
        while addreq_amount > 0:
            if buf[off:off + 3] == b"\x00\x00\x29":
                a = DNS.AddRecordRoot(buf[off:off + 11])
                off += 11
            else:
                # logger.debug(buf[idx:])
                # logger.debug(buf[off:])
                # logger.debug("data length via: %r" % buf[idx + 9: idx + 11])
                dlen = unpack_H(buf[off + 10:off + 10 + 2])[0]
                # logger.debug("AddRecord: %s" % buf[off: off + 12 + dlen])
                a = DNS.AddRecord(buf[off:off + 12 + dlen])
                # logger.debug("Additional Record: %s" % a)
                off += 12 + dlen
            self.addrecords.append(a)
            addreq_amount -= 1

        # logger.debug("dns: %s" % self)
        return off
예제 #27
0
 def __get_time(self):
     return [unpack_H(x)[0] for x in self.time]
예제 #28
0
 def _set_msgtype_full(self, msgtype):
     self.typeinfo = unpack_H(pack_H_le(msgtype))[0]
예제 #29
0
 def _set_msgtype(self, msgtype):
     typetmp = unpack_H(pack_H_le(msgtype))[0]
     self.typeinfo = (self.typeinfo
                      & ~MASK_MSGTYPE_LE) | (typetmp & MASK_MSGTYPE_LE)
예제 #30
0
 def _get_msgtype_full(self):
     return unpack_H(pack_H_le(self.typeinfo))[0]