Home | History | Annotate | Download | only in net
      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