Browse Source

[1224] DHCP::Pkt4 unittests are now passing.

Tomek Mrugalski 13 years ago
parent
commit
0a54d27ad8
3 changed files with 82 additions and 5 deletions
  1. 31 5
      src/lib/dhcp/pkt4.cc
  2. 8 0
      src/lib/dhcp/pkt4.h
  3. 43 0
      src/lib/dhcp/tests/pkt4_unittest.cc

+ 31 - 5
src/lib/dhcp/pkt4.cc

@@ -33,7 +33,7 @@ Pkt4::Pkt4(uint8_t msg_type, uint32_t transid)
       ifindex_(0),
       local_port_(DHCP4_SERVER_PORT),
       remote_port_(DHCP4_CLIENT_PORT),
-      op_(BOOTREPLY),
+      op_(DHCPTypeToBootpType(msg_type)),
       htype_(HTYPE_ETHER),
       hlen_(0),
       hops_(0),
@@ -74,6 +74,10 @@ Pkt4::Pkt4(const uint8_t* data, size_t len)
       bufferOut_(DHCPV4_PKT_HDR_LEN),
       msg_type_(DHCPDISCOVER)
 {
+    if (len < DHCPV4_PKT_HDR_LEN) {
+        isc_throw(OutOfRange, "Truncated DHCPv4 packet (len=" << len
+                  << " received, at least 236 bytes expected.");
+    }
     bufferIn_.writeData(data, len);
 }
 
@@ -104,19 +108,19 @@ Pkt4::toText() {
     tmp << "localAddr=[" << local_addr_.toText() << "]:" << local_port_
         << " remoteAddr=[" << remote_addr_.toText()
         << "]:" << remote_port_ << endl;
-    tmp << "msgtype=" << msg_type_ 
-        << ", transid=0x" << hex << transid_ << dec 
+    tmp << "msgtype=" << msg_type_
+        << ", transid=0x" << hex << transid_ << dec
         << endl;
 
     return tmp.str();
 }
 
-void 
+void
 Pkt4::setHWAddr(uint8_t hType, uint8_t hlen, const uint8_t* macAddr) {
     /// TODO Rewrite this once support for client-identifier option
     /// is implemented (ticket 1228?)
     if (hlen>MAX_CHADDR_LEN) {
-        isc_throw(OutOfRange, "Hardware address (len=" << hlen 
+        isc_throw(OutOfRange, "Hardware address (len=" << hlen
                   << " too long. Max " << MAX_CHADDR_LEN << " supported.");
     }
     htype_ = hType;
@@ -149,5 +153,27 @@ Pkt4::setFile(const uint8_t* file, size_t fileLen /*= MAX_FILE_LEN*/) {
     // no need to store snameLen as any empty space is filled with 0s
 }
 
+uint8_t
+Pkt4::DHCPTypeToBootpType(uint8_t dhcpType) {
+    switch (dhcpType) {
+    case DHCPDISCOVER:
+    case DHCPREQUEST:
+    case DHCPDECLINE:
+    case DHCPRELEASE:
+    case DHCPINFORM:
+    case DHCPLEASEQUERY:
+        return (BOOTREQUEST);
+    case DHCPACK:
+    case DHCPNAK:
+    case DHCPOFFER:
+    case DHCPLEASEUNASSIGNED:
+    case DHCPLEASEUNKNOWN:
+    case DHCPLEASEACTIVE:
+        return (BOOTREPLY);
+    default:
+        isc_throw(OutOfRange, "Invalid message type: "
+                  << static_cast<int>(dhcpType) );
+    }
+}
 
 };

+ 8 - 0
src/lib/dhcp/pkt4.h

@@ -269,6 +269,14 @@ public:
 
 protected:
 
+    /// converts DHCP message type to BOOTP op type
+    ///
+    /// @param dhcpType DHCP message type (e.g. DHCPDISCOVER)
+    ///
+    /// @return BOOTP type (BOOTREQUEST or BOOTREPLY)
+    uint8_t
+    DHCPTypeToBootpType(uint8_t dhcpType);
+
     /// local address (dst if receiving packet, src if sending packet)
     isc::asiolink::IOAddress local_addr_;
 

+ 43 - 0
src/lib/dhcp/tests/pkt4_unittest.cc

@@ -302,6 +302,49 @@ TEST(Pkt4Test, hwAddr) {
     /// longer than 16 bytes should be stored in client-identifier option
 }
 
+TEST(Pkt4Test, msgTypes) {
+
+    struct msgType {
+        uint8_t dhcp;
+        uint8_t bootp;
+    };
+
+    msgType types[] = {
+        {DHCPDISCOVER, BOOTREQUEST},
+        {DHCPOFFER, BOOTREPLY},
+        {DHCPREQUEST, BOOTREQUEST},
+        {DHCPDECLINE, BOOTREQUEST},
+        {DHCPACK, BOOTREPLY},
+        {DHCPNAK, BOOTREPLY},
+        {DHCPRELEASE, BOOTREQUEST},
+        {DHCPINFORM, BOOTREQUEST},
+        {DHCPLEASEQUERY, BOOTREQUEST},
+        {DHCPLEASEUNASSIGNED, BOOTREPLY},
+        {DHCPLEASEUNKNOWN, BOOTREPLY},
+        {DHCPLEASEACTIVE, BOOTREPLY}
+    };
+
+    Pkt4* pkt = 0;
+    for (int i=0; i < sizeof(types)/sizeof(msgType); i++) {
+
+        pkt = new Pkt4(types[i].dhcp, 0);
+        EXPECT_EQ(types[i].dhcp, pkt->getType());
+
+        EXPECT_EQ(types[i].bootp, pkt->getOp());
+
+        delete pkt;
+        pkt = 0;
+    }
+
+    EXPECT_THROW(
+        pkt = new Pkt4(100, 0), // there's no message type 100
+        OutOfRange
+    );
+    if (pkt) {
+        delete pkt;
+    }
+}
+
 // this test verifies handling of sname field
 TEST(Pkt4Test, sname) {