Changeset 87380 in vbox for trunk/src/VBox/NetworkServices/NAT
- Timestamp:
- Jan 22, 2021 10:18:46 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/NetworkServices/NAT/VBoxNetLwipNAT.cpp
r87379 r87380 132 132 static int fetchNatPortForwardRules(const ComNatPtr&, bool, VECNATSERVICEPF&); 133 133 134 static int vboxNetNATLogInit(int argc, char **argv);135 136 134 137 135 class VBoxNetLwipNAT: public VBoxNetBaseService, public NATNetworkEventAdapter 138 136 { 139 137 friend class NATNetworkListener; 138 140 139 public: 141 140 VBoxNetLwipNAT(SOCKET icmpsock4, SOCKET icmpsock6); 142 141 virtual ~VBoxNetLwipNAT(); 142 143 static int logInit(int argc, char **argv); 144 143 145 void usage(){ /** @todo should be implemented */ }; 144 146 int run(); … … 1112 1114 1113 1115 /** 1114 * Entry point. 1116 * Create release logger. 1117 * 1118 * The NAT network name is sanitized so that it can be used in a path 1119 * component. By default the release log is written to the file 1120 * ~/.VirtualBox/${netname}.log but its destiation and content can be 1121 * overridden with VBOXNET_${netname}_RELEASE_LOG family of 1122 * environment variables (also ..._DEST and ..._FLAGS). 1115 1123 */ 1116 extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) 1117 { 1118 int rc; 1119 1120 LogFlowFuncEnter(); 1121 1122 NOREF(envp); 1123 1124 #ifdef RT_OS_WINDOWS 1125 WSADATA wsaData; 1126 int err; 1127 1128 err = WSAStartup(MAKEWORD(2,2), &wsaData); 1129 if (err) 1130 { 1131 fprintf(stderr, "wsastartup: failed (%d)\n", err); 1132 return 1; 1133 } 1134 #endif 1135 1136 SOCKET icmpsock4 = INVALID_SOCKET; 1137 SOCKET icmpsock6 = INVALID_SOCKET; 1138 #ifndef RT_OS_DARWIN 1139 const int icmpstype = SOCK_RAW; 1140 #else 1141 /* on OS X it's not privileged */ 1142 const int icmpstype = SOCK_DGRAM; 1143 #endif 1144 1145 icmpsock4 = socket(AF_INET, icmpstype, IPPROTO_ICMP); 1146 if (icmpsock4 == INVALID_SOCKET) 1147 { 1148 perror("IPPROTO_ICMP"); 1149 #ifdef VBOX_RAWSOCK_DEBUG_HELPER 1150 icmpsock4 = getrawsock(AF_INET); 1151 #endif 1152 } 1153 1154 if (icmpsock4 != INVALID_SOCKET) 1155 { 1156 #ifdef ICMP_FILTER // Linux specific 1157 struct icmp_filter flt = { 1158 ~(uint32_t)( 1159 (1U << ICMP_ECHOREPLY) 1160 | (1U << ICMP_DEST_UNREACH) 1161 | (1U << ICMP_TIME_EXCEEDED) 1162 ) 1163 }; 1164 1165 int status = setsockopt(icmpsock4, SOL_RAW, ICMP_FILTER, 1166 &flt, sizeof(flt)); 1167 if (status < 0) 1168 { 1169 perror("ICMP_FILTER"); 1170 } 1171 #endif 1172 } 1173 1174 icmpsock6 = socket(AF_INET6, icmpstype, IPPROTO_ICMPV6); 1175 if (icmpsock6 == INVALID_SOCKET) 1176 { 1177 perror("IPPROTO_ICMPV6"); 1178 #ifdef VBOX_RAWSOCK_DEBUG_HELPER 1179 icmpsock6 = getrawsock(AF_INET6); 1180 #endif 1181 } 1182 1183 if (icmpsock6 != INVALID_SOCKET) 1184 { 1185 #ifdef ICMP6_FILTER // Windows doesn't support RFC 3542 API 1186 /* 1187 * XXX: We do this here for now, not in pxping.c, to avoid 1188 * name clashes between lwIP and system headers. 1189 */ 1190 struct icmp6_filter flt; 1191 ICMP6_FILTER_SETBLOCKALL(&flt); 1192 1193 ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &flt); 1194 1195 ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &flt); 1196 ICMP6_FILTER_SETPASS(ICMP6_PACKET_TOO_BIG, &flt); 1197 ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &flt); 1198 ICMP6_FILTER_SETPASS(ICMP6_PARAM_PROB, &flt); 1199 1200 int status = setsockopt(icmpsock6, IPPROTO_ICMPV6, ICMP6_FILTER, 1201 &flt, sizeof(flt)); 1202 if (status < 0) 1203 { 1204 perror("ICMP6_FILTER"); 1205 } 1206 #endif 1207 } 1208 1209 HRESULT hrc = com::Initialize(); 1210 if (FAILED(hrc)) 1211 { 1212 #ifdef VBOX_WITH_XPCOM 1213 if (hrc == NS_ERROR_FILE_ACCESS_DENIED) 1214 { 1215 char szHome[RTPATH_MAX] = ""; 1216 int vrc = com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome), false); 1217 if (RT_SUCCESS(vrc)) 1218 { 1219 closesocket(icmpsock4); 1220 closesocket(icmpsock6); 1221 return RTMsgErrorExit(RTEXITCODE_FAILURE, 1222 "Failed to initialize COM: %s: %Rhrf", 1223 szHome, hrc); 1224 } 1225 } 1226 #endif // VBOX_WITH_XPCOM 1227 closesocket(icmpsock4); 1228 closesocket(icmpsock6); 1229 return RTMsgErrorExit(RTEXITCODE_FAILURE, 1230 "Failed to initialize COM: %Rhrf", hrc); 1231 } 1232 1233 rc = vboxNetNATLogInit(argc, argv); 1234 // shall we bail if we failed to init logging? 1235 1236 g_pLwipNat = new VBoxNetLwipNAT(icmpsock4, icmpsock6); 1237 1238 Log2(("NAT: initialization\n")); 1239 rc = g_pLwipNat->parseArgs(argc - 1, argv + 1); 1240 rc = (rc == 0) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; /* XXX: FIXME */ 1241 1242 if (RT_SUCCESS(rc)) 1243 rc = g_pLwipNat->init(); 1244 1245 if (RT_SUCCESS(rc)) 1246 g_pLwipNat->run(); 1247 1248 delete g_pLwipNat; 1249 return 0; 1250 } 1251 1252 1253 static int vboxNetNATLogInit(int argc, char **argv) 1124 /* static */ 1125 int VBoxNetLwipNAT::logInit(int argc, char **argv) 1254 1126 { 1255 1127 size_t cch; 1256 1128 int rc; 1257 1129 1130 /* 1131 * NB: Contrary to what the "com" namespace might suggest, both 1132 * this call, and the call below to create the release logger are 1133 * NOT actually COM related in any way and can be used before COM 1134 * is initialized. 1135 */ 1258 1136 char szHome[RTPATH_MAX]; 1259 1137 rc = com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome), false); … … 1362 1240 1363 1241 1242 /** 1243 * Entry point. 1244 */ 1245 extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) 1246 { 1247 HRESULT hrc; 1248 int rc; 1249 1250 LogFlowFuncEnter(); 1251 1252 NOREF(envp); 1253 1254 #ifdef RT_OS_WINDOWS 1255 WSADATA wsaData; 1256 int err; 1257 1258 err = WSAStartup(MAKEWORD(2,2), &wsaData); 1259 if (err) 1260 { 1261 fprintf(stderr, "wsastartup: failed (%d)\n", err); 1262 return 1; 1263 } 1264 #endif 1265 1266 vboxNetNATLogInit(argc, argv); 1267 1268 hrc = com::Initialize(); 1269 if (FAILED(hrc)) 1270 { 1271 #ifdef VBOX_WITH_XPCOM 1272 if (hrc == NS_ERROR_FILE_ACCESS_DENIED) 1273 { 1274 char szHome[RTPATH_MAX] = ""; 1275 int vrc = com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome), false); 1276 if (RT_SUCCESS(vrc)) 1277 { 1278 return RTMsgErrorExit(RTEXITCODE_FAILURE, 1279 "Failed to initialize COM: %s: %Rhrf", 1280 szHome, hrc); 1281 } 1282 } 1283 #endif // VBOX_WITH_XPCOM 1284 return RTMsgErrorExit(RTEXITCODE_FAILURE, 1285 "Failed to initialize COM: %Rhrf", hrc); 1286 } 1287 1288 1289 SOCKET icmpsock4 = INVALID_SOCKET; 1290 SOCKET icmpsock6 = INVALID_SOCKET; 1291 #ifndef RT_OS_DARWIN 1292 const int icmpstype = SOCK_RAW; 1293 #else 1294 /* on OS X it's not privileged */ 1295 const int icmpstype = SOCK_DGRAM; 1296 #endif 1297 1298 icmpsock4 = socket(AF_INET, icmpstype, IPPROTO_ICMP); 1299 if (icmpsock4 == INVALID_SOCKET) 1300 { 1301 perror("IPPROTO_ICMP"); 1302 #ifdef VBOX_RAWSOCK_DEBUG_HELPER 1303 icmpsock4 = getrawsock(AF_INET); 1304 #endif 1305 } 1306 1307 if (icmpsock4 != INVALID_SOCKET) 1308 { 1309 #ifdef ICMP_FILTER // Linux specific 1310 struct icmp_filter flt = { 1311 ~(uint32_t)( 1312 (1U << ICMP_ECHOREPLY) 1313 | (1U << ICMP_DEST_UNREACH) 1314 | (1U << ICMP_TIME_EXCEEDED) 1315 ) 1316 }; 1317 1318 int status = setsockopt(icmpsock4, SOL_RAW, ICMP_FILTER, 1319 &flt, sizeof(flt)); 1320 if (status < 0) 1321 { 1322 perror("ICMP_FILTER"); 1323 } 1324 #endif 1325 } 1326 1327 icmpsock6 = socket(AF_INET6, icmpstype, IPPROTO_ICMPV6); 1328 if (icmpsock6 == INVALID_SOCKET) 1329 { 1330 perror("IPPROTO_ICMPV6"); 1331 #ifdef VBOX_RAWSOCK_DEBUG_HELPER 1332 icmpsock6 = getrawsock(AF_INET6); 1333 #endif 1334 } 1335 1336 if (icmpsock6 != INVALID_SOCKET) 1337 { 1338 #ifdef ICMP6_FILTER // Windows doesn't support RFC 3542 API 1339 /* 1340 * XXX: We do this here for now, not in pxping.c, to avoid 1341 * name clashes between lwIP and system headers. 1342 */ 1343 struct icmp6_filter flt; 1344 ICMP6_FILTER_SETBLOCKALL(&flt); 1345 1346 ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &flt); 1347 1348 ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &flt); 1349 ICMP6_FILTER_SETPASS(ICMP6_PACKET_TOO_BIG, &flt); 1350 ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &flt); 1351 ICMP6_FILTER_SETPASS(ICMP6_PARAM_PROB, &flt); 1352 1353 int status = setsockopt(icmpsock6, IPPROTO_ICMPV6, ICMP6_FILTER, 1354 &flt, sizeof(flt)); 1355 if (status < 0) 1356 { 1357 perror("ICMP6_FILTER"); 1358 } 1359 #endif 1360 } 1361 1362 1363 g_pLwipNat = new VBoxNetLwipNAT(icmpsock4, icmpsock6); 1364 1365 Log2(("NAT: initialization\n")); 1366 rc = g_pLwipNat->parseArgs(argc - 1, argv + 1); 1367 rc = (rc == 0) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; /* XXX: FIXME */ 1368 1369 if (RT_SUCCESS(rc)) 1370 rc = g_pLwipNat->init(); 1371 1372 if (RT_SUCCESS(rc)) 1373 g_pLwipNat->run(); 1374 1375 delete g_pLwipNat; 1376 return 0; 1377 } 1378 1379 1364 1380 static int fetchNatPortForwardRules(const ComNatPtr& nat, bool fIsIPv6, VECNATSERVICEPF& vec) 1365 1381 {
Note:
See TracChangeset
for help on using the changeset viewer.