|
@@ -28,17 +28,27 @@ public:
|
|
|
|
|
|
// The following declaration describes the various fields in the DNS
|
|
|
// packet header.
|
|
|
- struct Flags {
|
|
|
- unsigned int rc : 4;
|
|
|
- unsigned int cd : 1;
|
|
|
- unsigned int ad : 1;
|
|
|
- unsigned int z : 1; // Reserved
|
|
|
- unsigned int ra : 1;
|
|
|
- unsigned int rd : 1;
|
|
|
- unsigned int tc : 1;
|
|
|
- unsigned int aa : 1;
|
|
|
- unsigned int op : 4;
|
|
|
- unsigned int qr : 1;
|
|
|
+ enum FieldParameter {
|
|
|
+ QR_MASK = 0x8000, // To get the value
|
|
|
+ QR_OFF = 15, // Shift this number of bits left to set the value
|
|
|
+ OP_MASK = 0x7800,
|
|
|
+ OP_OFF = 11,
|
|
|
+ AA_MASK = 0x0400,
|
|
|
+ AA_OFF = 10,
|
|
|
+ TC_MASK = 0x0200,
|
|
|
+ TC_OFF = 9,
|
|
|
+ RD_MASK = 0x0100,
|
|
|
+ RD_OFF = 8,
|
|
|
+ RA_MASK = 0x0080,
|
|
|
+ RA_OFF = 7,
|
|
|
+ Z_MASK = 0x0040,
|
|
|
+ Z_OFF = 6,
|
|
|
+ AD_MASK = 0x0020,
|
|
|
+ AD_OFF = 5,
|
|
|
+ CD_MASK = 0x0010,
|
|
|
+ CD_OFF = 4,
|
|
|
+ RC_MASK = 0x000F,
|
|
|
+ RC_OFF = 0
|
|
|
};
|
|
|
|
|
|
/// \brief Constructor
|
|
@@ -53,22 +63,22 @@ public:
|
|
|
setValue(0);
|
|
|
}
|
|
|
|
|
|
+ /// \brief Get Header Flags as 16-bit Value
|
|
|
+ uint16_t getValue() const {
|
|
|
+ return (flags_);
|
|
|
+ }
|
|
|
+
|
|
|
/// \brief Set Header Flags as 16-Bit Value
|
|
|
///
|
|
|
/// \param value 16-bit value to put into object as representing the
|
|
|
/// header flags.
|
|
|
void setValue(uint16_t value) {
|
|
|
- flags_.value = value;
|
|
|
- }
|
|
|
-
|
|
|
- /// \brief Get Header Flags as 16-bit Value
|
|
|
- uint16_t getValue() const {
|
|
|
- return flags_.value;
|
|
|
+ flags_ = value;
|
|
|
}
|
|
|
|
|
|
/// \brief Get QR Bit
|
|
|
uint16_t getQR() const {
|
|
|
- return flags_.fields.qr;
|
|
|
+ return (getField(QR_MASK, QR_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set QR Bit
|
|
@@ -76,12 +86,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setQR(uint16_t value) {
|
|
|
- flags_.fields.qr = (value > 1) ? 1 : value;
|
|
|
+ setField(value, QR_MASK, QR_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get OP Value
|
|
|
uint16_t getOP() const {
|
|
|
- return flags_.fields.op;
|
|
|
+ return (getField(OP_MASK, OP_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set OP Value
|
|
@@ -89,12 +99,12 @@ public:
|
|
|
/// \param value New value of the field, which must in the range 0 to 15:
|
|
|
/// values outside that range are coerced to the nearest boundary.
|
|
|
void setOP(uint16_t value) {
|
|
|
- flags_.fields.op = (value > 15) ? 15 : value;
|
|
|
+ setField(value, OP_MASK, OP_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get AA Bit
|
|
|
uint16_t getAA() const {
|
|
|
- return flags_.fields.aa;
|
|
|
+ return (getField(AA_MASK, AA_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set AA Bit
|
|
@@ -102,12 +112,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setAA(uint16_t value) {
|
|
|
- flags_.fields.aa = (value > 1) ? 1 : value;
|
|
|
+ setField(value, AA_MASK, AA_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get TC Bit
|
|
|
uint16_t getTC() const {
|
|
|
- return flags_.fields.tc;
|
|
|
+ return (getField(TC_MASK, TC_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set TC Bit
|
|
@@ -115,12 +125,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setTC(uint16_t value) {
|
|
|
- flags_.fields.tc = (value > 1) ? 1 : value;
|
|
|
+ setField(value, TC_MASK, TC_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get RD Bit
|
|
|
uint16_t getRD() const {
|
|
|
- return flags_.fields.rd;
|
|
|
+ return (getField(RD_MASK, RD_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set RD Bit
|
|
@@ -128,12 +138,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setRD(uint16_t value) {
|
|
|
- flags_.fields.rd = (value > 1) ? 1 : value;
|
|
|
+ setField(value, RD_MASK, RD_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get RA Bit
|
|
|
uint16_t getRA() const {
|
|
|
- return flags_.fields.ra;
|
|
|
+ return (getField(RA_MASK, RA_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set RA Bit
|
|
@@ -141,12 +151,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setRA(uint16_t value) {
|
|
|
- flags_.fields.ra = (value > 1) ? 1 : value;
|
|
|
+ setField(value, RA_MASK, RA_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get Z Bit
|
|
|
uint16_t getZ() const {
|
|
|
- return flags_.fields.z;
|
|
|
+ return (getField(Z_MASK, Z_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set Z Bit
|
|
@@ -154,12 +164,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setZ(uint16_t value) {
|
|
|
- flags_.fields.z = (value > 1) ? 1 : value;
|
|
|
+ setField(value, Z_MASK, Z_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get AD Bit
|
|
|
uint16_t getAD() const {
|
|
|
- return flags_.fields.ad;
|
|
|
+ return (getField(AD_MASK, AD_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set AD Bit
|
|
@@ -167,12 +177,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setAD(uint16_t value) {
|
|
|
- flags_.fields.ad = (value > 1) ? 1 : value;
|
|
|
+ setField(value, AD_MASK, AD_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get CD Bit
|
|
|
uint16_t getCD() const {
|
|
|
- return flags_.fields.cd;
|
|
|
+ return (getField(CD_MASK, CD_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set CD Bit
|
|
@@ -180,12 +190,12 @@ public:
|
|
|
/// \param value New value of the field, which must be 0 or 1: values
|
|
|
/// outside that range are coerced to the nearest boundary.
|
|
|
void setCD(uint16_t value) {
|
|
|
- flags_.fields.cd = (value > 1) ? 1 : value;
|
|
|
+ setField(value, CD_MASK, CD_OFF);
|
|
|
}
|
|
|
|
|
|
/// \brief Get RC Value
|
|
|
uint16_t getRC() const {
|
|
|
- return flags_.fields.rc;
|
|
|
+ return (getField(RC_MASK, RC_OFF));
|
|
|
}
|
|
|
|
|
|
/// \brief Set RC Value
|
|
@@ -193,16 +203,43 @@ public:
|
|
|
/// \param value New value of the field, which must be in the range 0 to 15:
|
|
|
/// values outside that range are coerced to the nearest boundary.
|
|
|
void setRC(uint16_t value) {
|
|
|
- flags_.fields.rc = (value > 15) ? 15 : value;
|
|
|
+ setField(value, RC_MASK, RC_OFF);
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
|
|
- // The variable that performs the conversion
|
|
|
- union {
|
|
|
- uint16_t value;
|
|
|
- Flags fields;
|
|
|
- } flags_;
|
|
|
+ /// \brief Get Field
|
|
|
+ ///
|
|
|
+ /// Return the value of a bit field in the flags word.
|
|
|
+ ///
|
|
|
+ /// \param mask Bit mask identifying the field.
|
|
|
+ /// \param offset Offset of the field in the flags word.
|
|
|
+ ///
|
|
|
+ /// \return Value of the field.
|
|
|
+ uint16_t getField(FieldParameter mask, FieldParameter offset) const {
|
|
|
+ return ((flags_ & mask) >> offset);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// \brief Set Field
|
|
|
+ ///
|
|
|
+ /// Sets the value of a bit field.
|
|
|
+ ///
|
|
|
+ /// \param value Value to set. If the value is more than the field can
|
|
|
+ /// hold, it is set to the maximum.
|
|
|
+ /// \param mask Bit mask identifying the field.
|
|
|
+ /// \param offset Offset of the field in the flags word.
|
|
|
+ void setField(uint16_t value, FieldParameter mask, FieldParameter offset) {
|
|
|
+
|
|
|
+ // Ensure the value is within limits.
|
|
|
+ uint16_t maxval = mask >> offset;
|
|
|
+ uint16_t val = (value > maxval) ? maxval : value;
|
|
|
+
|
|
|
+ // Clear the field then set it with the value.
|
|
|
+ flags_ &= ~mask;
|
|
|
+ flags_ |= (val << offset);
|
|
|
+ }
|
|
|
+
|
|
|
+ uint16_t flags_; ///< Variable holding field values
|
|
|
};
|
|
|
|
|
|
} // namespace badpacket
|