1 // 2 // Copyright (C) 2015 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/net/netlink_packet.h" 18 19 #include <linux/netlink.h> 20 21 #include <gmock/gmock.h> 22 #include <gtest/gtest.h> 23 24 using testing::Test; 25 26 namespace shill { 27 28 class NetlinkPacketTest : public Test { 29 }; 30 31 TEST_F(NetlinkPacketTest, Constructor) { 32 // A null pointer should not crash the constructor, but should yield 33 // an invalid packet. 34 NetlinkPacket null_packet(nullptr, 100); 35 EXPECT_FALSE(null_packet.IsValid()); 36 37 unsigned char data[sizeof(nlmsghdr) + 1]; 38 memset(&data, 0, sizeof(data)); 39 40 // A packet that is too short to contain an nlmsghdr should be invalid. 41 NetlinkPacket short_packet(data, sizeof(nlmsghdr) - 1); 42 EXPECT_FALSE(short_packet.IsValid()); 43 44 // A packet that contains an invalid nlmsg_len (should be at least 45 // as large as sizeof(nlmgsghdr)) should be invalid. 46 NetlinkPacket invalid_packet(data, sizeof(nlmsghdr)); 47 EXPECT_FALSE(invalid_packet.IsValid()); 48 49 // Successfully parse a well-formed packet that has no payload. 50 nlmsghdr hdr; 51 memset(&hdr, 0, sizeof(hdr)); 52 hdr.nlmsg_len = sizeof(hdr); 53 hdr.nlmsg_type = 1; 54 memcpy(&data, &hdr, sizeof(hdr)); 55 NetlinkPacket empty_packet(data, sizeof(nlmsghdr)); 56 EXPECT_TRUE(empty_packet.IsValid()); 57 EXPECT_EQ(sizeof(nlmsghdr), empty_packet.GetLength()); 58 EXPECT_EQ(1, empty_packet.GetMessageType()); 59 char payload_byte = 0; 60 EXPECT_FALSE(empty_packet.ConsumeData(1, &payload_byte)); 61 62 // A packet that contains an nlmsg_len that is larger than the 63 // data provided should be invalid. 64 hdr.nlmsg_len = sizeof(hdr) + 1; 65 hdr.nlmsg_type = 2; 66 memcpy(&data, &hdr, sizeof(hdr)); 67 NetlinkPacket incomplete_packet(data, sizeof(nlmsghdr)); 68 EXPECT_FALSE(incomplete_packet.IsValid()); 69 70 // Retrieve a byte from a well-formed packet. After that byte is 71 // retrieved, no more data can be consumed. 72 data[sizeof(nlmsghdr)] = 10; 73 NetlinkPacket complete_packet(data, sizeof(nlmsghdr) + 1); 74 EXPECT_TRUE(complete_packet.IsValid()); 75 EXPECT_EQ(sizeof(nlmsghdr) + 1, complete_packet.GetLength()); 76 EXPECT_EQ(2, complete_packet.GetMessageType()); 77 EXPECT_EQ(1, complete_packet.GetRemainingLength()); 78 EXPECT_TRUE(complete_packet.ConsumeData(1, &payload_byte)); 79 EXPECT_EQ(10, payload_byte); 80 EXPECT_FALSE(complete_packet.ConsumeData(1, &payload_byte)); 81 } 82 83 TEST_F(NetlinkPacketTest, ConsumeData) { 84 // This code assumes that the value of NLMSG_ALIGNTO is 4, and that nlmsghdr 85 // is aligned to a 4-byte boundary. 86 static_assert(NLMSG_ALIGNTO == 4, "NLMSG_ALIGNTO sized has changed"); 87 static_assert((sizeof(nlmsghdr) % NLMSG_ALIGNTO) == 0, 88 "nlmsghdr is not aligned with NLMSG_ALIGNTO"); 89 90 const char kString1[] = "A"; 91 const char kString2[] = "pattern"; 92 const char kString3[] = "so"; 93 const char kString4[] = "grand"; 94 95 // Assert string sizes (with null terminator). 96 ASSERT_EQ(2, sizeof(kString1)); 97 ASSERT_EQ(8, sizeof(kString2)); 98 ASSERT_EQ(3, sizeof(kString3)); 99 ASSERT_EQ(6, sizeof(kString4)); 100 101 unsigned char data[sizeof(nlmsghdr) + 22]; 102 memset(data, 0, sizeof(data)); 103 nlmsghdr hdr; 104 memset(&hdr, 0, sizeof(hdr)); 105 hdr.nlmsg_len = sizeof(data); 106 memcpy(data, &hdr, sizeof(hdr)); 107 memcpy(data + sizeof(nlmsghdr), kString1, sizeof(kString1)); 108 memcpy(data + sizeof(nlmsghdr) + 4, kString2, sizeof(kString2)); 109 memcpy(data + sizeof(nlmsghdr) + 12, kString3, sizeof(kString3)); 110 memcpy(data + sizeof(nlmsghdr) + 16, kString4, sizeof(kString4)); 111 112 NetlinkPacket packet(data, sizeof(data)); 113 EXPECT_EQ(22, packet.GetRemainingLength()); 114 115 // Consuming 2 bytes of data also consumed 2 bytes of padding. 116 char string_piece[8]; 117 EXPECT_TRUE(packet.ConsumeData(2, &string_piece)); 118 EXPECT_STREQ(kString1, string_piece); 119 EXPECT_EQ(18, packet.GetRemainingLength()); 120 121 // An aligned read (8 bytes) should read no more than this number. 122 EXPECT_TRUE(packet.ConsumeData(8, &string_piece)); 123 EXPECT_STREQ(kString2, string_piece); 124 EXPECT_EQ(10, packet.GetRemainingLength()); 125 126 // Try an odd-numbered unaligned read. 127 EXPECT_TRUE(packet.ConsumeData(3, &string_piece)); 128 EXPECT_STREQ(kString3, string_piece); 129 EXPECT_EQ(6, packet.GetRemainingLength()); 130 131 // Reading more than is left should fail, and should not consume anything. 132 EXPECT_FALSE(packet.ConsumeData(7, &string_piece)); 133 EXPECT_EQ(6, packet.GetRemainingLength()); 134 135 // Reading a correctly-sized unalinged value which consumes the rest of 136 // the buffer should succeed. 137 EXPECT_TRUE(packet.ConsumeData(6, &string_piece)); 138 EXPECT_STREQ(kString4, string_piece); 139 EXPECT_EQ(0, packet.GetRemainingLength()); 140 } 141 142 } // namespace shill 143