儲存庫 vbox 的更動 12089
- 時間撮記:
- 2008-9-4 下午12:45:59 (16 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
r12035 r12089 328 328 static unsigned vboxNetFltSolarisMBlkCalcSGSegs(PVBOXNETFLTINS pThis, mblk_t *pMsg); 329 329 static int vboxNetFltSolarisMBlkToSG(PVBOXNETFLTINS pThis, mblk_t *pMsg, PINTNETSG pSG, unsigned cSegs, uint32_t fSrc); 330 static int vboxNetFltSolaris IOWorker(PVBOXNETFLTINS pThis, queue_t *pQueue, vboxnetflt_stream_t *pStream, mblk_t *pMsg, uint32_t fSrc);330 static int vboxNetFltSolarisRecv(PVBOXNETFLTINS pThis, vboxnetflt_stream_t *pStream, queue_t *pQueue, mblk_t *pMsg); 331 331 static PVBOXNETFLTINS vboxNetFltSolarisFindInstance(vboxnetflt_stream_t *pStream); 332 static void vboxNetFltSolarisFinalizeMBlk(mblk_t *pMsg);332 static mblk_t *vboxNetFltSolarisFixChecksums(mblk_t *pMsg); 333 333 static void vboxNetFltSolarisAnalyzeMBlk(mblk_t *pMsg); 334 334 … … 750 750 bool fSendUpstream = true; 751 751 vboxnetflt_stream_t *pStream = pQueue->q_ptr; 752 PVBOXNETFLTINS pThis = vboxNetFltSolarisFindInstance(pStream); 753 754 if (pStream->Type == kIpStream) 755 { 756 switch (DB_TYPE(pMsg)) 757 { 758 case M_DATA: 752 753 /* 754 * In the unlikely case where VirtualBox crashed and this filter 755 * is somehow still in the host stream we must try not to panic the host. 756 */ 757 if ( pStream 758 && pStream->Type == kIpStream 759 && pMsg) 760 { 761 PVBOXNETFLTINS pThis = vboxNetFltSolarisFindInstance(pStream); 762 if (RT_LIKELY(pThis)) 763 { 764 switch (DB_TYPE(pMsg)) 759 765 { 760 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut M_DATA\n")); 761 762 vboxNetFltSolarisIOWorker(pThis, pStream->pReadQueue, pStream, pMsg, INTNETTRUNKDIR_WIRE); 763 fSendUpstream = false; /* vboxNetFltSolarisIOWorker would send it if required, do nothing more here. */ 764 break; 766 case M_DATA: 767 { 768 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut M_DATA\n")); 769 770 vboxNetFltSolarisRecv(pThis, pStream, pQueue, pMsg); 771 fSendUpstream = false; /* vboxNetFltSolarisRecv would send it if required, do nothing more here. */ 772 break; 773 } 774 775 case M_PROTO: 776 case M_PCPROTO: 777 { 778 union DL_primitives *pPrim = (union DL_primitives *)pMsg->b_rptr; 779 t_uscalar_t Prim = pPrim->dl_primitive; 780 781 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO %d\n", Prim)); 782 switch (Prim) 783 { 784 case DL_UNITDATA_IND: 785 { 786 /* 787 * I do not think control would come here... We convert all outgoing fast mode requests 788 * to raw mode; so I don't think we should really receive any fast mode replies. 789 */ 790 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: DL_UNITDATA_IND\n")); 791 792 vboxNetFltSolarisRecv(pThis, pStream, pQueue, pMsg); 793 fSendUpstream = false; /* vboxNetFltSolarisRecv would send it if required, do nothing more here. */ 794 break; 795 } 796 797 case DL_PHYS_ADDR_ACK: 798 { 799 vboxNetFltSolarisCachePhysAddr(pThis, pMsg); 800 801 /* 802 * Swallow our fake physical address request acknowledgement. 803 */ 804 if (pStream->UnAckPrim == DL_PHYS_ADDR_REQ) 805 { 806 freemsg(pMsg); 807 fSendUpstream = false; 808 } 809 break; 810 } 811 812 case DL_OK_ACK: 813 { 814 dl_ok_ack_t *pOkAck = (dl_ok_ack_t *)pMsg->b_rptr; 815 if (pOkAck->dl_correct_primitive == DL_PROMISCON_REQ) 816 { 817 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO: DL_OK_ACK: fPromisc is ON.\n")); 818 pStream->fPromisc = true; 819 } 820 else if (pOkAck->dl_correct_primitive == DL_PROMISCOFF_REQ) 821 { 822 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO: DL_OK_ACK: fPromisc is OFF.\n")); 823 pStream->fPromisc = false; 824 } 825 826 /* 827 * Swallow our fake promiscous request acknowledgement. 828 */ 829 if (pStream->UnAckPrim == pOkAck->dl_correct_primitive) 830 { 831 freemsg(pMsg); 832 fSendUpstream = false; 833 } 834 break; 835 } 836 } 837 break; 838 } 839 840 case M_IOCACK: 841 { 842 /* 843 * Swallow our fake raw/fast path mode request acknowledgement. 844 */ 845 struct iocblk *pIOC = (struct iocblk *)pMsg->b_rptr; 846 if (pIOC->ioc_id == pStream->ModeReqId) 847 { 848 pStream->ModeReqId = VBOXNETFLT_MODE_REQ_MAGIC; 849 pStream->fRawMode = !pStream->fRawMode; 850 851 /* 852 * Somehow raw mode is turned off?? This should never really happen... 853 */ 854 if (pStream->fRawMode == false) 855 { 856 LogFlow((DEVICE_NAME ":re-requesting raw mode!\n")); 857 vboxNetFltSolarisSetRawMode(pQueue); 858 } 859 860 freemsg(pMsg); 861 fSendUpstream = false; 862 } 863 break; 864 } 865 866 case M_FLUSH: 867 { 868 /* 869 * We must support flushing queues. 870 */ 871 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_FLUSH\n")); 872 if (*pMsg->b_rptr & FLUSHR) 873 flushq(pQueue, FLUSHALL); 874 break; 875 } 765 876 } 766 767 case M_PROTO: 768 case M_PCPROTO: 769 { 770 union DL_primitives *pPrim = (union DL_primitives *)pMsg->b_rptr; 771 t_uscalar_t Prim = pPrim->dl_primitive; 772 773 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO %d\n", Prim)); 774 switch (Prim) 775 { 776 case DL_UNITDATA_IND: 777 { 778 /* 779 * I do not think control would come here... We convert all outgoing fast mode requests 780 * to raw mode; so I don't think we should really receive any fast mode replies. 781 */ 782 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: DL_UNITDATA_IND\n")); 783 784 vboxNetFltSolarisIOWorker(pThis, pStream->pReadQueue, pStream, pMsg, INTNETTRUNKDIR_WIRE); 785 fSendUpstream = false; /* vboxNetFltSolarisIOWorker would send it if required, do nothing more here. */ 786 break; 787 } 788 789 case DL_PHYS_ADDR_ACK: 790 { 791 vboxNetFltSolarisCachePhysAddr(pThis, pMsg); 792 793 /* 794 * Swallow our fake physical address request acknowledgement. 795 */ 796 if (pStream->UnAckPrim == DL_PHYS_ADDR_REQ) 797 { 798 freemsg(pMsg); 799 fSendUpstream = false; 800 } 801 break; 802 } 803 804 case DL_OK_ACK: 805 { 806 dl_ok_ack_t *pOkAck = (dl_ok_ack_t *)pMsg->b_rptr; 807 if (pOkAck->dl_correct_primitive == DL_PROMISCON_REQ) 808 { 809 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO: DL_OK_ACK: fPromisc is ON.\n")); 810 pStream->fPromisc = true; 811 } 812 else if (pOkAck->dl_correct_primitive == DL_PROMISCOFF_REQ) 813 { 814 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_PCPROTO: DL_OK_ACK: fPromisc is OFF.\n")); 815 pStream->fPromisc = false; 816 } 817 818 /* 819 * Swallow our fake promiscous request acknowledgement. 820 */ 821 if (pStream->UnAckPrim == pOkAck->dl_correct_primitive) 822 { 823 freemsg(pMsg); 824 fSendUpstream = false; 825 } 826 break; 827 } 828 } 829 break; 830 } 831 832 case M_IOCACK: 833 { 834 /* 835 * Swallow our fake raw/fast path mode request acknowledgement. 836 */ 837 struct iocblk *pIOC = (struct iocblk *)pMsg->b_rptr; 838 if (pIOC->ioc_id == pStream->ModeReqId) 839 { 840 pStream->ModeReqId = VBOXNETFLT_MODE_REQ_MAGIC; 841 pStream->fRawMode = !pStream->fRawMode; 842 843 /* 844 * Somehow raw mode is turned off?? 845 */ 846 if (pStream->fRawMode == false) 847 { 848 LogFlow((DEVICE_NAME ":re-requesting raw mode!!!!!!!!!!!!!!!!!!!!!!!!!!\n")); 849 vboxNetFltSolarisSetRawMode(pQueue); 850 } 851 852 freemsg(pMsg); 853 fSendUpstream = false; 854 } 855 break; 856 } 857 858 case M_FLUSH: 859 { 860 /* 861 * We must support flushing queues. 862 */ 863 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: M_FLUSH\n")); 864 if (*pMsg->b_rptr & FLUSHR) 865 flushq(pQueue, FLUSHALL); 866 break; 867 } 868 } 877 } 878 else 879 LogRel((DEVICE_NAME ":VBoxNetFltSolarisModReadPut: Could not find VirtualBox instance!!\n")); 869 880 } 870 881 … … 906 917 bool fSendDownstream = true; 907 918 vboxnetflt_stream_t *pStream = pQueue->q_ptr; 908 PVBOXNETFLTINS pThis = vboxNetFltSolarisFindInstance(pStream); 909 int rc; 910 if (pStream->Type == kIpStream) 911 { 912 switch (DB_TYPE(pMsg)) 913 { 914 case M_DATA: 919 920 /* 921 * In the unlikely case where VirtualBox crashed and this filter 922 * is somehow still in the host stream we must try not to panic the host. 923 */ 924 if ( pStream 925 && pStream->Type == kIpStream 926 && pMsg) 927 { 928 PVBOXNETFLTINS pThis = vboxNetFltSolarisFindInstance(pStream); 929 if (RT_LIKELY(pThis)) 930 { 931 switch (DB_TYPE(pMsg)) 915 932 { 916 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut M_DATA\n")); 917 break; 918 } 919 920 case M_PROTO: 921 case M_PCPROTO: 922 { 923 /* 924 * Queue up other primitives to the service routine. 925 */ 926 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut M_PROTO/M_PCPROTO\n")); 927 928 union DL_primitives *pPrim = (union DL_primitives *)pMsg->b_rptr; 929 t_uscalar_t Prim = pPrim->dl_primitive; 930 switch (Prim) 933 case M_DATA: 931 934 { 932 case DL_UNITDATA_REQ: 935 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut M_DATA\n")); 936 break; 937 } 938 939 case M_PROTO: 940 case M_PCPROTO: 941 { 942 /* 943 * Queue up other primitives to the service routine. 944 */ 945 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut M_PROTO/M_PCPROTO\n")); 946 947 union DL_primitives *pPrim = (union DL_primitives *)pMsg->b_rptr; 948 t_uscalar_t Prim = pPrim->dl_primitive; 949 switch (Prim) 933 950 { 934 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut DL_UNITDATA_REQ\n")); 935 mblk_t *pRawMsg; 936 rc = vboxNetFltSolarisUnitDataToRaw(pThis, pMsg, &pRawMsg); 937 if (VBOX_SUCCESS(rc)) 938 pMsg = pRawMsg; 939 else 951 case DL_UNITDATA_REQ: 952 { 953 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut DL_UNITDATA_REQ\n")); 954 mblk_t *pRawMsg; 955 int rc = vboxNetFltSolarisUnitDataToRaw(pThis, pMsg, &pRawMsg); 956 if (VBOX_SUCCESS(rc)) 957 pMsg = pRawMsg; 958 else 959 fSendDownstream = false; 960 break; 961 } 962 963 default: 964 { 965 /* 966 * Enqueue other DLPI primitives and service them later. 967 */ 940 968 fSendDownstream = false; 941 break; 969 putq(pQueue, pMsg); 970 break; 971 } 942 972 } 943 944 default: 973 break; 974 } 975 976 case M_IOCTL: 977 { 978 struct iocblk *pIOC = (struct iocblk *)pMsg->b_rptr; 979 if (pIOC->ioc_cmd == DL_IOC_HDR_INFO) 980 { 981 if (pThis->fActive) 982 { 983 /* 984 * Somebody is wanting fast path when we need raw mode. 985 * Since we are evil, let's acknowledge the request ourselves! 986 */ 987 miocnak(pQueue, pMsg, 0, EINVAL); 988 fSendDownstream = false; 989 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut: Fast path request when we need raw mode!\n")); 990 } 991 } 992 break; 993 } 994 995 case M_FLUSH: 996 { 997 /* 998 * Canonical flush courtesy man qreply(9F) while we have a service routine. 999 */ 1000 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut M_FLUSH\n")); 1001 if (*pMsg->b_rptr & FLUSHW) 945 1002 { 946 1003 /* 947 * Enqueue other DLPI primitives and service them later.1004 * Flush and mark as serviced. 948 1005 */ 949 fSendDownstream = false; 950 putq(pQueue, pMsg); 951 break; 1006 flushq(pQueue, FLUSHALL); 1007 *pMsg->b_rptr &= ~FLUSHW; 952 1008 } 953 } 954 break; 955 } 956 957 case M_IOCTL: 958 { 959 struct iocblk *pIOC = (struct iocblk *)pMsg->b_rptr; 960 if (pIOC->ioc_cmd == DL_IOC_HDR_INFO) 961 { 962 if (pThis->fActive) 1009 1010 if (*pMsg->b_rptr & FLUSHR) 963 1011 { 964 1012 /* 965 * Somebody is wanting fast path when we need raw mode. 966 * Since we are evil, let's acknowledge the request ourselves! 1013 * Send the request upstream. 967 1014 */ 968 miocnak(pQueue, pMsg, 0, EINVAL); 969 fSendDownstream = false; 970 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut: Fast path request when we need raw mode!\n")); 1015 flushq(RD(pQueue), FLUSHALL); 1016 qreply(pQueue, pMsg); 971 1017 } 1018 else 1019 freemsg(pMsg); 1020 1021 break; 972 1022 } 973 break;974 1023 } 975 976 case M_FLUSH: 977 { 978 /* 979 * Canonical flush courtesy man qreply(9F) while we have a service routine. 980 */ 981 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut M_FLUSH\n")); 982 if (*pMsg->b_rptr & FLUSHW) 983 { 984 /* 985 * Flush and mark as serviced. 986 */ 987 flushq(pQueue, FLUSHALL); 988 *pMsg->b_rptr &= ~FLUSHW; 989 } 990 991 if (*pMsg->b_rptr & FLUSHR) 992 { 993 /* 994 * Send the request upstream. 995 */ 996 flushq(RD(pQueue), FLUSHALL); 997 qreply(pQueue, pMsg); 998 } 999 else 1000 freemsg(pMsg); 1001 1002 break; 1003 } 1004 } 1024 } 1025 else 1026 LogRel((DEVICE_NAME ":VBoxNetFltSolarisModWritePut: Could not find VirtualBox instance!!\n")); 1005 1027 } 1006 1028 … … 1037 1059 1038 1060 /* 1039 * Drain the queue as we service the messages. 1061 * Implment just the flow controlled service draining of the queue. 1062 * Nothing else to do here, we handle all the important stuff in the Put procedure. 1040 1063 */ 1041 1064 mblk_t *pMsg; 1042 1065 while (pMsg = getq(pQueue)) 1043 1066 { 1044 switch (DB_TYPE(pMsg)) 1045 { 1046 case M_DATA: 1047 case M_PROTO: 1048 case M_PCPROTO: 1049 { 1050 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWriteService M_DATA/M_PROTO/M_PCPROTO forwarding downstream\n")); 1051 putnext(pQueue, pMsg); 1052 break; 1053 } 1054 1055 case M_IOCTL: 1056 case M_IOCDATA: 1057 { 1058 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWritePut M_IOCTL/M_IOCDATA\n")); 1059 putnext(pQueue, pMsg); 1060 break; 1061 } 1062 1063 default: 1064 { 1065 LogFlow((DEVICE_NAME ":VBoxNetFltSolarisModWriteService (Unknown)!\n")); 1066 if (canputnext(pQueue)) 1067 putnext(pQueue, pMsg); 1068 else 1069 putq(pQueue, pMsg); 1070 break; 1071 } 1067 if (canputnext(pQueue)) 1068 putnext(pQueue, pMsg); 1069 else 1070 { 1071 putbq(pQueue, pMsg); 1072 break; 1072 1073 } 1073 1074 } … … 1522 1523 int rc; 1523 1524 int rc2; 1524 int rc3;1525 1525 int ret; 1526 ldi_ident_t DevId = ldi_ident_from_anon(); 1526 ldi_ident_t IPDevId = ldi_ident_from_anon(); 1527 ldi_ident_t ARPDevId = ldi_ident_from_anon(); 1527 1528 ldi_handle_t IPDevHandle; 1528 1529 ldi_handle_t UDPDevHandle; … … 1530 1531 1531 1532 /* 1532 * @todo Do opening of each stream separately with error checking. 1533 */ 1534 /* 1535 * Open the IP stream as a layered device. 1536 */ 1537 rc = ldi_open_by_name(IP_DEV_NAME, FREAD | FWRITE, kcred, &IPDevHandle, DevId); 1538 rc2 = ldi_open_by_name("/dev/arp", FREAD | FWRITE, kcred, &ARPDevHandle, DevId); 1539 if ( !rc 1540 && !rc2) 1533 * Open the IP and ARP streams as layered devices. 1534 */ 1535 rc = ldi_open_by_name(IP_DEV_NAME, FREAD | FWRITE, kcred, &IPDevHandle, IPDevId); 1536 ldi_ident_release(IPDevId); 1537 if (rc) 1538 { 1539 LogRel((DEVICE_NAME ":failed to open the IP stream on '%s'.\n", pThis->szName)); 1540 return VERR_INTNET_FLT_IF_FAILED; 1541 } 1542 1543 rc = ldi_open_by_name("/dev/arp", FREAD | FWRITE, kcred, &ARPDevHandle, ARPDevId); 1544 ldi_ident_release(ARPDevId); 1545 if (rc) 1546 { 1547 LogRel((DEVICE_NAME ":failed to open the ARP stream on '%s'.\n", pThis->szName)); 1548 ldi_close(IPDevHandle, FREAD | FWRITE, kcred); 1549 return VERR_INTNET_FLT_IF_FAILED; 1550 } 1551 1552 /* 1553 * Obtain the interface flags from IP. 1554 */ 1555 rc = vboxNetFltSolarisGetIfFlags(IPDevHandle, &Interface); 1556 if (VBOX_SUCCESS(rc)) 1541 1557 { 1542 1558 /* 1543 * Obtain the interface flags from IP. 1559 * Open the UDP stream. We sort of cheat here and obtain the vnode so that we can perform 1560 * things that are not possible from the layered interface. 1544 1561 */ 1545 rc = vboxNetFltSolarisGetIfFlags(IPDevHandle, &Interface); 1562 vnode_t *pVNodeUDP = NULL; 1563 vnode_t *pVNodeUDPHeld = NULL; 1564 TIUSER *pUserUDP = NULL; 1565 rc = vboxNetFltSolarisOpenDev(UDP_DEV_NAME, &pVNodeUDP, &pVNodeUDPHeld, &pUserUDP); 1546 1566 if (VBOX_SUCCESS(rc)) 1547 1567 { 1548 1568 /* 1549 * Open the UDP stream. We sort of cheat here and obtain the vnode so that we can perform 1550 * things that are not possible from the layered interface. 1569 * Get the multiplexor IDs. 1551 1570 */ 1552 vnode_t *pVNodeUDP = NULL; 1553 vnode_t *pVNodeUDPHeld = NULL; 1554 TIUSER *pUserUDP = NULL; 1555 rc = vboxNetFltSolarisOpenDev(UDP_DEV_NAME, &pVNodeUDP, &pVNodeUDPHeld, &pUserUDP); 1556 if (VBOX_SUCCESS(rc)) 1571 rc = ldi_ioctl(IPDevHandle, SIOCGLIFMUXID, (intptr_t)&Interface, FKIOCTL, kcred, &ret); 1572 if (!rc) 1557 1573 { 1558 1574 /* 1559 * Get the multiplexor IDs. 1575 * Get the multiplex file descriptor to the lower streams. Generally this is lost 1576 * once a module is I_PLINK, we need to reobtain it for inserting/removing ourselves from the stack. 1560 1577 */ 1561 rc = ldi_ioctl(IPDevHandle, SIOCGLIFMUXID, (intptr_t)&Interface, FKIOCTL, kcred, &ret); 1562 if (!rc) 1578 int IpMuxFd; 1579 int ArpMuxFd; 1580 rc = vboxNetFltSolarisMuxIdToFd(pVNodeUDP, Interface.lifr_ip_muxid, &IpMuxFd); 1581 rc2 = vboxNetFltSolarisMuxIdToFd(pVNodeUDP, Interface.lifr_arp_muxid, &ArpMuxFd); 1582 if ( VBOX_SUCCESS(rc) 1583 && VBOX_SUCCESS(rc2)) 1563 1584 { 1564 1585 /* 1565 * Get the multiplex file descriptor to the lower streams. Generally this is lost1566 * o nce a module is I_PLINK, we need to reobtain it for inserting/removing ourselves from the stack.1586 * We need to I_PUNLINK on these multiplexor IDs before we can start 1587 * operating on the lower stream as insertions are direct operations on the lower stream. 1567 1588 */ 1568 int IpMuxFd; 1569 int ArpMuxFd; 1570 rc = vboxNetFltSolarisMuxIdToFd(pVNodeUDP, Interface.lifr_ip_muxid, &IpMuxFd); 1571 rc2 = vboxNetFltSolarisMuxIdToFd(pVNodeUDP, Interface.lifr_arp_muxid, &ArpMuxFd); 1572 if ( VBOX_SUCCESS(rc) 1573 && VBOX_SUCCESS(rc2)) 1589 int ret; 1590 rc = strioctl(pVNodeUDP, I_PUNLINK, (intptr_t)Interface.lifr_ip_muxid, 0, K_TO_K, kcred, &ret); 1591 rc2 = strioctl(pVNodeUDP, I_PUNLINK, (intptr_t)Interface.lifr_arp_muxid, 0, K_TO_K, kcred, &ret); 1592 if ( !rc 1593 && !rc2) 1574 1594 { 1575 1595 /* 1576 * We need to I_PUNLINK on these multiplexor IDs before we can start 1577 * operating on the lower stream as insertions are direct operations on the lower stream. 1596 * Obtain the vnode from the useless userland file descriptor. 1578 1597 */ 1579 int ret; 1580 rc = strioctl(pVNodeUDP, I_PUNLINK, (intptr_t)Interface.lifr_ip_muxid, 0, K_TO_K, kcred, &ret); 1581 rc2 = strioctl(pVNodeUDP, I_PUNLINK, (intptr_t)Interface.lifr_arp_muxid, 0, K_TO_K, kcred, &ret); 1582 if ( !rc 1583 && !rc2) 1598 file_t *pIpFile = getf(IpMuxFd); 1599 file_t *pArpFile = getf(ArpMuxFd); 1600 if ( pIpFile 1601 && pArpFile 1602 && pArpFile->f_vnode 1603 && pIpFile->f_vnode) 1584 1604 { 1605 vnode_t *pVNodeIp = pIpFile->f_vnode; 1606 vnode_t *pVNodeArp = pArpFile->f_vnode; 1607 1585 1608 /* 1586 * Obtain the vnode from the useless userland file descriptor.1609 * Find the position on the host stack for attaching/detaching ourselves. 1587 1610 */ 1588 file_t *pIpFile = getf(IpMuxFd); 1589 file_t *pArpFile = getf(ArpMuxFd); 1590 if ( pIpFile 1591 && pArpFile 1592 && pArpFile->f_vnode 1593 && pIpFile->f_vnode) 1611 rc = vboxNetFltSolarisDetermineModPos(fAttach, pVNodeIp, &StrMod.pos); 1612 rc2 = vboxNetFltSolarisDetermineModPos(fAttach, pVNodeArp, &ArpStrMod.pos); 1613 if ( VBOX_SUCCESS(rc) 1614 && VBOX_SUCCESS(rc2)) 1594 1615 { 1595 vnode_t *pVNodeIp = pIpFile->f_vnode;1596 vnode_t *pVNodeArp = pArpFile->f_vnode;1597 1598 1616 /* 1599 * Find the position on the host stack for attaching/detaching ourselves.1617 * Set global data which will be grabbed by ModOpen. 1600 1618 */ 1601 rc = vboxNetFltSolarisDetermineModPos(fAttach, pVNodeIp, &StrMod.pos); 1602 rc2 = vboxNetFltSolarisDetermineModPos(fAttach, pVNodeArp, &ArpStrMod.pos); 1603 if ( VBOX_SUCCESS(rc) 1604 && VBOX_SUCCESS(rc2)) 1619 g_VBoxNetFltSolarisState.pCurInstance = pThis; 1620 g_VBoxNetFltSolarisState.CurType = kIpStream; 1621 1622 /* 1623 * Inject/Eject from the host IP stack. 1624 */ 1625 rc = strioctl(pVNodeIp, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret); 1626 if (!rc) 1605 1627 { 1606 /** @todo -XXX- Do each step here with full error checking. I know the if-levels are1607 * getting ridiculous but it has to be done as failure here is still possible1608 * (though unlikely) given a terribly ackward user configuration or messed up stack.1609 */1610 /*1611 * Set global data which will be grabbed by ModOpen.1612 */1613 g_VBoxNetFltSolarisState.pCurInstance = pThis;1614 g_VBoxNetFltSolarisState.CurType = kIpStream;1615 1616 /*1617 * Inject/Eject from the host IP stack.1618 */1619 rc = strioctl(pVNodeIp, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret);1620 1621 1628 /* 1622 1629 * Inject/Eject from the host ARP stack. 1623 1630 */ 1624 1631 g_VBoxNetFltSolarisState.CurType = kArpStream; 1625 rc2 = strioctl(pVNodeArp, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&ArpStrMod, 0, K_TO_K, kcred, &ret); 1626 1627 g_VBoxNetFltSolarisState.pCurInstance = NULL; 1628 g_VBoxNetFltSolarisState.CurType = kUndefined; 1629 1630 /* 1631 * Our job's not yet over; we need to relink the upper and lower streams 1632 * otherwise we've pretty much screwed up the host interface. 1633 */ 1634 rc3 = vboxNetFltSolarisRelink(pVNodeUDP, &Interface, IpMuxFd, ArpMuxFd); 1635 if ( !rc 1636 && !rc2 1637 && VBOX_SUCCESS(rc3)) 1632 rc = strioctl(pVNodeArp, fAttach ? _I_INSERT : _I_REMOVE, (intptr_t)&ArpStrMod, 0, K_TO_K, kcred, &ret); 1633 if (!rc) 1638 1634 { 1639 bool fRawModeOk = !fAttach; /* Raw mode check is always ok during the detach case */ 1640 if (fAttach) 1635 g_VBoxNetFltSolarisState.pCurInstance = NULL; 1636 g_VBoxNetFltSolarisState.CurType = kUndefined; 1637 1638 /* 1639 * Our job's not yet over; we need to relink the upper and lower streams 1640 * otherwise we've pretty much screwed up the host interface. 1641 */ 1642 rc = vboxNetFltSolarisRelink(pVNodeUDP, &Interface, IpMuxFd, ArpMuxFd); 1643 if (VBOX_SUCCESS(rc)) 1641 1644 { 1642 /* 1643 * Check if our raw mode request was successful (only in the IP stream). 1644 */ 1645 vboxnetflt_stream_t *pStream = pThis->u.s.pvStream; 1646 AssertRelease(pStream); 1647 if ( pStream->fRawMode == true 1648 && pStream->ModeReqId == VBOXNETFLT_MODE_REQ_MAGIC) 1645 bool fRawModeOk = !fAttach; /* Raw mode check is always ok during the detach case */ 1646 if (fAttach) 1649 1647 { 1650 pStream->ModeReqId = 0; 1651 fRawModeOk = true; 1648 /* 1649 * Check if our raw mode request was successful (only in the IP stream). 1650 */ 1651 vboxnetflt_stream_t *pStream = pThis->u.s.pvStream; 1652 if (RT_LIKELY(pStream)) 1653 { 1654 if ( pStream->fRawMode == true 1655 && pStream->ModeReqId == VBOXNETFLT_MODE_REQ_MAGIC) 1656 { 1657 pStream->ModeReqId = 0; 1658 fRawModeOk = true; 1659 } 1660 } 1661 } 1662 1663 if (fRawModeOk) 1664 { 1665 /* 1666 * Close the devices ONLY during the return from function case; otherwise 1667 * we end up close twice which is an instant kernel panic. 1668 */ 1669 vboxNetFltSolarisCloseDev(pVNodeUDPHeld, pUserUDP); 1670 ldi_close(ARPDevHandle, FREAD | FWRITE, kcred); 1671 ldi_close(IPDevHandle, FREAD | FWRITE, kcred); 1672 1673 LogFlow((DEVICE_NAME ":vboxNetFltSolarisModSetup: Success! %s %s@(Ip:%d Arp:%d) %s interface %s\n", 1674 fAttach ? "Injected" : "Ejected", StrMod.mod_name, StrMod.pos, ArpStrMod.pos, 1675 fAttach ? "to" : "from", pThis->szName)); 1676 return VINF_SUCCESS; 1652 1677 } 1653 1678 else 1654 fRawModeOk = false; 1655 } 1656 1657 if (fRawModeOk) 1658 { 1659 /* 1660 * Close the devices ONLY during the return from function case; otherwise 1661 * we end up close twice which is an instant kernel panic. 1662 */ 1663 vboxNetFltSolarisCloseDev(pVNodeUDPHeld, pUserUDP); 1664 ldi_close(IPDevHandle, FREAD | FWRITE, kcred); 1665 ldi_close(ARPDevHandle, FREAD | FWRITE, kcred); 1666 ldi_ident_release(DevId); 1667 1668 LogFlow((DEVICE_NAME ":vboxNetFltSolarisModSetup: Success! %s %s@(Ip:%d Arp:%d) %s %s\n", 1669 fAttach ? "Attached" : "Detached", StrMod.mod_name, StrMod.pos, ArpStrMod.pos, 1670 fAttach ? "to" : "from", pThis->szName)); 1671 return VINF_SUCCESS; 1679 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: Raw mode request failed.\n")); 1672 1680 } 1673 1681 else 1674 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: Raw mode request failed.\n")); 1682 { 1683 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: module relinking failed. Mode=%s rc=%d.\n", 1684 fAttach ? "inject" : "eject", rc)); 1685 } 1686 1687 /* 1688 * Try failing gracefully during attach. 1689 */ 1690 if (fAttach) 1691 strioctl(pVNodeIp, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret); 1675 1692 } 1676 1693 else 1677 1694 { 1678 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: module %s or relinking failed. rc=%d rc2=%d rc3=%d.\n", 1679 fAttach ? "insert" : "remove", rc, rc2, rc3)); 1680 1681 /* 1682 * Try failing gracefully during attach. 1683 */ 1684 /** @todo -XXX- see todo above, and remove later accordingly. */ 1685 if (fAttach) 1686 { 1687 strioctl(pVNodeIp, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret); 1688 strioctl(pVNodeArp, _I_REMOVE, (intptr_t)&ArpStrMod, 0, K_TO_K, kcred, &ret); 1689 vboxNetFltSolarisRelink(pVNodeUDP, &Interface, IpMuxFd, ArpMuxFd); 1690 } 1695 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to %s the ARP stack. rc=%d\n", 1696 fAttach ? "inject into" : "eject from", rc)); 1691 1697 } 1698 1699 if (fAttach) 1700 strioctl(pVNodeIp, _I_REMOVE, (intptr_t)&StrMod, 0, K_TO_K, kcred, &ret); 1701 1702 vboxNetFltSolarisRelink(pVNodeUDP, &Interface, IpMuxFd, ArpMuxFd); 1692 1703 } 1693 1704 else 1694 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: vboxNetFltSolarisDetermineModPos failed. rc=%d rc2=%d\n", rc, rc2)); 1705 { 1706 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to %s the IP stack. rc=%d\n", 1707 fAttach ? "inject into" : "eject from", rc)); 1708 } 1695 1709 } 1696 1710 else 1697 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get vnode from MuxFd.\n"));1711 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: vboxNetFltSolarisDetermineModPos failed. rc=%d rc2=%d\n", rc, rc2)); 1698 1712 } 1699 1713 else 1700 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to unlink upper stream rc=%d rc2=%d.\n", rc, rc2));1714 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get vnode from MuxFd.\n")); 1701 1715 } 1702 1716 else 1703 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get MuxFd from MuxId. rc=%d rc2=%d\n"));1717 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to unlink upper stream rc=%d rc2=%d.\n", rc, rc2)); 1704 1718 } 1705 1719 else 1706 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get Mux Ids.\n")); 1707 vboxNetFltSolarisCloseDev(pVNodeUDPHeld, pUserUDP); 1720 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get MuxFd from MuxId. rc=%d rc2=%d\n")); 1708 1721 } 1709 1722 else 1710 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to open UDP.\n")); 1723 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to get Mux Ids.\n")); 1724 vboxNetFltSolarisCloseDev(pVNodeUDPHeld, pUserUDP); 1711 1725 } 1712 1726 else 1713 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: invalid interface '%s'.\n", pThis->szName)); 1714 1715 ldi_close(IPDevHandle, FREAD | FWRITE, kcred); 1716 ldi_close(ARPDevHandle, FREAD | FWRITE, kcred); 1717 ldi_ident_release(DevId); 1727 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to open UDP.\n")); 1718 1728 } 1719 1729 else 1720 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: failed to open IP and/or ARP!\n")); 1730 LogRel((DEVICE_NAME ":vboxNetFltSolarisModSetup: invalid interface '%s'.\n", pThis->szName)); 1731 1732 ldi_close(ARPDevHandle, FREAD | FWRITE, kcred); 1733 ldi_close(IPDevHandle, FREAD | FWRITE, kcred); 1721 1734 1722 1735 return VERR_INTNET_FLT_IF_FAILED; … … 2021 2034 2022 2035 pEtherMsg->b_cont = pMsg->b_cont; 2036 2037 /* 2038 * Change the chained blocks to type M_DATA. 2039 */ 2040 for (mblk_t *pTmp = pEtherMsg->b_cont; pTmp; pTmp = pTmp->b_cont) 2041 DB_TYPE(pTmp) = M_DATA; 2042 2023 2043 pMsg->b_cont = NULL; 2024 2044 freemsg(pMsg); … … 2033 2053 * 2034 2054 * @returns VBox status code. 2035 * @param pThis The instance.2036 * @param p Queue Pointer to the queue.2037 * @param p Msg Pointer to the message.2038 * @param fSrc The source of the frame.2039 */ 2040 static int vboxNetFltSolaris IOWorker(PVBOXNETFLTINS pThis, queue_t *pQueue, vboxnetflt_stream_t *pStream, mblk_t *pMsg, uint32_t fSrc)2041 { 2042 LogFlow((DEVICE_NAME ":vboxNetFltSolaris IOWorker pThis=%p pQueue=%p pMsg=%p fSrc=%d\n", pThis, pQueue, pMsg, fSrc));2055 * @param pThis The instance. 2056 * @param pStream Pointer to the stream. 2057 * @param pQueue Pointer to the queue. 2058 * @param pOrigMsg Pointer to the message. 2059 */ 2060 static int vboxNetFltSolarisRecv(PVBOXNETFLTINS pThis, vboxnetflt_stream_t *pStream, queue_t *pQueue, mblk_t *pOrigMsg) 2061 { 2062 LogFlow((DEVICE_NAME ":vboxNetFltSolarisRecv pThis=%p pOrigMsg=%p\n", pThis, pOrigMsg)); 2043 2063 2044 2064 AssertCompile(sizeof(struct ether_header) == sizeof(RTNETETHERHDR)); 2065 Assert(pStream->Type == kIpStream); 2045 2066 2046 2067 /* 2047 2068 * Make a copy as we will alter pMsg. 2048 2069 */ 2049 mblk_t *p OrigMsg = copymsg(pMsg);2070 mblk_t *pMsg = copymsg(pOrigMsg); 2050 2071 2051 2072 /* … … 2063 2084 { 2064 2085 freemsg(pMsg); 2065 LogRel((DEVICE_NAME ":vboxNetFltSolaris IOWorkerinvalid message!\n"));2086 LogRel((DEVICE_NAME ":vboxNetFltSolarisRecv invalid message!\n")); 2066 2087 return VERR_GENERAL_FAILURE; 2067 2088 } … … 2069 2090 2070 2091 /* 2071 * Figure out the source of the frame based on the source Mac address. 2072 */ 2092 * Figure out the source of the packet based on the source Mac address. 2093 */ 2094 /** @todo Is there a more fool-proof way to determine if the packet was indeed sent from the host?? */ 2095 uint32_t fSrc = INTNETTRUNKDIR_WIRE; 2073 2096 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr; 2074 2097 if (vboxNetFltPortOsIsHostMac(pThis, &pEthHdr->SrcMac)) 2075 2098 fSrc = INTNETTRUNKDIR_HOST; 2076 2099 2100 bool fChecksumAdjusted = false; 2077 2101 #if 0 2078 vboxNetFltSolarisAnalyzeMBlk(pMsg); 2102 if (fSrc & INTNETTRUNKDIR_HOST) 2103 { 2104 mblk_t *pCorrectedMsg = vboxNetFltSolarisFixChecksums(pMsg); 2105 if (pCorrectedMsg) 2106 { 2107 fChecksumAdjusted = true; 2108 pMsg = pCorrectedMsg; 2109 } 2110 } 2079 2111 #endif 2080 2112 2081 2113 /* 2082 * Don't route ARP stream packets from the wire up the internal network, 2083 * because we already get them on the IP stream under full promiscous mode. 2084 * This avoids sending 2 copies of packets into the internal network. 2085 */ 2086 bool fDropIt = false; 2087 if ( pStream->Type == kIpStream 2088 || (pStream->Type == kArpStream && (fSrc & INTNETTRUNKDIR_HOST))) /** Do we really need these?? */ 2089 { 2090 unsigned cSegs = vboxNetFltSolarisMBlkCalcSGSegs(pThis, pMsg); 2091 PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); 2092 int rc = vboxNetFltSolarisMBlkToSG(pThis, pMsg, pSG, cSegs, fSrc); 2093 if (VBOX_FAILURE(rc)) 2094 { 2095 LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG failed. rc=%d\n", rc)); 2096 return rc; 2097 } 2098 2099 fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc); 2100 } 2101 2114 * Route all received packets into the internal network. 2115 */ 2116 unsigned cSegs = vboxNetFltSolarisMBlkCalcSGSegs(pThis, pMsg); 2117 PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); 2118 int rc = vboxNetFltSolarisMBlkToSG(pThis, pMsg, pSG, cSegs, fSrc); 2119 if (VBOX_FAILURE(rc)) 2120 { 2121 LogRel((DEVICE_NAME ":vboxNetFltSolarisMBlkToSG failed. rc=%d\n", rc)); 2122 return rc; 2123 } 2124 2125 bool fDropIt = pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, pSG, fSrc); 2126 2127 /* 2128 * Drop messages consumed by the internal network. 2129 */ 2102 2130 if (fDropIt) 2103 2131 { 2104 LogFlow((DEVICE_NAME ": Packet consumed by internal network.\n"));2132 LogFlow((DEVICE_NAME ":vboxNetFltSolarisRecv Packet consumed by internal network.\n")); 2105 2133 freemsg(pOrigMsg); 2106 2134 freemsg(pMsg); … … 2109 2137 { 2110 2138 /* 2111 * Packets from the host must be send down as raw mode packets.2112 * Packets from the wire, we don't care; just push the original2113 * upstream in whatever way we go it.2139 * Packets from the host, push them up in raw mode. 2140 * Packets from the wire, we must push them in their original form 2141 * as upstream consumers expect this format. 2114 2142 */ 2115 2143 if (pStream->fRawMode) … … 2117 2145 if (fSrc & INTNETTRUNKDIR_HOST) 2118 2146 { 2119 if (fOriginalIsRaw) 2147 /* Raw packets with correct checksums, pass-through the original */ 2148 if ( fOriginalIsRaw 2149 && !fChecksumAdjusted) 2150 { 2120 2151 putnext(pQueue, pOrigMsg); 2121 else 2152 } 2153 else /* For M_PROTO packets or checksum corrected raw packets, pass-through the raw */ 2122 2154 { 2123 2155 putnext(pQueue, pMsg); 2124 pMsg = pOrigMsg; /* for freeing the M_PROTO message*/2156 pMsg = pOrigMsg; /* for the freemsg that follows */ 2125 2157 } 2126 2158 } … … 2162 2194 /** 2163 2195 * Finalize the message to be fed into the internal network. 2164 * 2196 * Verifies and tries to fix checksums for TCP, UDP and IP. 2197 * 2198 * @returns Corrected message or NULL if no change was required. 2165 2199 * @param pMsg Pointer to the message block. 2166 2200 * This must not be DLPI linked messages, must be M_DATA. 2167 2201 * 2168 * @remarks We don't compute ethernet CRC here. 2169 */ 2170 static void vboxNetFltSolarisFinalizeMBlk(mblk_t *pMsg) 2171 { 2172 LogFlow((DEVICE_NAME ":vboxNetFltSolarisFinalizeMBlk pMsg=%p\n")); 2202 * @remarks This function expects raw mblk_t (chained is acceptible) and if it 2203 * returns a corrected message, the passed in input message has been 2204 * freed and should not be referenced anymore. 2205 */ 2206 static mblk_t *vboxNetFltSolarisFixChecksums(mblk_t *pMsg) 2207 { 2208 LogFlow((DEVICE_NAME ":vboxNetFltSolarisFixChecksums pMsg=%p\n")); 2173 2209 2174 2210 Assert(DB_TYPE(pMsg) == M_DATA); 2175 2211 2176 /* 2177 * Concatenate chained mblks. 2178 */ 2179 if (pMsg->b_cont) 2180 { 2181 mblk_t *pFullMsg = allocb(msgdsize(pMsg), BPRI_MED); 2182 if (!pFullMsg) 2183 { 2184 LogRel((DEVICE_NAME ":vboxNetFltSolarisFinalizeMBlk failed to alloc new message.\n")); 2185 return; 2186 } 2187 2188 for (mblk_t *pTmp = pMsg; pTmp; pTmp = pTmp->b_cont) 2189 { 2190 if (DB_TYPE(pTmp) == M_DATA) 2212 if (MBLKL(pMsg) < sizeof(RTNETETHERHDR)) 2213 { 2214 LogRel((DEVICE_NAME ":vboxNetFltSolarisFixChecksums Packet shorter than ethernet header size!\n")); 2215 return NULL; 2216 } 2217 2218 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr; 2219 if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV4)) 2220 { 2221 /* 2222 * Check if we have a complete packet or being fed a chain. 2223 */ 2224 size_t cbIpPacket = 0; 2225 if (pMsg->b_cont) 2226 { 2227 LogFlow((DEVICE_NAME ":Chained mblk_t.\n")); 2228 2229 /* 2230 * Handle chain by making a packet copy to verify if the IP checksum is correct. 2231 * Contributions to calculating IP checksums from a chained message block with 2232 * odd/non-pulled up sizes are welcome. 2233 */ 2234 size_t cbFullMsg = msgdsize(pMsg); 2235 mblk_t *pFullMsg = allocb(cbFullMsg, BPRI_MED); 2236 LogFlow((DEVICE_NAME ":msgdsize returns %d\n", cbFullMsg)); 2237 if (RT_UNLIKELY(!pFullMsg)) 2191 2238 { 2192 bcopy(pTmp->b_rptr, pFullMsg->b_wptr, MBLKL(pTmp)); 2193 pFullMsg->b_wptr += MBLKL(pTmp); 2239 LogRel((DEVICE_NAME ":vboxNetFltSolarisFixChecksums failed to alloc new message of %d bytes.\n", cbFullMsg)); 2240 return false; 2241 } 2242 2243 for (mblk_t *pTmp = pMsg; pTmp; pTmp = pTmp->b_cont) 2244 { 2245 if (DB_TYPE(pTmp) == M_DATA) 2246 { 2247 bcopy(pTmp->b_rptr, pFullMsg->b_wptr, MBLKL(pTmp)); 2248 pFullMsg->b_wptr += MBLKL(pTmp); 2249 } 2250 else 2251 LogFlow((DEVICE_NAME ":Not M_DATA.. this is really bad.\n")); 2252 } 2253 2254 freemsg(pMsg); 2255 pMsg = pFullMsg; 2256 DB_TYPE(pMsg) = M_DATA; 2257 pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr; 2258 } 2259 2260 cbIpPacket = MBLKL(pMsg) - sizeof(RTNETETHERHDR); 2261 2262 /* 2263 * Check if the IP checksum is valid. 2264 */ 2265 PRTNETIPV4 pIpHdr = (PRTNETIPV4)(pEthHdr + 1); 2266 if (!RTNetIPv4IsHdrValid(pIpHdr, cbIpPacket, cbIpPacket)) 2267 { 2268 LogFlow((DEVICE_NAME ":Invalid IP checksum detected. Trying to fix...\n")); 2269 2270 /* 2271 * Fix up TCP/UDP and IP checksums if they're incomplete/invalid. 2272 */ 2273 if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP) 2274 { 2275 size_t cbTcpPacket = cbIpPacket - (pIpHdr->ip_hl << 2); 2276 2277 PRTNETTCP pTcpHdr = (PRTNETTCP)(pIpHdr + 1); 2278 if (!RTNetIPv4IsTCPValid(pIpHdr, pTcpHdr, cbTcpPacket, NULL, cbTcpPacket)) 2279 { 2280 RTNetIPv4TCPChecksum(pIpHdr, pTcpHdr, NULL); 2281 LogFlow((DEVICE_NAME ":fixed TCP checkum.\n")); 2282 } 2283 else 2284 LogFlow((DEVICE_NAME ":valid TCP checksum invalid IP checksum...\n")); 2285 } 2286 else if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP) 2287 { 2288 size_t cbUdpPacket = cbIpPacket - (pIpHdr->ip_hl << 2); 2289 2290 PRTNETUDP pUdpHdr = (PRTNETUDP)(pIpHdr + 1); 2291 RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1); 2292 2293 LogFlow((DEVICE_NAME ":fixed UDP checksum.\n")); 2194 2294 } 2195 2295 else 2196 2296 { 2197 LogRel((DEVICE_NAME ":vboxNetFltSolarisFinalizeMBlk non-M_DATA chained message!\n")); 2198 freemsg(pFullMsg); 2199 return; 2297 LogFlow((DEVICE_NAME ":Non TCP/UDP protocol with invalid IP header!\n")); 2200 2298 } 2201 } 2202 2203 freemsg(pMsg); 2204 pMsg = pFullMsg; 2205 DB_TYPE(pMsg) = M_DATA; 2206 } 2207 2208 size_t cbMsg = MBLKL(pMsg); 2209 if (cbMsg > sizeof(RTNETETHERHDR)) 2210 { 2211 PRTNETETHERHDR pEthHdr = (PRTNETETHERHDR)pMsg->b_rptr; 2212 if (pEthHdr->EtherType == RT_H2BE_U16(RTNET_ETHERTYPE_IPV4)) 2213 { 2214 cbMsg -= sizeof(RTNETETHERHDR); 2215 2216 PRTNETIPV4 pIpHdr = NULL; 2217 if (cbMsg > sizeof(RTNETIPV4)) 2218 pIpHdr = (PRTNETIPV4)(pEthHdr + 1); 2219 else 2220 { 2221 LogRel((DEVICE_NAME ":IP packet too short.\n")); 2222 return; 2223 } 2224 2225 if (RTNetIPv4IsHdrValid(pIpHdr, cbMsg, cbMsg)) 2226 { 2227 #if 0 2228 /* 2229 * Fix up TCP checksum. 2230 */ 2231 if (pIpHdr->ip_p == RTNETIPV4_PROT_TCP) 2232 { 2233 PRTNETTCP pTcpHdr = (PRTNETTCP)(pIpHdr + 1); 2234 cbLen -= pIpHdr->ip_hl * 4; 2235 if (!RTNetIPv4IsTCPValid(pIpHdr, pTcpHdr, cbLen, NULL, cbLen)) 2236 { 2237 /* 2238 * @todo -XXX- this will horribly fail for an mblk_t chain! Fix this later by allocating, copying temp buffer. 2239 */ 2240 RTNetIPv4TCPChecksum(pIpHdr, pTcpHdr, NULL); 2241 LogFlow((DEVICE_NAME ":computed TCP checksum.\n")); 2242 } 2243 } 2244 2245 /* 2246 * Fix up UDP checksum. 2247 */ 2248 if (pIpHdr->ip_p == RTNETIPV4_PROT_UDP) 2249 { 2250 PRTNETUDP pUdpHdr = (PRTNETUDP)(pIpHdr + 1); 2251 cbLen -= pIpHdr->ip_hl * 4; 2252 RTNetIPv4UDPChecksum(pIpHdr, pUdpHdr, pUdpHdr + 1); 2253 LogFlow((DEVICE_NAME ":computed UDP checksum.\n")); 2254 } 2255 RTNetIPv4HdrChecksum(pIpHdr); 2256 LogFlow((DEVICE_NAME ":computed IP checksum.\n")); 2257 #endif 2258 } 2259 else 2260 { 2261 RTNetIPv4HdrChecksum(pIpHdr); 2262 LogFlow((DEVICE_NAME ":Re-Computed IP Header.\n")); 2263 } 2264 } 2265 else 2266 LogFlow((DEVICE_NAME ":EtherType=%x D=%.6Rhxs S=%.6Rhxs\n", RT_H2BE_U16(pEthHdr->EtherType), &pEthHdr->DstMac, &pEthHdr->SrcMac)); 2267 } 2268 else 2269 LogRel((DEVICE_NAME ":Packet shorter than ethernet header size!\n")); 2299 2300 RTNetIPv4HdrChecksum(pIpHdr); 2301 LogFlow((DEVICE_NAME ":fixed IP checkum.\n")); 2302 2303 return pMsg; 2304 } 2305 } 2306 2307 return NULL; 2270 2308 } 2271 2309
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器