1#!/usr/bin/env python3 2# 3# Copyright (c) 2016, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30import io 31import unittest 32 33from common import MacAddress, MacAddressType 34import mac802154 35 36longaddrs = bytearray([0x61, 0xcc, 0x00, 0xce, 0xfa]) 37shortaddrs = bytearray([0x61, 0x88, 0x00, 0xce, 0xfa]) 38longshortaddrs = bytearray([0x61, 0xc8, 0x00, 0xce, 0xfa]) 39shortlongaddrs = bytearray([0x61, 0x8c, 0x00, 0xce, 0xfa]) 40 41 42class TestMacParser(unittest.TestCase): 43 44 def test_should_parse_ack_frame(self): 45 frame = mac802154.MacFrame() 46 frame.parse(io.BytesIO(bytearray([0x12, 0x00, 0x12, 0x34, 0x56]))) 47 48 self.assertEqual(mac802154.MacHeader.FrameType.ACK, frame.header.frame_type) 49 self.assertEqual(True, frame.header.frame_pending) 50 self.assertEqual(False, frame.header.ack_request) 51 self.assertEqual(0, frame.header.frame_version) 52 self.assertEqual(0x12, frame.header.seq) 53 self.assertEqual(bytearray([0x34, 0x56]), frame.header.fcs) 54 self.assertEqual(None, frame.payload) 55 56 def test_should_parse_data_frame_with_short_addresses(self): 57 frame = mac802154.MacFrame() 58 frame.parse( 59 io.BytesIO(bytearray([0x61, 0x88, 0x34, 0xce, 0xfa, 0xad, 0xde, 0xef, 0xbe, 0x12, 0x34, 0xfe, 0xdc]))) 60 61 self.assertEqual(mac802154.MacHeader.FrameType.DATA, frame.header.frame_type) 62 self.assertEqual(False, frame.header.frame_pending) 63 self.assertEqual(True, frame.header.ack_request) 64 self.assertEqual(0, frame.header.frame_version) 65 self.assertEqual(0x34, frame.header.seq) 66 self.assertEqual(bytearray([0xfe, 0xdc]), frame.header.fcs) 67 self.assertEqual(0xface, frame.header.dest_pan_id) 68 self.assertEqual(0xdead, frame.header.dest_address.rloc) 69 self.assertEqual(0xface, frame.header.src_pan_id) 70 self.assertEqual(0xbeef, frame.header.src_address.rloc) 71 72 self.assertEqual(bytearray([0x12, 0x34]), frame.payload.data) 73 74 def test_should_parse_data_frame_with_extended_addresses(self): 75 frame = mac802154.MacFrame() 76 frame.parse( 77 io.BytesIO( 78 bytearray([ 79 0x61, 0xcc, 0x56, 0xce, 0xfa, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0x0b, 0xad, 0xf0, 80 0x0d, 0xba, 0xd0, 0xd0, 0x0d, 0x12, 0x34, 0xfe, 0xdc 81 ]))) 82 83 self.assertEqual(mac802154.MacHeader.FrameType.DATA, frame.header.frame_type) 84 self.assertEqual(False, frame.header.frame_pending) 85 self.assertEqual(True, frame.header.ack_request) 86 self.assertEqual(0, frame.header.frame_version) 87 self.assertEqual(0x56, frame.header.seq) 88 self.assertEqual(bytearray([0xfe, 0xdc]), frame.header.fcs) 89 self.assertEqual(0xface, frame.header.dest_pan_id) 90 self.assertEqual(bytearray(reversed([0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef])), 91 frame.header.dest_address.mac_address) 92 self.assertEqual(0xface, frame.header.src_pan_id) 93 self.assertEqual(bytearray(reversed([0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0, 0x0d])), 94 frame.header.src_address.mac_address) 95 96 self.assertEqual(bytearray([0x12, 0x34]), frame.payload.data) 97 98 def test_should_parse_data_frame_with_short_and_extended_addresses(self): 99 frame = mac802154.MacFrame() 100 frame.parse( 101 io.BytesIO( 102 bytearray([ 103 0x61, 0xc8, 0x56, 0xce, 0xfa, 0xad, 0xde, 0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0, 0x0d, 0x12, 104 0x34, 0xfe, 0xdc 105 ]))) 106 107 self.assertEqual(mac802154.MacHeader.FrameType.DATA, frame.header.frame_type) 108 self.assertEqual(False, frame.header.frame_pending) 109 self.assertEqual(True, frame.header.ack_request) 110 self.assertEqual(0, frame.header.frame_version) 111 self.assertEqual(0x56, frame.header.seq) 112 self.assertEqual(bytearray([0xfe, 0xdc]), frame.header.fcs) 113 self.assertEqual(0xface, frame.header.dest_pan_id) 114 self.assertEqual(0xdead, frame.header.dest_address.rloc) 115 self.assertEqual(0xface, frame.header.src_pan_id) 116 self.assertEqual(bytearray(reversed([0x0b, 0xad, 0xf0, 0x0d, 0xba, 0xd0, 0xd0, 0x0d])), 117 frame.header.src_address.mac_address) 118 119 self.assertEqual(bytearray([0x12, 0x34]), frame.payload.data) 120 121 def test_should_parse_data_frame_with_extended_and_short_addresses(self): 122 frame = mac802154.MacFrame() 123 frame.parse( 124 io.BytesIO( 125 bytearray([ 126 0x61, 0x8c, 0x56, 0xce, 0xfa, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0x0d, 0xf0, 0x12, 127 0x34, 0xfe, 0xdc 128 ]))) 129 130 self.assertEqual(mac802154.MacHeader.FrameType.DATA, frame.header.frame_type) 131 self.assertEqual(False, frame.header.frame_pending) 132 self.assertEqual(True, frame.header.ack_request) 133 self.assertEqual(0, frame.header.frame_version) 134 self.assertEqual(0x56, frame.header.seq) 135 self.assertEqual(bytearray([0xfe, 0xdc]), frame.header.fcs) 136 self.assertEqual(0xface, frame.header.dest_pan_id) 137 self.assertEqual(bytearray(reversed([0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef])), 138 frame.header.dest_address.mac_address) 139 self.assertEqual(0xface, frame.header.src_pan_id) 140 self.assertEqual(0xf00d, frame.header.src_address.rloc) 141 142 self.assertEqual(bytearray([0x12, 0x34]), frame.payload.data) 143 144 def test_should_parse_data_request_command(self): 145 frame = mac802154.MacFrame() 146 frame.parse(io.BytesIO(bytearray([0x63, 0x88, 0x78, 0xce, 0xfa, 0xad, 0xde, 0x0d, 0xf0, 0x04, 0xfe, 0xdc]))) 147 148 self.assertEqual(mac802154.MacHeader.FrameType.COMMAND, frame.header.frame_type) 149 self.assertEqual(False, frame.header.frame_pending) 150 self.assertEqual(True, frame.header.ack_request) 151 self.assertEqual(0, frame.header.frame_version) 152 self.assertEqual(0x78, frame.header.seq) 153 self.assertEqual(bytearray([0xfe, 0xdc]), frame.header.fcs) 154 self.assertEqual(0xface, frame.header.dest_pan_id) 155 self.assertEqual(0xdead, frame.header.dest_address.rloc) 156 self.assertEqual(0xface, frame.header.src_pan_id) 157 self.assertEqual(0xf00d, frame.header.src_address.rloc) 158 159 self.assertEqual(bytearray([0x4]), frame.payload.data) 160 161 def test_should_decrypt_data_frame(self): 162 163 mac802154.DeviceDescriptors.add( 164 0x2001, MacAddress(bytearray([0x16, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x07]), MacAddressType.LONG)) 165 166 frame = mac802154.MacFrame() 167 frame.parse( 168 io.BytesIO( 169 bytearray([ 170 0x69, 171 0x98, 172 0x68, # FC, seq 173 0xce, 174 0xfa, # Pan Id 175 0x00, 176 0x20, # Dst addr 177 0x01, 178 0x20, # Src addr 179 0x0d, 180 0x00, 181 0x00, 182 0x00, 183 0x00, 184 0x01, # Aux Security Header 185 0xb5, 186 0x5a, 187 0x0d, 188 0x8e, 189 0x18, 190 0x5c, 191 0xb1, 192 0x06, # Payload 193 0xc4, 194 0x6f, 195 0x7d, 196 0x6b, 197 0xb5, 198 0x4a, 199 0x87, 200 0x14, 201 0xae, 202 0xdd, 203 0x8e, 204 0xb7, 205 0x37, 206 0x62, 207 0x27, 208 0x48, 209 0xc9, 210 0x53, 211 0x0c, 212 0x44, 213 0x31, 214 0x59, 215 0x8b, 216 0xa2, 217 0x83, 218 0x59, 219 0xa1, 220 0x43, # MIC (valid) 221 0x74, 222 0xe0, 223 0x2a, 224 0xf6, 225 0x99, 226 0xfc 227 ]))) # FCS (valid) 228 229 self.assertEqual(mac802154.MacHeader.FrameType.DATA, frame.header.frame_type) 230 self.assertEqual(False, frame.header.frame_pending) 231 self.assertEqual(True, frame.header.ack_request) 232 self.assertEqual(1, frame.header.frame_version) 233 self.assertEqual(0x68, frame.header.seq) 234 self.assertEqual(bytearray([0x99, 0xfc]), frame.header.fcs) 235 self.assertEqual(0xface, frame.header.dest_pan_id) 236 self.assertEqual(0x2000, frame.header.dest_address.rloc) 237 self.assertEqual(0xface, frame.header.src_pan_id) 238 self.assertEqual(0x2001, frame.header.src_address.rloc) 239 240 self.assertEqual(0, frame.header.aux_sec_header.frame_counter) 241 self.assertEqual(5, frame.header.aux_sec_header.security_level) 242 243 self.assertEqual( 244 bytes( 245 bytearray([ 246 0x7c, 0x77, 0x80, 0xf0, 0x4d, 0x4d, 0x4d, 0x4d, 0xe0, 0x04, 0x44, 0x02, 0x44, 0x66, 0x13, 0x5f, 247 0x22, 0x80, 0xb1, 0x61, 0x02, 0x61, 0x73, 0x11, 0x2a, 0xff, 0x01, 0x08, 0x16, 0x6e, 0x0a, 0x00, 248 0x00, 0x00, 0x00, 0x07 249 ])), frame.payload.data) 250 251 def test_should_decrypt_command_frame(self): 252 frame = mac802154.MacFrame() 253 frame.parse( 254 io.BytesIO( 255 bytearray([ 256 0x6b, 0xdc, 0xce, 0xce, 0xfa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x6e, 0x16, 0x03, 0x00, 0x00, 257 0x00, 0x00, 0x0a, 0x6e, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x2d, 0xbc, 0x12, 0xbe, 258 0x0a, 0x4f 259 ]))) 260 261 self.assertEqual(mac802154.MacHeader.FrameType.COMMAND, frame.header.frame_type) 262 self.assertEqual(False, frame.header.frame_pending) 263 self.assertEqual(True, frame.header.ack_request) 264 self.assertEqual(1, frame.header.frame_version) 265 self.assertEqual(206, frame.header.seq) 266 self.assertEqual(bytearray([0x0a, 0x4f]), frame.header.fcs) 267 self.assertEqual(0xface, frame.header.dest_pan_id) 268 self.assertEqual(bytearray([0x16, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02]), 269 frame.header.dest_address.mac_address) 270 self.assertEqual(0xface, frame.header.src_pan_id) 271 self.assertEqual(bytearray([0x16, 0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x03]), 272 frame.header.src_address.mac_address) 273 274 self.assertEqual(0, frame.header.aux_sec_header.frame_counter) 275 self.assertEqual(5, frame.header.aux_sec_header.security_level) 276 277 278if __name__ == "__main__": 279 unittest.main() 280