Beispiel #1
0
def buildMessage(msgtype,
                 token,
                 code,
                 messageId,
                 options=[],
                 payload=[],
                 securityContext=None,
                 partialIV=None):
    assert msgtype in d.TYPE_ALL
    assert code in d.METHOD_ALL + d.COAP_RC_ALL

    message = []

    TKL = 0
    if token:
        # determine token length
        for tokenLen in range(1, 8 + 1):
            if token < (1 << (8 * tokenLen)):
                TKL = tokenLen
                break
        if not TKL:
            raise ValueError('token {0} too long'.format(token))

    # header
    message += [d.COAP_VERSION << 6 | msgtype << 4 | TKL]
    message += [code]
    message += u.int2buf(messageId, 2)
    message += u.int2buf(token, TKL)

    # options
    options = sortOptions(options)

    if securityContext:
        # invoke oscoap to protect the message
        (outerOptions,
         newPayload) = oscoap.protectMessage(context=securityContext,
                                             version=d.COAP_VERSION,
                                             code=code,
                                             options=options,
                                             payload=payload,
                                             partialIV=partialIV)
    else:
        (outerOptions, newPayload) = (options, payload)

    # add encoded options
    message += encodeOptions(outerOptions)

    # add payload
    message += encodePayload(newPayload)

    return message
Beispiel #2
0
 def _writePcapMessage(self,timestamp,srcIp,destIp,srcPort,destPort,payload):
     
     bytesToWrite    = []
     
     # IPv6 message
     bytesToWrite   += [0x06<<4]                   # version + traffic_class[high]
     bytesToWrite   += [0x00]*3                    # traffic_class[low] + flow_label
     bytesToWrite   += u.int2buf(8+len(payload),2) # payload length (incl. UDP header)
     bytesToWrite   += [17]                        # next header (17==UDP)
     bytesToWrite   += [64]                        # hop limit
     bytesToWrite   += srcIp                       # source address
     bytesToWrite   += destIp                      # destination addres
     
     # UDP header
     bytesToWrite   += u.int2buf(srcPort,2)        # source port
     bytesToWrite   += u.int2buf(destPort,2)       # destination port
     bytesToWrite   += u.int2buf(len(payload),2)   # length
     bytesToWrite   += u.int2buf(
         u.calcUdpCheckSum(
             srcIp,
             destIp,
             srcPort,
             destPort,
             payload,
         ),
         2
     )                                             # checksum
     
     # payload
     bytesToWrite   += payload                     # payload
     
     # format PCAP message header
     ts_sec          = int(timestamp)
     ts_usec         = int((timestamp-ts_sec)*1000000)
     pcapMsgHeader   = struct.pack(
         'IIII',
         ts_sec,                                   # ts_sec
         ts_usec,                                  # ts_usec
         len(bytesToWrite),                        # incl_len
         len(bytesToWrite),                        # orig_len
     )
     
     # write to file
     stringToWrite   = ''.join(
        [pcapMsgHeader]+[''.join([chr(b) for b in bytesToWrite])]
     )
     self.pcapFile.write(stringToWrite)
     self.pcapFile.flush()
     
     log.debug('written {0} bytes'.format(len(stringToWrite)))
