Changeset 11123 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Aug 4, 2008 8:28:13 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 34060
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r11119 r11123 46 46 /** @def INTNET_WITH_DHCP_SNOOPING 47 47 * Enabled DHCP snooping when in shared-mac-on-the-wire mode. */ 48 /*#define INTNET_WITH_DHCP_SNOOPING - the implementation isn't completed yet. */ 48 #define INTNET_WITH_DHCP_SNOOPING 49 49 50 50 … … 809 809 static void intnetR0IfAddrCacheDeleteIt(PINTNETIF pIf, PINTNETADDRCACHE pCache, int iEntry, const char *pszMsg) 810 810 { 811 Log(("intnetR0IfAddrCacheDeleteIt: hIf=%RX32 type=%d #%d %.*Rhxs %s\n", pIf->hIf,812 (int)(intptr_t)(pCache - &pIf->aAddrCache[0]), iEntry, pCache->cbAddress,813 pCache->pbEntries + iEntry * pCache->cbEntry, pszMsg));814 811 AssertReturnVoid(iEntry < pCache->cEntries); 812 AssertReturnVoid(iEntry >= 0); 813 #ifdef LOG_ENABLED 814 INTNETADDRTYPE enmAddrType = (INTNETADDRTYPE)(uintptr_t)(pCache - &pIf->aAddrCache[0]); 815 PCRTNETADDRU pAddr = (PCRTNETADDRU)(pCache->pbEntries + iEntry * pCache->cbEntry); 816 switch (enmAddrType) 817 { 818 case kIntNetAddrType_IPv4: 819 Log(("intnetR0IfAddrCacheDeleteIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %d.%d.%d.%d %s\n", 820 pIf->hIf, &pIf->Mac, iEntry, pAddr->au8[0], pAddr->au8[1], pAddr->au8[2], pAddr->au8[3], pszMsg)); 821 break; 822 default: 823 Log(("intnetR0IfAddrCacheDeleteIt: hIf=%RX32 MAC=%.6Rhxs type=%d #%d %.*Rhxs %s\n", 824 pIf->hIf, &pIf->Mac, enmAddrType, iEntry, pCache->cbAddress, pAddr, pszMsg)); 825 break; 826 } 827 #endif 828 815 829 pCache->cEntries--; 816 830 if (iEntry < pCache->cEntries) … … 957 971 memcpy(pbEntry, pAddr, pCache->cbAddress); 958 972 memset(pbEntry + pCache->cbAddress, '\0', pCache->cbEntry - pCache->cbAddress); 959 Log(("intnetR0IfAddrCacheAddIt: type=%d added #%d %.*Rhxs %s\n", 960 (int)(uintptr_t)(pCache - &pIf->aAddrCache[0]), pCache->cEntries, 961 pCache->cbAddress, pAddr, pszMsg)); 973 #ifdef LOG_ENABLED 974 INTNETADDRTYPE enmAddrType = (INTNETADDRTYPE)(uintptr_t)(pCache - &pIf->aAddrCache[0]); 975 switch (enmAddrType) 976 { 977 case kIntNetAddrType_IPv4: 978 Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs IPv4 added #%d %d.%d.%d.%d %s\n", 979 pIf->hIf, &pIf->Mac, pCache->cEntries, pAddr->au8[0], pAddr->au8[1], pAddr->au8[2], pAddr->au8[3], pszMsg)); 980 break; 981 default: 982 Log(("intnetR0IfAddrCacheAddIt: hIf=%#x MAC=%.6Rhxs type=%d added #%d %.*Rhxs %s\n", 983 pIf->hIf, &pIf->Mac, enmAddrType, pCache->cEntries, pCache->cbAddress, pAddr, pszMsg)); 984 break; 985 } 986 #endif 962 987 pCache->cEntries++; 963 988 Assert(pCache->cEntries <= pCache->cEntriesAlloc); … … 1041 1066 static void intnetR0NetworkSnoopDhcp(PINTNETNETWORK pNetwork, PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, uint32_t cbUdpPkt) 1042 1067 { 1043 /** @todo later */ 1044 } 1045 1046 1068 /* 1069 * Check if the DHCP message is valid and get the type. 1070 */ 1071 if (!RTNetIPv4IsUDPValid(pIpHdr, pUdpHdr, pUdpHdr + 1, cbUdpPkt)) 1072 { 1073 Log6(("Bad UDP packet\n")); 1074 return; 1075 } 1076 PCRTNETBOOTP pDhcp = (PCRTNETBOOTP)(pUdpHdr + 1); 1077 uint8_t MsgType; 1078 if (!RTNetIPv4IsDHCPValid(pUdpHdr, pDhcp, cbUdpPkt - sizeof(*pUdpHdr), &MsgType)) 1079 { 1080 Log6(("Bad DHCP packet\n")); 1081 return; 1082 } 1083 1084 #ifdef LOG_ENABLED 1085 /* 1086 * Log it. 1087 */ 1088 const char *pszType = "unknown"; 1089 switch (MsgType) 1090 { 1091 case RTNET_DHCP_MT_DISCOVER: pszType = "discover"; break; 1092 case RTNET_DHCP_MT_OFFER: pszType = "offer"; break; 1093 case RTNET_DHCP_MT_REQUEST: pszType = "request"; break; 1094 case RTNET_DHCP_MT_DECLINE: pszType = "decline"; break; 1095 case RTNET_DHCP_MT_ACK: pszType = "ack";break; 1096 case RTNET_DHCP_MT_NAC: pszType = "nac"; break; 1097 case RTNET_DHCP_MT_RELEASE: pszType = "release"; break; 1098 case RTNET_DHCP_MT_INFORM: pszType = "inform"; break; 1099 } 1100 Log6(("DHCP msg: %d (%s) client %.6Rhxs ciaddr=%d.%d.%d.%d yiaddr=%d.%d.%d.%d\n", MsgType, pszType, &pDhcp->bp_chaddr, 1101 pDhcp->bp_ciaddr.au8[0], pDhcp->bp_ciaddr.au8[1], pDhcp->bp_ciaddr.au8[2], pDhcp->bp_ciaddr.au8[3], 1102 pDhcp->bp_yiaddr.au8[0], pDhcp->bp_yiaddr.au8[1], pDhcp->bp_yiaddr.au8[2], pDhcp->bp_yiaddr.au8[3])); 1103 #endif /* LOG_EANBLED */ 1104 1105 /* 1106 * Act upon the message. 1107 */ 1108 switch (MsgType) 1109 { 1110 /* 1111 * Lookup the interface by its MAC address and insert the IPv4 address into the cache. 1112 * Delete the old client address first, just in case it changed in a renewal. 1113 */ 1114 case RTNET_DHCP_MT_ACK: 1115 if (intnetR0IPv4AddrIsGood(pDhcp->bp_yiaddr)) 1116 for (PINTNETIF pCur = pNetwork->pIFs; pCur; pCur = pCur->pNext) 1117 if ( pCur->fMacSet 1118 && !memcmp(&pCur->Mac, &pDhcp->bp_chaddr, sizeof(RTMAC))) 1119 { 1120 intnetR0IfAddrCacheDelete(pCur, &pCur->aAddrCache[kIntNetAddrType_IPv4], 1121 (PCRTNETADDRU)&pDhcp->bp_ciaddr, sizeof(RTNETADDRIPV4), "DHCP_MT_ACK"); 1122 intnetR0IfAddrCacheAdd(pCur, &pCur->aAddrCache[kIntNetAddrType_IPv4], 1123 (PCRTNETADDRU)&pDhcp->bp_yiaddr, sizeof(RTNETADDRIPV4), "DHCP_MT_ACK"); 1124 break; 1125 } 1126 break; 1127 1128 1129 /* 1130 * Lookup the interface by its MAC address and remove the IPv4 address(es) from the cache. 1131 */ 1132 case RTNET_DHCP_MT_RELEASE: 1133 { 1134 for (PINTNETIF pCur = pNetwork->pIFs; pCur; pCur = pCur->pNext) 1135 if ( pCur->fMacSet 1136 && !memcmp(&pCur->Mac, &pDhcp->bp_chaddr, sizeof(RTMAC))) 1137 { 1138 intnetR0IfAddrCacheDelete(pCur, &pCur->aAddrCache[kIntNetAddrType_IPv4], 1139 (PCRTNETADDRU)&pDhcp->bp_ciaddr, sizeof(RTNETADDRIPV4), "DHCP_MT_RELEASE"); 1140 intnetR0IfAddrCacheDelete(pCur, &pCur->aAddrCache[kIntNetAddrType_IPv4], 1141 (PCRTNETADDRU)&pDhcp->bp_yiaddr, sizeof(RTNETADDRIPV4), "DHCP_MT_RELEASE"); 1142 } 1143 break; 1144 } 1145 } 1146 1147 } 1148 1149 1150 /** 1151 * Worker for intnetR0TrunkIfSnoopAddr that takes care of what 1152 * is likely to be a DHCP message. 1153 * 1154 * The caller has already check that the UDP source and destination ports 1155 * are BOOTPS or BOOTPC. 1156 * 1157 * @param pNetwork The network this frame was seen on. 1158 * @param pSG The gather list for the frame. 1159 */ 1047 1160 static void intnetR0TrunkIfSnoopDhcp(PINTNETNETWORK pNetwork, PCINTNETSG pSG) 1048 1161 { 1162 /* 1163 * Get a pointer to a linear copy of the full packet, using the 1164 * temporary buffer if necessary. 1165 */ 1166 PCRTNETIPV4 pIpHdr = (PCRTNETIPV4)((PCRTNETETHERHDR)pSG->aSegs[0].pv + 1); 1167 size_t cbPacket = pSG->cbTotal - sizeof(RTNETETHERHDR); 1168 if (pSG->cSegsUsed > 1) 1169 { 1170 cbPacket = RT_MIN(cbPacket, INTNETNETWORK_TMP_SIZE); 1171 Log6(("intnetR0TrunkIfSnoopDhcp: Copying IPv4/UDP/DHCP pkt %u\n", cbPacket)); 1172 if (!intnetR0SgReadPart(pSG, sizeof(RTNETETHERHDR), cbPacket, pNetwork->pbTmp)) 1173 return; 1174 //pSG->fFlags |= INTNETSG_FLAGS_PKT_CP_IN_TMP; 1175 pIpHdr = (PCRTNETIPV4)pNetwork->pbTmp; 1176 } 1177 1178 /* 1179 * Validate the IP header and find the UDP packet. 1180 */ 1181 if (!RTNetIPv4IsHdrValid(pIpHdr, cbPacket, pSG->cbTotal - sizeof(RTNETETHERHDR))) 1182 { 1183 Log(("intnetR0TrunkIfSnoopDhcp: bad ip header\n")); 1184 return; 1185 } 1186 size_t cbIpHdr = pIpHdr->ip_hl * 4; 1187 1188 /* 1189 * Hand it over to the common DHCP snooper. 1190 */ 1191 intnetR0NetworkSnoopDhcp(pNetwork, pIpHdr, (PCRTNETUDP)((uintptr_t)pIpHdr + cbIpHdr), cbPacket - cbIpHdr); 1049 1192 } 1050 1193 … … 1058 1201 * The purpose of this purging is to get rid of stale addresses. 1059 1202 * 1060 * @param pNetwork The network th e this frame was seen on.1203 * @param pNetwork The network this frame was seen on. 1061 1204 * @param pSG The gather list for the frame. 1062 1205 */ … … 1158 1301 if (b) 1159 1302 return; 1303 1304 /* get the lower byte of the UDP destination port number. */ 1305 b = intnetR0SgReadByte(pSG, sizeof(RTNETETHERHDR) + cbIpHdr + RT_OFFSETOF(RTNETUDP, uh_dport) + 1); 1306 if ( b != RTNETIPV4_PORT_BOOTPS 1307 && b != RTNETIPV4_PORT_BOOTPC) 1308 return; 1309 b = intnetR0SgReadByte(pSG, sizeof(RTNETETHERHDR) + cbIpHdr + RT_OFFSETOF(RTNETUDP, uh_dport)); 1310 if (b) 1311 return; 1160 1312 intnetR0TrunkIfSnoopDhcp(pNetwork, pSG); 1161 1313 break; … … 1197 1349 return; 1198 1350 uint32_t cbHdr = (uint32_t)pIpHdr->ip_hl * 4; 1199 if ( cbHdr < RT _UOFFSETOF(RTNETIPV4, ip_options)1351 if ( cbHdr < RTNETIPV4_MIN_LEN 1200 1352 || cbPacket < cbHdr) 1201 1353 return; 1202 1354 1203 1355 /* 1204 * I gnore non good IP address (like broadcast and my network),1205 * also skip packets containing address that are already in the1206 * cache. Don't ignore potential DHCP traffic though.1356 * If the source address is good (not broadcast or my network) and 1357 * not already in the address cache of the sender, add it. Validate 1358 * the IP header before adding it. 1207 1359 */ 1208 1360 bool fValidatedIpHdr = false; … … 1212 1364 && intnetR0IfAddrCacheLookupLikely(&pIf->aAddrCache[kIntNetAddrType_IPv4], &Addr, sizeof(Addr.IPv4)) < 0) 1213 1365 { 1214 /*1215 * Got a candidate, check that the IP header is valid before adding it.1216 */1217 1366 if (!RTNetIPv4IsHdrValid(pIpHdr, cbPacket, cbPacket)) 1218 1367 { … … 3455 3604 Assert(pTrunkIF->pIfPort); 3456 3605 pNetwork->pTrunkIF = pTrunkIF; 3457 Log(("intnetR0NetworkCreateTrunkIf: VINF_SUCCESS - pszName=%s szTrunk=%s %s Network=%s%s\n",3606 Log(("intnetR0NetworkCreateTrunkIf: VINF_SUCCESS - pszName=%s szTrunk=%s%s Network=%s\n", 3458 3607 pszName, pNetwork->szTrunk, pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE ? " shared-mac" : "", pNetwork->szName)); 3459 3608 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.