Changeset 58313 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Oct 19, 2015 4:31:59 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
r58283 r58313 79 79 }; 80 80 #undef GIMHV_MSRRANGE 81 82 /** 83 * DHCP OFFER packet response to the guest (client) over the Hyper-V debug 84 * transport. 85 * 86 * - MAC: Destination: broadcast. 87 * - MAC: Source: 00:00:00:00:01 (hypervisor). It's important that it's 88 * different from the client's MAC address which is all 0's. 89 * - IP: Source: 10.0.5.1 (hypervisor) 90 * - IP: Destination: broadcast. 91 * - IP: Checksum included. 92 * - BOOTP: Client IP address: 10.0.5.5. 93 * - BOOTP: Server IP address: 10.0.5.1. 94 * - DHCP options: Subnet mask, router, lease-time, DHCP server identifier. 95 * Options are kept to a minimum required for making Windows guests happy. 96 */ 97 #define GIMHV_DEBUGCLIENT_IPV4 RT_H2N_U32_C(0x0a000505) /* 10.0.5.5 */ 98 #define GIMHV_DEBUGSERVER_IPV4 RT_H2N_U32_C(0x0a000501) /* 10.0.5.1 */ 99 static const uint8_t g_abDhcpOffer[] = 100 { 101 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x45, 0x10, 102 0x01, 0x28, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x6a, 0xb5, 0x0a, 0x00, 0x05, 0x01, 0xff, 0xff, 103 0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x14, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x00, 0x00, 104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0x05, 0x00, 0x00, 105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, 119 0xff, 0xff, 0x00, 0x03, 0x04, 0x0a, 0x00, 0x05, 0x01, 0x33, 0x04, 0xff, 0xff, 0xff, 0xff, 0x36, 120 0x04, 0x0a, 0x00, 0x05, 0x01, 0xff 121 }; 122 123 /** 124 * DHCP ACK packet response to the guest (client) over the Hyper-V debug 125 * transport. 126 * 127 * - MAC: Destination: 00:00:00:00:00 (client). 128 * - IP: Destination: 10.0.5.5 (client). 129 * - Rest are mostly similar to the DHCP offer. 130 */ 131 static const uint8_t g_abDhcpAck[] = 132 { 133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x45, 0x10, 134 0x01, 0x28, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0x5b, 0xb0, 0x0a, 0x00, 0x05, 0x01, 0x0a, 0x00, 135 0x05, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x14, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x00, 0x00, 136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0x05, 0x0a, 0x00, 0x05, 0x05, 0x00, 0x00, 137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x01, 0x04, 0xff, 151 0xff, 0xff, 0x00, 0x03, 0x04, 0x0a, 0x00, 0x05, 0x01, 0x33, 0x04, 0xff, 0xff, 0xff, 0xff, 0x36, 152 0x04, 0x0a, 0x00, 0x05, 0x01, 0xff 153 }; 154 155 /** 156 * ARP reply to the guest (client) over the Hyper-V debug transport. 157 * 158 * - MAC: Destination: 00:00:00:00:00 (client) 159 * - MAC: Source: 00:00:00:00:01 (hypervisor) 160 * - ARP: Reply: 10.0.5.1 is at Source MAC address. 161 */ 162 static const uint8_t g_abArpReply[] = 163 { 164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x01, 165 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x05, 0x01, 166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x05, 0x05 167 }; 81 168 82 169 … … 1026 1113 AssertReturn(cbBuf >= cbRead, VERR_INVALID_PARAMETER); 1027 1114 1028 /* 1029 * Read the data. 1030 */ 1031 size_t cbReallyRead = cbRead; 1032 int rc = GIMR3DebugRead(pVM, pvBuf, &cbReallyRead); 1033 1034 /* 1035 * Encapsulate it in a UDP packet if required. 1036 */ 1037 if ( RT_SUCCESS(rc) 1038 && fUdpPkt 1039 && cbReallyRead > 0) 1040 { 1041 uint8_t abFrame[sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + sizeof(RTNETUDP)]; 1042 if (cbReallyRead + sizeof(abFrame) <= cbBuf) 1115 int rc; 1116 if (!fUdpPkt) 1117 { 1118 /* 1119 * Read the raw debug data. 1120 */ 1121 size_t cbReallyRead = cbRead; 1122 rc = GIMR3DebugRead(pVM, pvBuf, &cbReallyRead); 1123 *pcbRead = (uint32_t)cbReallyRead; 1124 } 1125 else 1126 { 1127 /* 1128 * Guest requires UDP encapsulated frames. 1129 */ 1130 PGIMHV pHv = &pVM->gim.s.u.Hv; 1131 rc = VERR_GIM_IPE_1; 1132 switch (pHv->enmDebugReply) 1043 1133 { 1044 /* 1045 * Windows guests pumps ethernet frames over the Hyper-V debug connection as 1046 * explained in gimR3HvHypercallPostDebugData(). Here, we reconstruct the packet 1047 * with the guest's self-chosen IP ARP address we saved in pHv->DbgGuestAddr. 1048 * 1049 * Note! We really need to pass the minimum IPv4 header length. The Windows 10 guest 1050 * is -not- happy if we include the IPv4 options field, i.e. using sizeof(RTNETIPV4) 1051 * instead of RTNETIPV4_MIN_LEN. 1052 */ 1053 PGIMHV pHv = &pVM->gim.s.u.Hv; 1054 RT_ZERO(abFrame); 1055 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)&abFrame[0]; 1056 PRTNETIPV4 pIpHdr = (PRTNETIPV4) (pEthHdr + 1); 1057 PRTNETUDP pUdpHdr = (PRTNETUDP) ((uint8_t *)pIpHdr + RTNETIPV4_MIN_LEN); 1058 1059 /* Ethernet */ 1060 pEthHdr->EtherType = RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4); 1061 /* IPv4 */ 1062 pIpHdr->ip_v = 4; 1063 pIpHdr->ip_hl = RTNETIPV4_MIN_LEN / sizeof(uint32_t); 1064 pIpHdr->ip_tos = 0; 1065 pIpHdr->ip_len = RT_H2N_U16((uint16_t)cbReallyRead + sizeof(RTNETUDP) + RTNETIPV4_MIN_LEN); 1066 pIpHdr->ip_id = 0; 1067 pIpHdr->ip_off = 0; 1068 pIpHdr->ip_ttl = 255; 1069 pIpHdr->ip_p = RTNETIPV4_PROT_UDP; 1070 pIpHdr->ip_sum = 0; 1071 pIpHdr->ip_src.u = 0; 1072 pIpHdr->ip_dst.u = pHv->DbgGuestAddr.u; 1073 pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr); 1074 /* UDP */ 1075 pUdpHdr->uh_ulen = RT_H2N_U16_C((uint16_t)cbReallyRead + sizeof(*pUdpHdr)); 1076 1077 /* Make room by moving the payload and prepending the headers. */ 1078 uint8_t *pbData = (uint8_t *)pvBuf; 1079 memmove(pbData + sizeof(abFrame), pbData, cbReallyRead); 1080 memcpy(pbData, &abFrame[0], sizeof(abFrame)); 1081 1082 /* Update the adjusted sizes. */ 1083 cbReallyRead += sizeof(abFrame); 1134 case GIMHVDEBUGREPLY_UDP: 1135 { 1136 size_t cbReallyRead = cbRead; 1137 rc = GIMR3DebugRead(pVM, pvBuf, &cbReallyRead); 1138 if ( RT_SUCCESS(rc) 1139 && cbReallyRead > 0) 1140 { 1141 uint8_t abFrame[sizeof(RTNETETHERHDR) + RTNETIPV4_MIN_LEN + sizeof(RTNETUDP)]; 1142 if (cbReallyRead + sizeof(abFrame) <= cbBuf) 1143 { 1144 /* 1145 * Windows guests pumps ethernet frames over the Hyper-V debug connection as 1146 * explained in gimR3HvHypercallPostDebugData(). Here, we reconstruct the packet 1147 * with the guest's self-chosen IP ARP address we saved in pHv->DbgGuestAddr. 1148 * 1149 * Note! We really need to pass the minimum IPv4 header length. The Windows 10 guest 1150 * is -not- happy if we include the IPv4 options field, i.e. using sizeof(RTNETIPV4) 1151 * instead of RTNETIPV4_MIN_LEN. 1152 */ 1153 RT_ZERO(abFrame); 1154 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)&abFrame[0]; 1155 PRTNETIPV4 pIpHdr = (PRTNETIPV4) (pEthHdr + 1); 1156 PRTNETUDP pUdpHdr = (PRTNETUDP) ((uint8_t *)pIpHdr + RTNETIPV4_MIN_LEN); 1157 1158 /* Ethernet */ 1159 pEthHdr->EtherType = RT_H2N_U16_C(RTNET_ETHERTYPE_IPV4); 1160 /* IPv4 */ 1161 pIpHdr->ip_v = 4; 1162 pIpHdr->ip_hl = RTNETIPV4_MIN_LEN / sizeof(uint32_t); 1163 pIpHdr->ip_tos = 0; 1164 pIpHdr->ip_len = RT_H2N_U16((uint16_t)cbReallyRead + sizeof(RTNETUDP) + RTNETIPV4_MIN_LEN); 1165 pIpHdr->ip_id = 0; 1166 pIpHdr->ip_off = 0; 1167 pIpHdr->ip_ttl = 255; 1168 pIpHdr->ip_p = RTNETIPV4_PROT_UDP; 1169 pIpHdr->ip_sum = 0; 1170 pIpHdr->ip_src.u = 0; 1171 pIpHdr->ip_dst.u = pHv->DbgGuestAddr.u; 1172 pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr); 1173 /* UDP */ 1174 pUdpHdr->uh_ulen = RT_H2N_U16_C((uint16_t)cbReallyRead + sizeof(*pUdpHdr)); 1175 1176 /* Make room by moving the payload and prepending the headers. */ 1177 uint8_t *pbData = (uint8_t *)pvBuf; 1178 memmove(pbData + sizeof(abFrame), pbData, cbReallyRead); 1179 memcpy(pbData, &abFrame[0], sizeof(abFrame)); 1180 1181 /* Update the adjusted sizes. */ 1182 cbReallyRead += sizeof(abFrame); 1183 } 1184 else 1185 rc = VERR_BUFFER_UNDERFLOW; 1186 } 1187 *pcbRead = (uint32_t)cbReallyRead; 1188 break; 1189 } 1190 1191 case GIMHVDEBUGREPLY_ARP_REPLY: 1192 { 1193 uint32_t const cbArpReplyPkt = sizeof(g_abArpReply); 1194 if (cbBuf >= cbArpReplyPkt) 1195 { 1196 memcpy(pvBuf, g_abArpReply, cbArpReplyPkt); 1197 rc = VINF_SUCCESS; 1198 *pcbRead = cbArpReplyPkt; 1199 pHv->enmDebugReply = GIMHVDEBUGREPLY_ARP_REPLY_SENT; 1200 } 1201 else 1202 { 1203 rc = VERR_BUFFER_UNDERFLOW; 1204 *pcbRead = 0; 1205 } 1206 break; 1207 } 1208 1209 case GIMHVDEBUGREPLY_DHCP_OFFER: 1210 { 1211 uint32_t const cbDhcpOfferPkt = sizeof(g_abDhcpOffer); 1212 if (cbBuf >= cbDhcpOfferPkt) 1213 { 1214 memcpy(pvBuf, g_abDhcpOffer, cbDhcpOfferPkt); 1215 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pvBuf; 1216 PRTNETIPV4 pIpHdr = (PRTNETIPV4) (pEthHdr + 1); 1217 PRTNETUDP pUdpHdr = (PRTNETUDP) ((uint8_t *)pIpHdr + RTNETIPV4_MIN_LEN); 1218 PRTNETBOOTP pBootpHdr = (PRTNETBOOTP) (pUdpHdr + 1); 1219 pBootpHdr->bp_xid = pHv->uBootpXId; 1220 1221 rc = VINF_SUCCESS; 1222 *pcbRead = cbDhcpOfferPkt; 1223 pHv->enmDebugReply = GIMHVDEBUGREPLY_DHCP_OFFER_SENT; 1224 LogRel(("GIM: HyperV: Debug DHCP offered IP address %RTnaipv4, transaction Id %#x\n", pBootpHdr->bp_yiaddr, 1225 RT_N2H_U32(pHv->uBootpXId))); 1226 } 1227 else 1228 { 1229 rc = VERR_BUFFER_UNDERFLOW; 1230 *pcbRead = 0; 1231 } 1232 break; 1233 } 1234 1235 case GIMHVDEBUGREPLY_DHCP_ACK: 1236 { 1237 uint32_t const cbDhcpAckPkt = sizeof(g_abDhcpAck); 1238 if (cbBuf >= cbDhcpAckPkt) 1239 { 1240 memcpy(pvBuf, g_abDhcpAck, cbDhcpAckPkt); 1241 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pvBuf; 1242 PRTNETIPV4 pIpHdr = (PRTNETIPV4) (pEthHdr + 1); 1243 PRTNETUDP pUdpHdr = (PRTNETUDP) ((uint8_t *)pIpHdr + RTNETIPV4_MIN_LEN); 1244 PRTNETBOOTP pBootpHdr = (PRTNETBOOTP) (pUdpHdr + 1); 1245 pBootpHdr->bp_xid = pHv->uBootpXId; 1246 1247 rc = VINF_SUCCESS; 1248 *pcbRead = cbDhcpAckPkt; 1249 pHv->enmDebugReply = GIMHVDEBUGREPLY_DHCP_ACK_SENT; 1250 LogRel(("GIM: HyperV: Debug DHCP acknowledged IP address %RTnaipv4, transaction Id %#x\n", 1251 pBootpHdr->bp_yiaddr, RT_N2H_U32(pHv->uBootpXId))); 1252 } 1253 else 1254 { 1255 rc = VERR_BUFFER_UNDERFLOW; 1256 *pcbRead = 0; 1257 } 1258 break; 1259 } 1260 1261 case GIMHVDEBUGREPLY_ARP_REPLY_SENT: 1262 case GIMHVDEBUGREPLY_DHCP_OFFER_SENT: 1263 case GIMHVDEBUGREPLY_DHCP_ACK_SENT: 1264 { 1265 rc = VINF_SUCCESS; 1266 *pcbRead = 0; 1267 break; 1268 } 1269 1270 default: 1271 { 1272 AssertMsgFailed(("GIM: HyperV: Invalid/unimplemented debug reply type %u\n", pHv->enmDebugReply)); 1273 rc = VERR_INTERNAL_ERROR_2; 1274 } 1084 1275 } 1085 else 1086 rc = VERR_BUFFER_UNDERFLOW; 1087 } 1088 1089 *pcbRead = (uint32_t)cbReallyRead; 1276 Assert(rc != VERR_GIM_IPE_1); 1277 } 1090 1278 return rc; 1091 1279 } … … 1122 1310 * protocol payload. 1123 1311 * 1124 * At present, we only handle guests configured with the "nodhcp" option. This makes1125 * the guest send ARP queries with a self-chosen IP and after a couple of attempts of1126 * receiving no replies, the guest picks its own IP address. After this, the guest1127 * starts sending the UDP packets we require. We thus ignore the initial ARP packets1128 * (and to be safe all non-UDP packets) until the guest eventually starts talking1129 * UDP. Then we can finally feed the UDP payload over the debugconnection.1312 * If the guest is configured with the "nodhcp" option it sends ARP queries with 1313 * a self-chosen IP and after a couple of attempts of receiving no replies, the guest 1314 * picks its own IP address. After this, the guest starts sending the UDP packets 1315 * we require. We thus ignore the initial ARP packets until the guest eventually 1316 * starts talking UDP. Then we can finally feed the UDP payload over the debug 1317 * connection. 1130 1318 */ 1131 1319 if (cbWrite > sizeof(RTNETETHERHDR)) … … 1150 1338 { 1151 1339 /* 1152 * Extract the UDP payload and pass it to the debugger and record the guest IP address. 1153 * Hyper-V sends UDP debugger packets with source and destination port as 0. If we don't 1154 * filter out the ports here, we would receive BOOTP, NETBIOS and other UDP sub-protocol 1155 * packets which the debugger yells as "Bad packet received from...". 1340 * Check for DHCP. 1156 1341 */ 1157 if ( !pUdpHdr->uh_dport 1158 && !pUdpHdr->uh_sport) 1342 size_t const cbUdpPkt = cbMaxIpPkt - cbIpHdr; 1343 if ( pUdpHdr->uh_dport == RT_N2H_U16_C(RTNETIPV4_PORT_BOOTPS) 1344 && pUdpHdr->uh_sport == RT_N2H_U16_C(RTNETIPV4_PORT_BOOTPC) 1345 && cbMaxIpPkt >= cbIpHdr + RTNETUDP_MIN_LEN + RTNETBOOTP_DHCP_MIN_LEN) 1159 1346 { 1347 PCRTNETBOOTP pDhcpPkt = (PCRTNETBOOTP)(pUdpHdr + 1); 1348 uint8_t bMsgType; 1349 if (RTNetIPv4IsDHCPValid(pUdpHdr, pDhcpPkt, cbUdpPkt - sizeof(*pUdpHdr), &bMsgType)) 1350 { 1351 switch (bMsgType) 1352 { 1353 case RTNET_DHCP_MT_DISCOVER: 1354 pHv->enmDebugReply = GIMHVDEBUGREPLY_DHCP_OFFER; 1355 pHv->uBootpXId = pDhcpPkt->bp_xid; 1356 break; 1357 case RTNET_DHCP_MT_REQUEST: 1358 pHv->enmDebugReply = GIMHVDEBUGREPLY_DHCP_ACK; 1359 pHv->uBootpXId = pDhcpPkt->bp_xid; 1360 break; 1361 default: 1362 LogRelMax(5, ("GIM: HyperV: Debug DHCP MsgType %#x not implemented! Packet dropped\n", 1363 bMsgType)); 1364 break; 1365 } 1366 } 1367 fIgnorePkt = true; 1368 } 1369 else if ( !pUdpHdr->uh_dport 1370 && !pUdpHdr->uh_sport) 1371 { 1372 /* 1373 * Extract the UDP payload and pass it to the debugger and record the guest IP address. 1374 * Hyper-V sends UDP debugger packets with source and destination port as 0. If we don't 1375 * filter out the ports here, we would receive BOOTP, NETBIOS and other UDP sub-protocol 1376 * packets which the debugger yells as "Bad packet received from...". 1377 */ 1160 1378 uint32_t const cbFrameHdr = sizeof(RTNETETHERHDR) + cbIpHdr + sizeof(RTNETUDP); 1161 1379 pbData += cbFrameHdr; 1162 1380 cbWrite -= cbFrameHdr; 1163 1381 pHv->DbgGuestAddr = pIp4Hdr->ip_src; 1382 pHv->enmDebugReply = GIMHVDEBUGREPLY_UDP; 1164 1383 } 1165 1384 else … … 1189 1408 } 1190 1409 } 1410 else if (pEtherHdr->EtherType == RT_H2N_U16_C(RTNET_ETHERTYPE_ARP)) 1411 { 1412 /* 1413 * Check for targetted ARP query. 1414 */ 1415 PCRTNETARPHDR pArpHdr = (PCRTNETARPHDR)(pbData + sizeof(RTNETETHERHDR)); 1416 if ( pArpHdr->ar_hlen == sizeof(RTMAC) 1417 && pArpHdr->ar_plen == sizeof(RTNETADDRIPV4) 1418 && pArpHdr->ar_htype == RT_H2N_U16(RTNET_ARP_ETHER) 1419 && pArpHdr->ar_ptype == RT_H2N_U16(RTNET_ETHERTYPE_IPV4)) 1420 { 1421 uint16_t uArpOp = pArpHdr->ar_oper; 1422 if (uArpOp == RT_H2N_U16_C(RTNET_ARPOP_REQUEST)) 1423 { 1424 PCRTNETARPIPV4 pArpPkt = (PCRTNETARPIPV4)pArpHdr; 1425 bool fGratuitous = pArpPkt->ar_spa.u == pArpPkt->ar_tpa.u; 1426 if ( !fGratuitous 1427 && pArpPkt->ar_spa.u == GIMHV_DEBUGCLIENT_IPV4 1428 && pArpPkt->ar_tpa.u == GIMHV_DEBUGSERVER_IPV4) 1429 { 1430 pHv->enmDebugReply = GIMHVDEBUGREPLY_ARP_REPLY; 1431 } 1432 } 1433 } 1434 fIgnorePkt = true; 1435 } 1191 1436 else 1192 1437 {
Note:
See TracChangeset
for help on using the changeset viewer.