Beispiel #3
0
    def _receiveFromCoAP(self, timestamp, sender, data):
        '''
        Receive CoAP response and forward it to the mesh network.
        Appends UDP and IPv6 headers to the CoAP message and forwards it on the Eventbus towards the mesh.
        '''
        self.coapClient.close()

        # UDP
        udplen = len(data) + 8

        udp = u.int2buf(self.coapClient.udpPort,2)  # src port
        udp += u.int2buf(sender[1],2) # dest port
        udp += [udplen >> 8, udplen & 0xff]  # length
        udp += [0x00, 0x00]  # checksum
        udp += data

        # destination address of the packet is CoAP client's IPv6 address (address of the mote)
        dstIpv6Address = u.ipv6AddrString2Bytes(self.coapClient.ipAddress)
        assert len(dstIpv6Address)==16
        # source address of the packet is DAG root's IPV6 address
        # use the same prefix (link-local or global) as in the destination address
        srcIpv6Address = dstIpv6Address[:8]
        srcIpv6Address += self.dagRootEui64
        assert len(srcIpv6Address)==16

        # CRC See https://tools.ietf.org/html/rfc2460.

        udp[6:8] = openvisualizer.openvisualizer_utils.calculatePseudoHeaderCRC(
            src=srcIpv6Address,
            dst=dstIpv6Address,
            length=[0x00, 0x00] + udp[4:6],
            nh=[0x00, 0x00, 0x00, 17], # UDP as next header
            payload=data,
        )

        # IPv6
        ip = [6 << 4]  # v6 + traffic class (upper nybble)
        ip += [0x00, 0x00, 0x00]  # traffic class (lower nibble) + flow label
        ip += udp[4:6]  # payload length
        ip += [17]  # next header (protocol); UDP=17
        ip += [64]  # hop limit (pick a safe value)
        ip += srcIpv6Address  # source
        ip += dstIpv6Address  # destination
        ip += udp

        # announce network prefix
        self.dispatch(
            signal        = 'v6ToMesh',
            data          = ip
        )
Beispiel #4
0
    def _writePcapMessage(self, timestamp, srcIp, destIp, srcPort, destPort,
                          payload):

        bytesToWrite = []

        # IPv6 message
        bytesToWrite += [0x06 << 4]  # version + traffic_class[high]
        bytesToWrite += [0x00] * 3  # traffic_class[low] + flow_label
        bytesToWrite += u.int2buf(8 + len(payload),
                                  2)  # payload length (incl. UDP header)
        bytesToWrite += [17]  # next header (17==UDP)
        bytesToWrite += [64]  # hop limit
        bytesToWrite += srcIp  # source address
        bytesToWrite += destIp  # destination addres

        # UDP header
        bytesToWrite += u.int2buf(srcPort, 2)  # source port
        bytesToWrite += u.int2buf(destPort, 2)  # destination port
        bytesToWrite += u.int2buf(len(payload), 2)  # length
        bytesToWrite += u.int2buf(
            u.calcUdpCheckSum(
                srcIp,
                destIp,
                srcPort,
                destPort,
                payload,
            ), 2)  # checksum

        # payload
        bytesToWrite += payload  # payload

        # format PCAP message header
        ts_sec = int(timestamp)
        ts_usec = int((timestamp - ts_sec) * 1000000)
        pcapMsgHeader = struct.pack(
            'IIII',
            ts_sec,  # ts_sec
            ts_usec,  # ts_usec
            len(bytesToWrite),  # incl_len
            len(bytesToWrite),  # orig_len
        )

        # write to file
        stringToWrite = ''.join([pcapMsgHeader] +
                                [''.join([chr(b) for b in bytesToWrite])])
        self.pcapFile.write(stringToWrite)
        self.pcapFile.flush()

        log.debug('written {0} bytes'.format(len(stringToWrite)))
