- Timestamp:
- Jul 16, 2019 2:05:45 PM (6 years ago)
- Location:
- trunk/src/VBox/NetworkServices/Dhcpd
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/Dhcpd/Config.cpp
r79800 r79810 65 65 va_list va; 66 66 va_start(va, a_pszMsgFmt); 67 m_strMsg.appendPrintf (a_pszMsgFmt, va);67 m_strMsg.appendPrintfV(a_pszMsgFmt, va); 68 68 va_end(va); 69 69 } … … 91 91 m_strMsg.append('/'); 92 92 m_strMsg.append(pNode->getName()); 93 if (pNode->isElement() )93 if (pNode->isElement() && pNode->getParent()) 94 94 { 95 95 xml::ElementNode const *pElm = (xml::ElementNode const *)pNode; 96 for (xml::Node const *p NodeChild = pElm->getFirstChild(); pNodeChild!= NULL;97 pNodeChild = pNodeChild->getNextSibiling())98 if (p NodeChild->isAttribute())96 for (xml::Node const *pAttrib = pElm->getFirstAttribute(); pAttrib != NULL; 97 pAttrib = pAttrib->getNextSibiling()) 98 if (pAttrib->isAttribute()) 99 99 { 100 100 m_strMsg.append("[@"); 101 m_strMsg.append(p NodeChild->getName());101 m_strMsg.append(pAttrib->getName()); 102 102 m_strMsg.append('='); 103 m_strMsg.append(p NodeChild->getValue());103 m_strMsg.append(pAttrib->getValue()); 104 104 m_strMsg.append(']'); 105 105 } … … 882 882 void GroupConfig::i_parseChild(const xml::ElementNode *pElmChild, bool fStrict) 883 883 { 884 /* 885 * Match the condition 886 */ 887 std::unique_ptr<GroupCondition> ptrCondition; 884 888 if (pElmChild->nameEquals("ConditionMAC")) 885 { }889 ptrCondition.reset(new GroupConditionMAC()); 886 890 else if (pElmChild->nameEquals("ConditionMACWildcard")) 887 { }891 ptrCondition.reset(new GroupConditionMACWildcard()); 888 892 else if (pElmChild->nameEquals("ConditionVendorClassID")) 889 { }893 ptrCondition.reset(new GroupConditionVendorClassID()); 890 894 else if (pElmChild->nameEquals("ConditionVendorClassIDWildcard")) 891 { }895 ptrCondition.reset(new GroupConditionVendorClassIDWildcard()); 892 896 else if (pElmChild->nameEquals("ConditionUserClassID")) 893 { }897 ptrCondition.reset(new GroupConditionUserClassID()); 894 898 else if (pElmChild->nameEquals("ConditionUserClassIDWildcard")) 895 { }899 ptrCondition.reset(new GroupConditionUserClassIDWildcard()); 896 900 else 897 901 { 902 /* 903 * Not a condition, pass it on to the base class. 904 */ 898 905 ConfigLevelBase::i_parseChild(pElmChild, fStrict); 899 906 return; 907 } 908 909 /* 910 * Get the attributes and initialize the condition. 911 */ 912 bool fInclusive; 913 if (!pElmChild->getAttributeValue("inclusive", fInclusive)) 914 fInclusive = true; 915 const char *pszValue = pElmChild->findAttributeValue("value"); 916 if (pszValue && *pszValue) 917 { 918 int rc = ptrCondition->initCondition(pszValue, fInclusive); 919 if (RT_SUCCESS(rc)) 920 { 921 /* 922 * Add it to the appropriate vector. 923 */ 924 if (fInclusive) 925 m_Inclusive.push_back(ptrCondition.release()); 926 else 927 m_Exclusive.push_back(ptrCondition.release()); 928 } 929 else 930 { 931 ConfigFileError Xcpt(pElmChild, "initCondition failed with %Rrc for '%s' and %RTbool", rc, pszValue, fInclusive); 932 if (!fStrict) 933 LogRelFunc(("%s, ignoring condition\n", Xcpt.what())); 934 else 935 throw ConfigFileError(Xcpt); 936 } 937 } 938 else 939 { 940 ConfigFileError Xcpt(pElmChild, "condition value is empty or missing (inclusive=%RTbool)", fInclusive); 941 if (!fStrict) 942 LogRelFunc(("%s, ignoring condition\n", Xcpt.what())); 943 else 944 throw Xcpt; 900 945 } 901 946 } … … 990 1035 991 1036 /* Groups: */ 992 RT_NOREF(a_ridVendorClass, a_ridUserClass); /* not yet */ 1037 for (GroupConfigMap::const_iterator itGrp = m_GroupConfigs.begin(); itGrp != m_GroupConfigs.end(); ++itGrp) 1038 if (itGrp->second->match(a_ridClient, a_ridVendorClass, a_ridUserClass)) 1039 a_rRetConfigs.push_back(itGrp->second); 993 1040 994 1041 /* Global: */ … … 1076 1123 return a_rRetOpts; 1077 1124 } 1125 1126 1127 1128 /********************************************************************************************************************************* 1129 * Group Condition Matching * 1130 *********************************************************************************************************************************/ 1131 1132 bool GroupConfig::match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 1133 const OptUserClassId &a_ridUserClass) const 1134 { 1135 /* 1136 * Check the inclusive ones first, only one need to match. 1137 */ 1138 for (GroupConditionVec::const_iterator itIncl = m_Inclusive.begin(); itIncl != m_Inclusive.end(); ++itIncl) 1139 if ((*itIncl)->match(a_ridClient, a_ridVendorClass, a_ridUserClass)) 1140 { 1141 /* 1142 * Now make sure it isn't excluded by any of the exclusion condition. 1143 */ 1144 for (GroupConditionVec::const_iterator itExcl = m_Exclusive.begin(); itExcl != m_Exclusive.end(); ++itExcl) 1145 if ((*itIncl)->match(a_ridClient, a_ridVendorClass, a_ridUserClass)) 1146 return false; 1147 return true; 1148 } 1149 1150 return false; 1151 } 1152 1153 1154 int GroupCondition::initCondition(const char *a_pszValue, bool a_fInclusive) 1155 { 1156 m_fInclusive = a_fInclusive; 1157 return m_strValue.assignNoThrow(a_pszValue); 1158 } 1159 1160 1161 bool GroupCondition::matchClassId(bool a_fPresent, const std::vector<uint8_t> &a_rBytes, bool fWildcard) const RT_NOEXCEPT 1162 { 1163 if (a_fPresent) 1164 { 1165 size_t const cbBytes = a_rBytes.size(); 1166 if (cbBytes > 0) 1167 { 1168 if (a_rBytes[cbBytes - 1] == '\0') 1169 { 1170 uint8_t const *pb = &a_rBytes.front(); 1171 if (!fWildcard) 1172 return m_strValue.equals((const char *)pb); 1173 return RTStrSimplePatternMatch(m_strValue.c_str(), (const char *)pb); 1174 } 1175 1176 if (cbBytes <= 255) 1177 { 1178 char szTmp[256]; 1179 memcpy(szTmp, &a_rBytes.front(), cbBytes); 1180 szTmp[cbBytes] = '\0'; 1181 if (!fWildcard) 1182 return m_strValue.equals(szTmp); 1183 return RTStrSimplePatternMatch(m_strValue.c_str(), szTmp); 1184 } 1185 } 1186 } 1187 return false; 1188 1189 } 1190 1191 1192 int GroupConditionMAC::initCondition(const char *a_pszValue, bool a_fInclusive) 1193 { 1194 int vrc = RTNetStrToMacAddr(a_pszValue, &m_MACAddress); 1195 if (RT_SUCCESS(vrc)) 1196 return GroupCondition::initCondition(a_pszValue, a_fInclusive); 1197 return vrc; 1198 } 1199 1200 1201 bool GroupConditionMAC::match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 1202 const OptUserClassId &a_ridUserClass) const 1203 { 1204 RT_NOREF(a_ridVendorClass, a_ridUserClass); 1205 return a_ridClient.mac() == m_MACAddress; 1206 } 1207 1208 1209 bool GroupConditionMACWildcard::match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 1210 const OptUserClassId &a_ridUserClass) const 1211 { 1212 RT_NOREF(a_ridVendorClass, a_ridUserClass); 1213 char szTmp[32]; 1214 RTStrPrintf(szTmp, sizeof(szTmp), "%RTmac", &a_ridClient.mac()); 1215 return RTStrSimplePatternMatch(m_strValue.c_str(), szTmp); 1216 } 1217 1218 1219 bool GroupConditionVendorClassID::match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 1220 const OptUserClassId &a_ridUserClass) const 1221 { 1222 RT_NOREF(a_ridClient, a_ridUserClass); 1223 return matchClassId(a_ridVendorClass.present(), a_ridVendorClass.value()); 1224 } 1225 1226 1227 bool GroupConditionVendorClassIDWildcard::match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 1228 const OptUserClassId &a_ridUserClass) const 1229 { 1230 RT_NOREF(a_ridClient, a_ridUserClass); 1231 return matchClassId(a_ridVendorClass.present(), a_ridVendorClass.value(), true /*fWildcard*/); 1232 } 1233 1234 1235 bool GroupConditionUserClassID::match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 1236 const OptUserClassId &a_ridUserClass) const 1237 { 1238 RT_NOREF(a_ridClient, a_ridVendorClass); 1239 return matchClassId(a_ridVendorClass.present(), a_ridUserClass.value()); 1240 } 1241 1242 1243 bool GroupConditionUserClassIDWildcard::match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 1244 const OptUserClassId &a_ridUserClass) const 1245 { 1246 RT_NOREF(a_ridClient, a_ridVendorClass); 1247 return matchClassId(a_ridVendorClass.present(), a_ridUserClass.value(), true /*fWildcard*/); 1248 } 1249 -
trunk/src/VBox/NetworkServices/Dhcpd/Config.h
r79800 r79810 97 97 98 98 99 #if 0 /* later */100 99 /** 101 100 * Group membership condition. 102 101 */ 103 class GroupCondition Base102 class GroupCondition 104 103 { 105 104 protected: 106 105 /** The value. */ 107 106 RTCString m_strValue; 108 109 public: 110 111 }; 112 #endif 107 /** Inclusive (true) or exclusive (false), latter takes precedency. */ 108 bool m_fInclusive; 109 110 public: 111 virtual ~GroupCondition() 112 {} 113 114 virtual int initCondition(const char *a_pszValue, bool a_fInclusive); 115 virtual bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 116 const OptUserClassId &a_ridUserClass) const RT_NOEXCEPT = 0; 117 118 /** @name accessors 119 * @{ */ 120 RTCString const &getValue() const RT_NOEXCEPT { return m_strValue; } 121 bool getInclusive() const RT_NOEXCEPT { return m_fInclusive; } 122 /** @} */ 123 124 protected: 125 bool matchClassId(bool a_fPresent, std::vector<uint8_t> const &a_rBytes, bool fWildcard = false) const RT_NOEXCEPT; 126 }; 127 128 /** MAC condition. */ 129 class GroupConditionMAC : public GroupCondition 130 { 131 private: 132 RTMAC m_MACAddress; 133 public: 134 int initCondition(const char *a_pszValue, bool a_fInclusive) RT_OVERRIDE; 135 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 136 const OptUserClassId &a_ridUserClass) const RT_OVERRIDE; 137 }; 138 139 /** MAC wildcard condition. */ 140 class GroupConditionMACWildcard : public GroupCondition 141 { 142 public: 143 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 144 const OptUserClassId &a_ridUserClass) const RT_OVERRIDE; 145 }; 146 147 /** Vendor class ID condition. */ 148 class GroupConditionVendorClassID : public GroupCondition 149 { 150 public: 151 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 152 const OptUserClassId &a_ridUserClass) const RT_OVERRIDE; 153 }; 154 155 /** Vendor class ID wildcard condition. */ 156 class GroupConditionVendorClassIDWildcard : public GroupCondition 157 { 158 public: 159 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 160 const OptUserClassId &a_ridUserClass) const RT_OVERRIDE; 161 }; 162 163 /** User class ID condition. */ 164 class GroupConditionUserClassID : public GroupCondition 165 { 166 public: 167 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 168 const OptUserClassId &a_ridUserClass) const RT_OVERRIDE; 169 }; 170 171 /** User class ID wildcard condition. */ 172 class GroupConditionUserClassIDWildcard : public GroupCondition 173 { 174 public: 175 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, 176 const OptUserClassId &a_ridUserClass) const RT_OVERRIDE; 177 }; 113 178 114 179 … … 118 183 class GroupConfig : public ConfigLevelBase 119 184 { 120 public: 185 private: 186 typedef std::vector<GroupCondition *> GroupConditionVec; 187 121 188 /** The group name. */ 122 RTCString m_strName; 189 RTCString m_strName; 190 /** Vector containing the inclusive membership conditions (must match one). */ 191 GroupConditionVec m_Inclusive; 192 /** Vector containing the exclusive membership conditions (must match none). */ 193 GroupConditionVec m_Exclusive; 123 194 124 195 public: … … 129 200 130 201 void initFromXml(xml::ElementNode const *pElm, bool fStrict) RT_OVERRIDE; 131 const char *getType() const RT_NOEXCEPT RT_OVERRIDE { return "group"; } 132 const char *getName() const RT_NOEXCEPT RT_OVERRIDE { return m_strName.c_str(); } 202 bool match(const ClientId &a_ridClient, const OptVendorClassId &a_ridVendorClass, const OptUserClassId &a_ridUserClass) const; 133 203 134 204 /** @name Accessors 135 205 * @{ */ 206 const char *getType() const RT_NOEXCEPT RT_OVERRIDE { return "group"; } 207 const char *getName() const RT_NOEXCEPT RT_OVERRIDE { return m_strName.c_str(); } 136 208 RTCString const &getGroupName() const RT_NOEXCEPT { return m_strName; } 137 209 /** @} */ -
trunk/src/VBox/NetworkServices/Dhcpd/DhcpMessage.cpp
r79568 r79810 24 24 #include "DhcpOptions.h" 25 25 26 #include <iprt/ctype.h> 26 27 #include <iprt/string.h> 27 28 … … 279 280 } 280 281 281 bool fHeader = true;282 282 for (rawopts_t::const_iterator it = m_rawopts.begin(); it != m_rawopts.end(); ++it) 283 283 { … … 294 294 295 295 default: 296 if (fHeader) 297 { 298 LogRel((" other options:")); 299 fHeader = false; 300 } 301 LogRel((" %d", optcode)); 302 break; 296 { 297 size_t const cbBytes = it->second.size(); 298 uint8_t const *pbBytes = &it->second.front(); 299 bool fAllPrintable = true; 300 for (size_t off = 0; off < cbBytes; off++) 301 if (!RT_C_IS_PRINT((char )pbBytes[off])) 302 { 303 fAllPrintable = false; 304 break; 305 } 306 if (fAllPrintable) 307 LogRel((" %2d: '%.*s'\n", optcode, cbBytes, pbBytes)); 308 else 309 LogRel((" %2d: %.*Rhxs\n", optcode, cbBytes, pbBytes)); 310 } 303 311 } 304 312 } 305 if (!fHeader)306 LogRel(("\n"));307 313 } 308 314
Note:
See TracChangeset
for help on using the changeset viewer.