Changeset 50747 in vbox for trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
- Timestamp:
- Mar 12, 2014 2:12:22 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/darwin/VBoxNetFlt-darwin.cpp
r50410 r50747 139 139 static mbuf_tag_id_t g_idTag; 140 140 141 /** the offset of the struct ifnet::if_pcount variable . */141 /** the offset of the struct ifnet::if_pcount variable (valid for Lion). */ 142 142 static unsigned g_offIfNetPCount = sizeof(void *) * (1 /*if_softc*/ + 1 /*if_name*/ + 2 /*if_link*/ + 2 /*if_addrhead*/ + 1 /*if_check_multi*/) 143 143 + sizeof(u_long) /*if_refcnt*/; … … 145 145 #define VBOX_GET_PCOUNT(pIfNet) ( *(int *)((uintptr_t)pIfNet + g_offIfNetPCount) ) 146 146 147 /** The size of area of ifnet structure we try to locate if_pcount in. */ 148 #define VBOXNETFLT_DARWIN_IFNET_SIZE 256 149 150 /* 151 * Note that this implementation relies on if_pcount to be aligned on sizeof(int). 152 */ 153 static unsigned vboxNetFltDarwinSetAndDiff(ifnet_t pIfNet, int iPromisc) 154 { 155 unsigned i; 156 int aSavedState[VBOXNETFLT_DARWIN_IFNET_SIZE/sizeof(int)]; 157 158 memcpy(aSavedState, pIfNet, sizeof(aSavedState)); 159 ifnet_set_promiscuous(pIfNet, iPromisc); 160 161 int offset = 0; 162 int iDiff = iPromisc ? 1 : -1; 163 /* 164 * We assume that ifnet structure will never have less members in front of if_pcount 165 * than it used to have in Lion. If this turns out to be false assumption we will 166 * have to start from zero offset. 167 */ 168 for (i = g_offIfNetPCount / sizeof(int); i < sizeof(aSavedState) / sizeof(int); i++) 169 if (((int*)pIfNet)[i] - aSavedState[i] == iDiff) 170 { 171 offset = i * sizeof(int); 172 break; 173 } 174 175 return offset; 176 } 177 178 /** 179 * Detect and adjust the offset of ifnet::if_pcount. 180 */ 181 static void vboxNetFltDarwinDetectPCountOffset(ifnet_t pIfNet) 182 { 183 unsigned offTry1, offTry2, offTry3, offTry4; 184 /* 185 * It would be nice to use locking at this point, but it is not available via KPI. 186 * This is why we try several times. At each attempt we modify if_pcount four times 187 * to rule out false detections. 188 */ 189 for (int nAttempts = 0; nAttempts < 3; nAttempts++) 190 { 191 offTry1 = vboxNetFltDarwinSetAndDiff(pIfNet, 1); 192 offTry2 = vboxNetFltDarwinSetAndDiff(pIfNet, 1); 193 offTry3 = vboxNetFltDarwinSetAndDiff(pIfNet, 0); 194 offTry4 = vboxNetFltDarwinSetAndDiff(pIfNet, 0); 195 /* If any attempt has failed we won't continue as our algorithm is flawed. */ 196 if (!offTry1 || !offTry2 || !offTry3 || !offTry4) 197 break; 198 if (offTry1 == offTry2 && offTry2 == offTry3 && offTry3 == offTry4) 199 { 200 if (g_offIfNetPCount != offTry1) 201 { 202 Log(("VBoxNetFltDarwinDetectPCountOffset: Adjusted if_pcount offset to %x from %x.\n", offTry1, g_offIfNetPCount)); 203 g_offIfNetPCount = offTry1; 204 } 205 break; 206 } 207 } 208 209 if (g_offIfNetPCount != offTry1) 210 LogRel(("VBoxNetFlt: Failed to detect promiscuous count, all traffic may reach wire (%x != %x).\n", g_offIfNetPCount, offTry1)); 211 } 147 212 148 213 /** … … 956 1021 RTSpinlockReleaseNoInts(pThis->hSpinlock); 957 1022 1023 /* Adjust g_offIfNetPCount as it varies for different versions of xnu. */ 1024 vboxNetFltDarwinDetectPCountOffset(pIfNet); 1025 958 1026 /* Prevent stuck-in-dock issue by associating interface receive thread with kernel thread. */ 959 1027 vboxNetFltSendDummy(pIfNet);
Note:
See TracChangeset
for help on using the changeset viewer.