Beispiel #5
0
    def _receiveFromCoAP(self, timestamp, sender, data):
        '''
        Receive CoAP response and forward it to the mesh network.
        Appends UDP and IPv6 headers to the CoAP message and forwards it on the Eventbus towards the mesh.
        '''
        self.coapClient.close()

        # UDP
        udplen = len(data) + 8

        udp = u.int2buf(sender[1], 2)  # src port
        udp += u.int2buf(self.coapClient.udpPort, 2)  # dest port
        udp += [udplen >> 8, udplen & 0xff]  # length
        udp += [0x00, 0x00]  # checksum
        udp += data

        # destination address of the packet is CoAP client's IPv6 address (address of the mote)
        dstIpv6Address = u.ipv6AddrString2Bytes(self.coapClient.ipAddress)
        assert len(dstIpv6Address) == 16
        # source address of the packet is DAG root's IPV6 address
        # use the same prefix (link-local or global) as in the destination address
        srcIpv6Address = dstIpv6Address[:8]
        srcIpv6Address += self.dagRootEui64
        assert len(srcIpv6Address) == 16

        # CRC See https://tools.ietf.org/html/rfc2460.

        udp[6:
            8] = openvisualizer.openvisualizer_utils.calculatePseudoHeaderCRC(
                src=srcIpv6Address,
                dst=dstIpv6Address,
                length=[0x00, 0x00] + udp[4:6],
                nh=[0x00, 0x00, 0x00, 17],  # UDP as next header
                payload=udp,
            )

        # IPv6
        ip = [6 << 4]  # v6 + traffic class (upper nybble)
        ip += [0x00, 0x00, 0x00]  # traffic class (lower nibble) + flow label
        ip += udp[4:6]  # payload length
        ip += [17]  # next header (protocol); UDP=17
        ip += [64]  # hop limit (pick a safe value)
        ip += srcIpv6Address  # source
        ip += dstIpv6Address  # destination
        ip += udp

        # announce network prefix
        self.dispatch(signal='v6ToMesh', data=ip)
Beispiel #6
0
def getRequestSecurityParams(objectSecurityOption):
    if objectSecurityOption:
        context = objectSecurityOption.context
        newSequenceNumber = objectSecurityOption.context.getSequenceNumber()
        # convert sequence number to string that is the length of the IV
        newSequenceNumber = u.buf2str(
            u.int2buf(newSequenceNumber, context.aeadAlgorithm.ivLength))
        return (context, newSequenceNumber)
    else:
        return (None, None)
Beispiel #7
0
def test_int2buf(logFixture, validint2buf):

    (val, len, output) = validint2buf

    log.debug('val:    {0}'.format(val))
    log.debug('len:    {0}'.format(len))
    log.debug('output: {0}'.format(output))

    result = coapUtils.int2buf(val, len)

    log.debug('result: {0}'.format(result))

    assert tuple(result) == output
Beispiel #8
0
def test_int2buf(logFixture, validint2buf):
    
    (val,len,output) = validint2buf
    
    log.debug('val:    {0}'.format(val))
    log.debug('len:    {0}'.format(len))
    log.debug('output: {0}'.format(output))
    
    result = coapUtils.int2buf(val,len)
    
    log.debug('result: {0}'.format(result))
    
    assert tuple(result)==output
Beispiel #9
0
    def toBytes(self, lastOptionNum):

        payload = self.getPayloadBytes()
        delta = self.optionNumber - lastOptionNum

        # optionDelta and optionDeltaExt fields
        if delta <= 12:
            optionDelta = delta
            optionDeltaExt = u.int2buf(delta, 0)
        elif delta <= (0xff + 13):
            optionDelta = 13
            optionDeltaExt = u.int2buf(delta - 13, 1)
        elif delta <= (0xffff + 269):
            optionDelta = 14
            optionDeltaExt = u.int2buf(delta - 269, 2)
        else:
            raise ValueError('delta is too large: {0}'.format(delta))

        # optionLength and optionLengthExt fields
        if len(payload) <= 12:
            optionLength = len(payload)
            optionLengthExt = u.int2buf(len(payload), 0)
        elif len(payload) <= (0xff + 13):
            optionLength = 13
            optionLengthExt = u.int2buf(len(payload) - 13, 1)
        elif len(payload) <= (0xffff + 269):
            optionLength = 14
            optionLengthExt = u.int2buf(len(payload) - 269, 2)
        else:
            raise ValueError('payload is too long, {0} bytes'.format(
                len(payload)))

        returnVal = []
        returnVal += [optionDelta << 4 | optionLength]
        returnVal += optionDeltaExt
        returnVal += optionLengthExt
        returnVal += payload

        return returnVal