Changeset 12604 in vbox for trunk/src/VBox/HostDrivers/VBoxNetFlt
- Timestamp:
- Sep 19, 2008 3:06:08 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 36871
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
r12597 r12604 177 177 static struct cb_ops g_VBoxNetFltSolarisCbOps = 178 178 { 179 nulldev, /* cb open */180 nulldev, /* cb close */181 nodev, /* b strategy */182 nodev, /* b dump */183 nodev, /* b print */184 nodev, /* cb read */185 nodev, /* cb write */186 nodev, /* cb ioctl */187 nodev, /* c devmap */188 nodev, /* c mmap */189 nodev, /* c segmap */190 nochpoll, /* c poll */191 ddi_prop_op, /* property ops */179 nulldev, /* cb open */ 180 nulldev, /* cb close */ 181 nodev, /* b strategy */ 182 nodev, /* b dump */ 183 nodev, /* b print */ 184 nodev, /* cb read */ 185 nodev, /* cb write */ 186 nodev, /* cb ioctl */ 187 nodev, /* c devmap */ 188 nodev, /* c mmap */ 189 nodev, /* c segmap */ 190 nochpoll, /* c poll */ 191 ddi_prop_op, /* property ops */ 192 192 &g_VBoxNetFltSolarisStreamTab, 193 D_NEW | D_MP | D_MTPERMOD, /* compat. flag */194 CB_REV /* revision */193 D_NEW | D_MP | D_MTPERMOD, /* compat. flag */ 194 CB_REV /* revision */ 195 195 }; 196 196 … … 200 200 static struct dev_ops g_VBoxNetFltSolarisDevOps = 201 201 { 202 DEVO_REV, /* driver build revision */203 0, /* ref count */202 DEVO_REV, /* driver build revision */ 203 0, /* ref count */ 204 204 VBoxNetFltSolarisGetInfo, 205 nulldev, /* identify */206 nulldev, /* probe */205 nulldev, /* identify */ 206 nulldev, /* probe */ 207 207 VBoxNetFltSolarisAttach, 208 208 VBoxNetFltSolarisDetach, 209 nodev, /* reset */209 nodev, /* reset */ 210 210 &g_VBoxNetFltSolarisCbOps, 211 211 (struct bus_ops *)0, 212 nodev /* power */212 nodev /* power */ 213 213 }; 214 214 … … 218 218 static struct modldrv g_VBoxNetFltSolarisDriver = 219 219 { 220 &mod_driverops, /* extern from kernel */220 &mod_driverops, /* extern from kernel */ 221 221 DEVICE_DESC_DRV, 222 222 &g_VBoxNetFltSolarisDevOps … … 238 238 static struct modlstrmod g_VBoxNetFltSolarisModule = 239 239 { 240 &mod_strmodops, /* extern from kernel */240 &mod_strmodops, /* extern from kernel */ 241 241 DEVICE_DESC_MOD, 242 242 &g_VBoxNetFltSolarisModOps … … 248 248 static struct modlinkage g_VBoxNetFltSolarisModLinkage = 249 249 { 250 MODREV_1, /* loadable module system revision */251 &g_VBoxNetFltSolarisDriver, /* streams driver framework */252 &g_VBoxNetFltSolarisModule, /* streams module framework */253 NULL /* terminate array of linkage structures */250 MODREV_1, /* loadable module system revision */ 251 &g_VBoxNetFltSolarisDriver, /* streams driver framework */ 252 &g_VBoxNetFltSolarisModule, /* streams module framework */ 253 NULL /* terminate array of linkage structures */ 254 254 }; 255 255 … … 279 279 280 280 /** 281 * vboxnetflt_stream_t: per-stream data 281 * vboxnetflt_stream_t: per-stream data (multiple streams per interface) 282 282 */ 283 283 typedef struct vboxnetflt_stream_t … … 286 286 queue_t *pReadQueue; /* read side queue */ 287 287 struct vboxnetflt_stream_t *pNext; /* next stream in list */ 288 PVBOXNETFLTINS pThis; /* the backend instance */ 289 VBOXNETFLTSTREAMTYPE Type; /* the type of the stream Ip/Arp */ 290 } vboxnetflt_stream_t; 291 292 /** 293 * vboxnetflt_promisc_stream_t: per-interface dedicated stream data 294 */ 295 typedef struct vboxnetflt_promisc_stream_t 296 { 297 vboxnetflt_stream_t Stream; /* The generic stream */ 288 298 bool fPromisc; /* cached promiscous value */ 289 299 bool fRawMode; /* whether raw mode request was successful */ 290 300 uint32_t ModeReqId; /* track MIOCTLs for swallowing our fake request acknowledgements */ 291 PVBOXNETFLTINS pThis; /* the backend instance */ 292 VBOXNETFLTSTREAMTYPE Type; /* the type of the stream Ip/Arp */ 293 } vboxnetflt_stream_t; 301 uint32_t aLoopback[64]; /* loopback CRC buffer */ 302 } vboxnetflt_promisc_stream_t; 294 303 295 304 /** … … 298 307 typedef struct vboxnetflt_state_t 299 308 { 300 /** Global device info handle. */301 dev_info_t *pDip;302 309 /** The list of all opened streams. */ 303 310 vboxnetflt_stream_t *pOpenedStreams; … … 315 322 * Internal Functions * 316 323 *******************************************************************************/ 317 static int vboxNetFltSolarisSetRawMode( queue_t *pQueue);318 static int vboxNetFltSolarisSetFastMode(queue_t *pQueue); 324 static int vboxNetFltSolarisSetRawMode(vboxnetflt_promisc_stream_t *pPromiscStream); 325 /* static int vboxNetFltSolarisSetFastMode(queue_t *pQueue); */ 319 326 320 327 static int vboxNetFltSolarisPhysAddrReq(queue_t *pQueue); 321 328 static void vboxNetFltSolarisCachePhysAddr(PVBOXNETFLTINS pThis, mblk_t *pPhysAddrAckMsg); 322 static mblk_t *vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP);329 static int vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP); 323 330 324 331 static int vboxNetFltSolarisUnitDataToRaw(PVBOXNETFLTINS pThis, mblk_t *pMsg, mblk_t **ppRawMsg); … … 341 348 /** Global state. */ 342 349 static vboxnetflt_state_t g_VBoxNetFltSolarisState; 350 /** Mutex protecting dynamic binding of the filter. */ 351 RTSEMFASTMUTEX g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX; 352 /** Global device info handle. */ 353 static dev_info_t *g_pVBoxNetFltSolarisDip = NULL; 354 355 343 356 /** GCC C++ hack. */ 344 357 unsigned __gxx_personality_v0 = 0xdecea5ed; 345 /** Global Mutex protecting global state. */346 RTSEMFASTMUTEX g_VBoxNetFltSolarisMtx = NIL_RTSEMFASTMUTEX;347 358 348 359 … … 471 482 if (rc == DDI_SUCCESS) 472 483 { 473 g_ VBoxNetFltSolarisState.pDip = pDip;484 g_pVBoxNetFltSolarisDip = pDip; 474 485 ddi_report_dev(pDip); 475 486 return DDI_SUCCESS; … … 540 551 case DDI_INFO_DEVT2DEVINFO: 541 552 { 542 *ppResult = g_ VBoxNetFltSolarisState.pDip;553 *ppResult = g_pVBoxNetFltSolarisDip; 543 554 return DDI_SUCCESS; 544 555 } … … 621 632 DevMinor = getminor(*pDev); 622 633 623 /* 624 * Allocate & initialize per-stream data. Hook it into the (read and write) queue's module specific data. 625 */ 626 pStream = RTMemAlloc(sizeof(*pStream)); 627 if (RT_UNLIKELY(!pStream)) 628 { 629 LogRel((DEVICE_NAME ":VBoxNetFltSolarisModOpen failed to allocate stream data.\n")); 630 return ENOMEM; 634 if (pState->CurType == kPromiscStream) 635 { 636 vboxnetflt_promisc_stream_t *pPromiscStream = RTMemAlloc(sizeof(vboxnetflt_promisc_stream_t)); 637 if (RT_UNLIKELY(!pPromiscStream)) 638 { 639 LogRel((DEVICE_NAME ":VBoxNetFltSolarisModOpen failed to allocate promiscuous stream data.\n")); 640 return ENOMEM; 641 } 642 643 pPromiscStream->fPromisc = false; 644 pPromiscStream->fRawMode = false; 645 pPromiscStream->ModeReqId = 0; 646 bzero(pPromiscStream->aLoopback, sizeof(pPromiscStream->aLoopback)); 647 pStream = (vboxnetflt_stream_t *)pPromiscStream; 648 } 649 else 650 { 651 /* 652 * Allocate & initialize per-stream data. Hook it into the (read and write) queue's module specific data. 653 */ 654 pStream = RTMemAlloc(sizeof(vboxnetflt_stream_t)); 655 if (RT_UNLIKELY(!pStream)) 656 { 657 LogRel((DEVICE_NAME ":VBoxNetFltSolarisModOpen failed to allocate stream data.\n")); 658 return ENOMEM; 659 } 631 660 } 632 661 pStream->DevMinor = DevMinor; 633 662 pStream->pReadQueue = pQueue; 634 pStream->fPromisc = false;635 pStream->fRawMode = false;636 663 637 664 /* … … 641 668 pStream->pThis = pState->pCurInstance; 642 669 pStream->Type = pState->CurType; 643 if (pState->CurType == kIpStream)644 pState->pCurInstance->u.s.pvIpStream = pStream;645 else if (pState->CurType == kArpStream)646 pState->pCurInstance->u.s.pvArpStream = pStream;647 else if (pState->CurType == kPromiscStream)648 pState->pCurInstance->u.s.pvPromiscStream = pStream;649 650 pStream->ModeReqId = 0; 670 switch (pStream->Type) 671 { 672 case kIpStream: pState->pCurInstance->u.s.pvIpStream = pStream; break; 673 case kArpStream: pState->pCurInstance->u.s.pvArpStream = pStream; break; 674 case kPromiscStream: pState->pCurInstance->u.s.pvPromiscStream = pStream; break; 675 default: AssertRelease(pStream->Type); break; 676 } 677 651 678 pQueue->q_ptr = pStream; 652 679 WR(pQueue)->q_ptr = pStream; … … 662 689 if (pStream->Type == kPromiscStream) 663 690 { 691 vboxnetflt_promisc_stream_t *pPromiscStream = (vboxnetflt_promisc_stream_t *)pStream; 692 664 693 /* 665 694 * Bind to SAP 0 (DL_ETHER). … … 669 698 * TPR anymore as far as I know. 670 699 */ 671 vboxNetFltSolarisBindReq(pStream->pReadQueue, 0 /* SAP */); 700 int rc = vboxNetFltSolarisBindReq(pStream->pReadQueue, 0 /* SAP */); 701 if (RT_UNLIKELY(RT_FAILURE(rc))) 702 { 703 LogRel((DEVICE_NAME ":vboxNetFltSolarisBindReq failed rc=%Vrc.\n", rc)); 704 return EPROTO; 705 } 672 706 673 707 /* … … 675 709 */ 676 710 /** @todo take a look at DLPI notifications additionally for these things. */ 677 vboxNetFltSolarisPhysAddrReq(pStream->pReadQueue); 711 rc = vboxNetFltSolarisPhysAddrReq(pStream->pReadQueue); 712 if (RT_UNLIKELY(RT_FAILURE(rc))) 713 { 714 LogRel((DEVICE_NAME ":vboxNetFltSolarisPhysAddrReq failed rc=%Vrc.\n", rc)); 715 return EPROTO; 716 } 678 717 679 718 /* 680 719 * Enable raw mode. 681 720 */ 682 vboxNetFltSolarisSetRawMode(pStream->pReadQueue); 683 } 684 685 pStream->pThis->fDisconnectedFromHost = false; 721 rc = vboxNetFltSolarisSetRawMode(pPromiscStream); 722 if (RT_UNLIKELY(RT_FAILURE(rc))) 723 { 724 LogRel((DEVICE_NAME ":vboxNetFltSolarisSetRawMode failed rc=%Vrc.\n", rc)); 725 return EPROTO; 726 } 727 } 686 728 687 729 NOREF(fOpenMode); … … 722 764 } 723 765 724 pStream->pThis->fDisconnectedFromHost = true;725 766 qprocsoff(pQueue); 726 767 … … 736 777 * Delete the stream. 737 778 */ 738 if (pStream->Type == kIpStream) 739 pStream->pThis->u.s.pvIpStream = NULL; 740 else if (pStream->Type == kArpStream) 741 pStream->pThis->u.s.pvArpStream = NULL; 742 else 743 pStream->pThis->u.s.pvPromiscStream = NULL; 779 switch (pStream->Type) 780 { 781 case kIpStream: ASMAtomicUoWritePtr(pStream->pThis->u.s.pvIpStream, NULL); break; 782 case kArpStream: ASMAtomicUoWritePtr(pStream->pThis->u.s.pvArpStream, NULL); break; 783 case kPromiscStream: ASMAtomicUoWritePtr(pStream->pThis->u.s.pvPromiscStream, NULL); break; 784 default: AssertRelease(pStream->Type); break; 785 } 744 786 745 787 RTMemFree(pStream); … … 764 806 static int VBoxNetFltSolarisModReadPut(queue_t *pQueue, mblk_t *pMsg) 765 807 { 808 /* 809 * Yes, I'm paranoid. 810 */ 811 if (!pMsg || !pQueue) 812 { 813 LogRel((DEVICE_NAME ":VBoxNetFltSolarisModReadPut huh?? Invalid parameters.\n")); 814 return 0; 815 } 816 766 817 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut pQueue=%p pMsg=%p\n", pQueue, pMsg)); 767 818 … … 776 827 */ 777 828 if ( pStream 778 && pStream->Type == kPromiscStream 779 && pMsg) 829 && pStream->Type == kPromiscStream) 780 830 { 781 831 pThis = vboxNetFltSolarisFindInstance(pStream); … … 792 842 RTSpinlockRelease(pThis->hSpinlock, &Tmp); 793 843 844 vboxnetflt_promisc_stream_t *pPromiscStream = (vboxnetflt_promisc_stream_t *)pStream; 845 794 846 switch (DB_TYPE(pMsg)) 795 847 { … … 799 851 800 852 if ( fActive 801 && p Stream->fRawMode)853 && pPromiscStream->fRawMode) 802 854 { 803 855 vboxNetFltSolarisRecv(pThis, pStream, pQueue, pMsg); … … 865 917 { 866 918 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO: DL_OK_ACK: fPromisc is ON.\n")); 867 p Stream->fPromisc = true;919 pPromiscStream->fPromisc = true; 868 920 } 869 921 else if (pOkAck->dl_correct_primitive == DL_PROMISCOFF_REQ) 870 922 { 871 923 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO: DL_OK_ACK: fPromisc is OFF.\n")); 872 p Stream->fPromisc = false;924 pPromiscStream->fPromisc = false; 873 925 } 874 926 … … 887 939 */ 888 940 struct iocblk *pIOC = (struct iocblk *)pMsg->b_rptr; 889 if (pIOC->ioc_id == p Stream->ModeReqId)941 if (pIOC->ioc_id == pPromiscStream->ModeReqId) 890 942 { 891 p Stream->fRawMode = true;943 pPromiscStream->fRawMode = true; 892 944 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: Mode acknowledgement. RawMode is %s\n", 893 p Stream->fRawMode ? "ON" : "OFF"));945 pPromiscStream->fRawMode ? "ON" : "OFF")); 894 946 895 947 freemsg(pMsg); … … 1158 1210 1159 1211 /* 1160 * Impl ment just the flow controlled service draining of the queue.1212 * Implement just the flow controlled service draining of the queue. 1161 1213 * Nothing else to do here, we handle all the important stuff in the Put procedure. 1162 1214 */ … … 1183 1235 * @param pQueue Pointer to the queue. 1184 1236 */ 1185 static int vboxNetFltSolarisSetRawMode( queue_t *pQueue)1186 { 1187 LogFlow((DEVICE_NAME ":vboxNetFltSolarisSetRawMode p Queue=%p\n", pQueue));1237 static int vboxNetFltSolarisSetRawMode(vboxnetflt_promisc_stream_t *pPromiscStream) 1238 { 1239 LogFlow((DEVICE_NAME ":vboxNetFltSolarisSetRawMode pPromiscStream=%p\n", pPromiscStream)); 1188 1240 1189 1241 mblk_t *pRawMsg = NULL; … … 1192 1244 return VERR_NO_MEMORY; 1193 1245 1194 vboxnetflt_stream_t *pStream = pQueue->q_ptr; 1246 queue_t *pQueue = pPromiscStream->Stream.pReadQueue; 1247 if (!pQueue) 1248 return VERR_INVALID_POINTER; 1249 1195 1250 struct iocblk *pIOC = (struct iocblk *)pRawMsg->b_rptr; 1196 p Stream->ModeReqId = pIOC->ioc_id;1251 pPromiscStream->ModeReqId = pIOC->ioc_id; 1197 1252 pIOC->ioc_count = 0; 1198 1253 … … 1355 1410 * Prepare DLPI bind request to a SAP. 1356 1411 * 1357 * @returns Pointer to the request message. 1358 */ 1359 static mblk_t *vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP) 1412 * @returns VBox status code. 1413 * @param pQueue Pointer to the queue. 1414 * @param SAP The SAP to bind the stream to. 1415 */ 1416 static int vboxNetFltSolarisBindReq(queue_t *pQueue, int SAP) 1360 1417 { 1361 1418 LogFlow((DEVICE_NAME ":vboxNetFltSolarisBindReq SAP=%u\n", SAP)); … … 1363 1420 mblk_t *pBindMsg = mexchange(NULL, NULL, DL_BIND_REQ_SIZE, M_PROTO, DL_BIND_REQ); 1364 1421 if (RT_UNLIKELY(!pBindMsg)) 1365 return NULL;1422 return VERR_NO_MEMORY; 1366 1423 1367 1424 dl_bind_req_t *pBindReq = (dl_bind_req_t *)pBindMsg->b_rptr; … … 1912 1969 rc = vboxNetFltSolarisOpenStream(pThis); 1913 1970 if (RT_SUCCESS(rc)) 1971 { 1914 1972 rc = vboxNetFltSolarisModSetup(pThis, true); 1973 if (RT_SUCCESS(rc)) 1974 ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, false); 1975 } 1915 1976 else 1916 1977 LogRel((DEVICE_NAME ":vboxNetFltSolarisAttachToInterface vboxNetFltSolarisOpenStream failed rc=%Vrc\n", rc)); … … 1934 1995 AssertRC(rc); 1935 1996 1997 ASMAtomicWriteBool(&pThis->fDisconnectedFromHost, true); 1936 1998 vboxNetFltSolarisCloseStream(pThis); 1937 1999 rc = vboxNetFltSolarisModSetup(pThis, false); … … 2252 2314 fSrc = INTNETTRUNKDIR_HOST; 2253 2315 2316 #if 0 2254 2317 if (fSrc & INTNETTRUNKDIR_HOST) 2255 2318 { … … 2258 2321 pMsg = pCorrectedMsg; 2259 2322 } 2323 #endif 2260 2324 2261 2325 vboxNetFltSolarisAnalyzeMBlk(pMsg); … … 2366 2430 * Check if the IP checksum is valid. 2367 2431 */ 2368 PRTNETIPV4 pIpHdr = (PRTNETIPV4)(pEthHdr + 1); 2432 uint8_t *pbProtocol = (uint8_t *)(pEthHdr + 1); 2433 PRTNETIPV4 pIpHdr = (PRTNETIPV4)pbProtocol; 2434 size_t cbPayload = cbIpPacket - (pIpHdr->ip_hl << 2); 2435 2369 2436 bool fChecksumAdjusted = false; 2370 2437 … … 2374 2441 if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP) 2375 2442 { 2376 size_t cbTcpPacket = cbIpPacket -(pIpHdr->ip_hl << 2);2377 2378 PRTNETTCP pTcpHdr = (PRTNETTCP)((uint32_t *)(pIpHdr + pIpHdr->ip_hl));2379 if ( !RTNetIPv4IsTCPValid(pIpHdr, pTcpHdr, cbTcpPacket, NULL, cbTcpPacket))2443 pbProtocol += (pIpHdr->ip_hl << 2); 2444 PRTNETTCP pTcpHdr = (PRTNETTCP)pbProtocol; 2445 uint16_t TcpChecksum = RTNetIPv4TCPChecksum(pIpHdr, pTcpHdr, NULL); 2446 if (pTcpHdr->th_sum != TcpChecksum) 2380 2447 { 2381 pTcpHdr->th_sum = RTNetIPv4TCPChecksum(pIpHdr, pTcpHdr, NULL);2448 pTcpHdr->th_sum = TcpChecksum; 2382 2449 fChecksumAdjusted = true; 2383 LogFlow((DEVICE_NAME ":fixed TCP check um.\n"));2450 LogFlow((DEVICE_NAME ":fixed TCP checksum.\n")); 2384 2451 } 2385 2452 2386 if (!RTNetIPv4IsHdrValid(pIpHdr, cbIpPacket, cbIpPacket)) 2453 uint16_t IpChecksum = RTNetIPv4HdrChecksum(pIpHdr); 2454 if (pIpHdr->ip_sum != IpChecksum) 2387 2455 { 2388 pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr);2456 pIpHdr->ip_sum = IpChecksum; 2389 2457 fChecksumAdjusted = true; 2390 LogFlow((DEVICE_NAME ":fixed IP check um.\n"));2458 LogFlow((DEVICE_NAME ":fixed IP checksum.\n")); 2391 2459 } 2392 2460 } 2393 2461 else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP) 2394 2462 { 2395 size_t cbUdpPacket = cbIpPacket -(pIpHdr->ip_hl << 2);2396 PRTNETUDP pUdpHdr = (PRTNETUDP) ((uint32_t *)pIpHdr + pIpHdr->ip_hl);2463 pbProtocol += (pIpHdr->ip_hl << 2); 2464 PRTNETUDP pUdpHdr = (PRTNETUDP)pbProtocol; 2397 2465 uint16_t UdpChecksum = RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1); 2398 2466 … … 2401 2469 pUdpHdr->uh_sum = UdpChecksum; 2402 2470 fChecksumAdjusted = true; 2403 LogFlow((DEVICE_NAME ": Invalid UDP checksum!!"));2471 LogFlow((DEVICE_NAME ":Fixed UDP checksum.")); 2404 2472 } 2405 2473 2406 if (!RTNetIPv4IsHdrValid(pIpHdr, cbIpPacket, cbIpPacket)) 2474 uint16_t IpChecksum = RTNetIPv4HdrChecksum(pIpHdr); 2475 if (pIpHdr->ip_sum != IpChecksum) 2407 2476 { 2408 pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr);2477 pIpHdr->ip_sum = IpChecksum; 2409 2478 fChecksumAdjusted = true; 2410 LogFlow((DEVICE_NAME ":fixed IP check um.\n"));2479 LogFlow((DEVICE_NAME ":fixed IP checksum.\n")); 2411 2480 } 2412 2481 }
Note:
See TracChangeset
for help on using the changeset viewer.