Skip to content
Extraits de code Groupes Projets
CoAP.py 3,25 ko
Newer Older
  • Learn to ignore specific revisions
  • François De Keersmaeker's avatar
    François De Keersmaeker a validé
    import logging
    
    import random
    
    import scapy.all as scapy
    from scapy.contrib import coap
    from packet.Packet import Packet
    
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
    class CoAP(Packet):
    
    
        # Class variables
        name = "CoAP"
    
        # Modifiable fields
        fields = {
            "type": "int[0,3]",
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
            "code": "int[1,4]",
    
        fields = [
            "type",
            "code",
            "uri"
        ]
    
    
        @staticmethod
        def new_int_value(old_value: int, start: int, end: int) -> int:
            """
            Generate a new random integer value between start and end, different from old_value.
    
            :param old_value: Old value of the integer.
            :param start: Start of the range.
            :param end: End of the range.
            :return: New random integer value.
            :raises ValueError: If start is greater than end.
            """
            # Invalid parameters handling
            if start > end:
                raise ValueError("Start value must be smaller than end value.")
            
            # Generate new random int value
            new_value = old_value
            while new_value == old_value:
                new_value = random.randint(start, end)
            return new_value
        
    
        @staticmethod
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
        def edit_uri(options: list) -> dict:
    
            """
            Randomly edit one character in each part of the URI of a CoAP packet.
    
            :param options: List of CoAP options.
            :return: Edited list of CoAP options.
            """
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
            result = {
                "new_options": [],
                "old_uri": b"",
                "new_uri": b""
            }
    
            for i in range(len(options)):
                if options[i][0] == "Uri-Path" or options[i][0] == "Uri-Query":
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
                    new_value = Packet.bytes_edit_char(options[i][1])
                    result["new_options"].append((options[i][0], new_value))
                    prefix = b"/?" if options[i][0] == "Uri-Query" else b"/"
                    result["old_uri"] += prefix + options[i][1]
                    result["new_uri"] += prefix + new_value
    
                else:
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
                    result["new_options"].append(options[i])
            return result
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
        def tweak(self) -> dict:
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
            Randomly edit one field of the CoAP packet, among the following:
                - type
                - code
                - uri
    
            :return: Dictionary containing tweak information.
    
            """
            # Get field which will be modified
            field = random.choice(self.fields)
    
    
            # Initialize old and new values
            old_value = None
            new_value = None
    
    
            # Chosen field is an integer
            if field == "type" or field == "code":
                old_value = self.layer.getfieldval(field)
                if field == "type":
                    new_value = CoAP.new_int_value(old_value, 0, 3)
                elif field == "code":
                    new_value = CoAP.new_int_value(old_value, 1, 4)
                self.layer.setfieldval(field, new_value)
            
            # Chosen field is the URI
            elif field == "uri":
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
                result = CoAP.edit_uri(self.layer.getfieldval("options"))
                old_value = result["old_uri"]
                new_value = result["new_uri"]
    
                self.layer.setfieldval("options", result["new_options"])
    
            
            # Update checksums
    
            self.update_fields()
    
    François De Keersmaeker's avatar
    François De Keersmaeker a validé
    
            # Return value: dictionary containing tweak information
            return self.get_dict_log(field, old_value, new_value)