📄 miniport.cxx
字号:
if (pAdapter) {
gpPAN->AddRef ();
gpPAN->Unlock ();
MpMediaStatusIndicate (pAdapter);
gpPAN->Lock ();
gpPAN->DelRef ();
}
}
if (pAdapter)
pAdapter->DelRef ();
}
static BTHPAN_CONNECTION *GetAdapterConnection (BTHPAN_ADAPTER *pAdapter) {
SVSUTIL_ASSERT (gpPAN->IsLocked ());
int nAdapter = pAdapter - gpPAN->aAdapters;
int i;
for (i = 0 ; i < SVSUTIL_ARRLEN(gpPAN->aConn) ; ++i) {
if ((gpPAN->aConn[i].state != DOWN) && (gpPAN->aConn[i].nAdapter == nAdapter)) {
return &gpPAN->aConn[i];
}
}
return NULL;
}
static DWORD WINAPI TimeoutConnection (void *pCallContext) { // Aborted call == immediate death...
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"TimeoutConnection 0x%08x\n", pCallContext));
if (! gpPAN) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PAN] TimeoutConnection: context doesn't exist\n"));
return ERROR_SUCCESS;
}
gpPAN->Lock ();
if (gpPAN->state != UP) {
IFDBG(DebugOut (DEBUG_ERROR, L"[PAN] TimeoutConnection: context not up\n"));
gpPAN->Unlock ();
return ERROR_SUCCESS;
}
BTHPAN_CONNECTION *pConn = ConnFromCtx (pCallContext);
if (pConn) {
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"TimeoutConnection : aborting connection %04x%08x cid=0x%04x\n", pConn->ba.NAP, pConn->ba.SAP, pConn->cid));
CloseConnection (pConn, NULL);
} else {
IFDBG(DebugOut (DEBUG_ERROR, L"[PAN] TimeoutConnection: connection not found!\n"));
}
gpPAN->Unlock ();
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"TimeoutConnection DONE\n"));
return ERROR_SUCCESS;
}
static void ConnectionStarted (BTHPAN_CONNECTION *pConn) {
SVSUTIL_ASSERT (gpPAN->IsLocked ());
SVSUTIL_ASSERT (pConn->state == CONFIG_LINK);
SVSUTIL_ASSERT (pConn->fConfigState == CONFIG_DONE);
pConn->state = CONFIG_BNEP;
pConn->fConfigState = 0;
if (pConn->fPeerInitiated) // Nothing to do, just wait for the other guy
return;
// We started connection, so we KNOW what adapter it is.
SVSUTIL_ASSERT (pConn->nAdapter >= 0);
unsigned char packet_body[256];
SVSUTIL_ASSERT(gpPAN->cDataHeaders + gpPAN->cDataTrailers < 128);
unsigned char *p = packet_body + gpPAN->cDataHeaders;
*p++ = 0x01; // Control
*p++ = 0x01; // Setup connection request
unsigned int uiDestUUID, uiSrcUUID;
if (IsBluetoothBasedGUID (&pConn->dest_service_id, &uiDestUUID) &&
IsBluetoothBasedGUID (&gpPAN->aAdapters[pConn->nAdapter].service_id, &uiSrcUUID)) {
if ((uiSrcUUID <= 0xffff) && (uiDestUUID <= 0xffff)) {
*p++ = 2;
*p++ = (unsigned char)(uiDestUUID >> 8);
*p++ = (unsigned char)(uiDestUUID);
*p++ = (unsigned char)(uiSrcUUID >> 8);
*p++ = (unsigned char)(uiSrcUUID);
} else { // 32 bits
*p++ = 4;
*p++ = (unsigned char)(uiDestUUID >> 24);
*p++ = (unsigned char)(uiDestUUID >> 16);
*p++ = (unsigned char)(uiDestUUID >> 8);
*p++ = (unsigned char)(uiDestUUID);
*p++ = (unsigned char)(uiSrcUUID >> 24);
*p++ = (unsigned char)(uiSrcUUID >> 16);
*p++ = (unsigned char)(uiSrcUUID >> 8);
*p++ = (unsigned char)(uiSrcUUID);
}
} else { // Full UUIDs
*p++ = sizeof(GUID); // UUID size - full UUIDs
SVSUTIL_ASSERT (sizeof(GUID) == sizeof(pConn->dest_service_id));
SVSUTIL_ASSERT (sizeof(GUID) == sizeof(gpPAN->aAdapters[pConn->nAdapter].service_id));
UUIDToWire (p, &pConn->dest_service_id);
p += sizeof(GUID);
UUIDToWire (p, &gpPAN->aAdapters[pConn->nAdapter].service_id);
p += sizeof(GUID);
}
BD_BUFFER Buff;
Buff.cSize = (p - packet_body) + gpPAN->cDataTrailers;
Buff.cStart = gpPAN->cDataHeaders;
Buff.cEnd = Buff.cSize - gpPAN->cDataTrailers;
Buff.pFree = BufferFree;
Buff.fMustCopy = TRUE;
Buff.pBuffer = packet_body;
unsigned int uiConnRef = pConn->uiRef;
pConn->scTimeout = btutil_ScheduleEvent (TimeoutConnection, ConnToCtx (pConn), gpPAN->aAdapters[pConn->nAdapter].uiCrtTimeout);
if (! StartAuthenticatingThread (pConn)) {
gpPAN->AddRef ();
gpPAN->Unlock ();
IFDBG(DumpBnepPacket (L"Sending connection request.", &Buff));
int iRes = gpPAN->l2cap_if.l2ca_DataDown_In (gpPAN->hL2CAP, ConnToCtx (pConn), pConn->cid, &Buff);
gpPAN->Lock ();
gpPAN->DelRef ();
if ((iRes != ERROR_SUCCESS) && (pConn->uiRef == uiConnRef))
CloseConnection (pConn, NULL);
} else { // Delay request
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ConnectionStarted : connection request delayed pending authentication\n"));
BNEPPacket *pPendingPacket = new BNEPPacket(BufferCopy(&Buff));
if (pPendingPacket)
QueuePendingPacket(pConn, pPendingPacket);
}
}
static void AddConfigFlag (BTHPAN_CONNECTION *pConn, unsigned int uiFlag) {
pConn->fConfigState |= uiFlag;
if (pConn->fConfigState == CONFIG_DONE)
ConnectionStarted (pConn);
}
static void MpCleanUpConnections (void) {
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"MpCleanUpConnections\n"));
// Go through all adapters and set states of everything to disconnected
gpPAN->Lock ();
int i;
for (i = 0 ; i < SVSUTIL_ARRLEN (gpPAN->aConn) ; ++i)
SetConnectionToDown (&gpPAN->aConn[i]);
gpPAN->Unlock ();
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"MpCleanUpConnections DONE\n"));
}
static int FilterByMCast (FILTER *pFilter, unsigned char *pAddr) {
if (pFilter->cMCasts == 0)
return FALSE;
unsigned __int64 ui64Addr = net48tohost64(pAddr);
for (int i = 0 ; i < (int)pFilter->cMCasts ; ++i) {
pAddr = (unsigned char *)&pFilter->amc[i].from;
unsigned __int64 ui64from = net48tohost64(pAddr);
pAddr = (unsigned char *)&pFilter->amc[i].to;
unsigned __int64 ui64to = net48tohost64(pAddr);
if ((ui64Addr >= ui64from) && (ui64Addr <= ui64to))
return FALSE;
}
return TRUE;
}
static int FilterByType (FILTER *pFilter, unsigned int uiNetType) {
// Returns TRUE if packet is filtered out (NOT sent)
if (pFilter->cNetTypes == 0)
return FALSE;
for (int i = 0 ; i < (int)pFilter->cNetTypes ; ++i) {
if ((uiNetType >= pFilter->ant[i].from) && (uiNetType <= pFilter->ant[i].to))
return FALSE;
}
return TRUE;
}
static void InvertAddress (unsigned char *pAddr1, unsigned char *pAddr2, unsigned char *pAddr3) {
if (memcmp (pAddr1, pAddr3, 6) == 0)
memcpy (pAddr1, pAddr2, 6);
else if (memcmp (pAddr1, pAddr2, 6) == 0)
memcpy (pAddr1, pAddr3, 6);
}
static int ComputeTotalExtensionLengthByType (unsigned char *pExt, int cTotal, BOOL fIgnoreKnown) { // return > 0 or -1
// Total can be bigger than extensions.
int fExt = TRUE;
int iLen = 0;
while (fExt) {
if (cTotal < 2)
return -1;
unsigned char eType = *pExt & 0x7f;
fExt = *pExt >> 7;
unsigned char eLen = pExt[1];
if (eLen < 1)
return -1;
cTotal -= eLen;
pExt += eLen + 2;
if (!fIgnoreKnown || (eType != 0))
iLen += eLen + 2;
}
return (cTotal >= 0) ? iLen : -1;
}
static int ComputeTotalExtensionLength (unsigned char *pExt, int cTotal) {
return ComputeTotalExtensionLengthByType (pExt, cTotal, FALSE);
}
static void ProcessArpData (BTHPAN_ADAPTER *pAdapter, unsigned char *pPacket, int cPacket) {
if ((cPacket != 28) && (cPacket != 46)) {
IFDBG(DebugOut (DEBUG_WARN, L"[PAN] Warning - ARP packet with unexpected zie %d\n", cPacket));
return;
}
if (pAdapter->fAddressSet) {
// Substitute our internal addresses for Bluetooth and vice versa in ARP packets.
InvertAddress (pPacket + 8, pAdapter->ethAddr, gpPAN->eth);
InvertAddress (pPacket + 18, pAdapter->ethAddr, gpPAN->eth);
}
}
static int ProcessEthernet (
BTHPAN_CONNECTION *pConnRecv,
unsigned char *pDestEther,
unsigned char *pSrcEther,
unsigned int uiNetType,
unsigned char *p8021q,
unsigned char *pExt,
int iExtSize,
unsigned char *pData,
int cData) {
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet\n"));
SVSUTIL_ASSERT (gpPAN->IsLocked ());
unsigned int uiConnRef = pConnRecv->uiRef;
if (pConnRecv->state == CONFIG_SECURITY) {
IFDBG(DebugOut (DEBUG_WARN, L"ProcessEthernet : packet dropped because security setup is still in process\n"));
return TRUE;
}
if ((pConnRecv->state != UP) || (pConnRecv->nAdapter == -1) || (gpPAN->aAdapters[pConnRecv->nAdapter].state != UP)) {
IFDBG(DebugOut (DEBUG_WARN, L"ProcessEthernet : packet on a closed (or closing) connection or on inactive adapter\n"));
return FALSE;
}
if (! pSrcEther)
pSrcEther = pConnRecv->eth;
if (! pDestEther)
pDestEther = gpPAN->eth;
BTHPAN_ADAPTER *pAdapter = &gpPAN->aAdapters[pConnRecv->nAdapter];
pAdapter->AddRef ();
int nAdapter = pAdapter - gpPAN->aAdapters;
int fMCast = ETH_IS_MULTICAST(pDestEther);
int fBroad = ETH_IS_BROADCAST(pDestEther);
int fUnicast = (! (fMCast || fBroad));
int fUnicastToMe = fUnicast && (memcmp (gpPAN->eth, pDestEther, 6) == 0);
int fConsumerFound = FALSE;
if ((! fUnicastToMe) && (pAdapter->type != PANU)) { // Do the forwarding...
for (int i = 0 ; (pAdapter->state == UP) && (i < SVSUTIL_ARRLEN (gpPAN->aConn)) ; ++i) {
if ((pConnRecv != &gpPAN->aConn[i]) && (gpPAN->aConn[i].nAdapter == nAdapter) && (gpPAN->aConn[i].state == UP)) {
BTHPAN_CONNECTION *pConnForward = &gpPAN->aConn[i];
// Broadcast addresses are sent everywhere
// Multicast addresses are sent everywhere except where not filtered
// If this adapter is PANU, it sends everything over this one and only one connection
int fSendSrc = TRUE; // Source is always sent - this packet came from elsewhere
int fSendDst = (memcmp (pConnForward->eth, pDestEther, 6) != 0);
if ((! (fBroad || fMCast)) && fSendDst)
continue;
if (! fSendDst) // got it!
fConsumerFound = TRUE;
BOOL fOmitPayload = FALSE;
int iUnkExtSize = 0;
if (pExt && (iExtSize > 0))
iUnkExtSize = ComputeTotalExtensionLengthByType(pExt, iExtSize, TRUE);
if (iUnkExtSize < 0) {
// Something has gone wrong! We should never get here since we should have
// already verified that the extension headers look good.
SVSUTIL_ASSERT(0);
return FALSE;
}
if (FilterByType (&pConnForward->filter, uiNetType)) {
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: packet filtered by net type rule\n"));
if (iUnkExtSize == 0)
continue;
fOmitPayload = TRUE;
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: forwarding *just* unknown extensions\n"));
}
if (fMCast && FilterByMCast (&pConnForward->filter, pDestEther)) {
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: packet filtered by mcast rule\n"));
if (iUnkExtSize == 0)
continue;
fOmitPayload = TRUE;
IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: forwarding *just* unknown extensions\n"));
}
// Send the thing...
BD_BUFFER *pBuff = BufferAlloc (gpPAN->cDataHeaders + gpPAN->cDataTrailers + (fSendSrc ? 6 : 0) + (fSendDst ? 6 : 0) + 3 + iUnkExtSize + (p8021q ? 4 : 0) + (fOmitPayload ? 0 : cData));
if (pBuff) {
pBuff->cStart = gpPAN->cDataHeaders;
pBuff->cEnd = pBuff->cSize - gpPAN->cDataTrailers;
// ** Add addresses **
unsigned char *p = pBuff->pBuffer + pBuff->cStart;
if (fSendSrc && fSendDst) {
*p++ = (iUnkExtSize ? 0x80 : 0x00); // general ether
memcpy (p, pDestEther, 6);
p += 6;
memcpy (p, pSrcEther, 6);
p += 6;
} else if (fSendSrc) {
*p++ = (iUnkExtSize ? 0x83 : 0x03); // source only
memcpy (p, pSrcEther, 6);
p += 6;
} else if (fSendDst) {
*p++ = (iUnkExtSize ? 0x84 : 0x04); // dest only
memcpy (p, pDestEther, 6);
p += 6;
} else {
*p++ = (iUnkExtSize ? 0x82 : 0x02); // compressed
}
// ** Add protocol type **
if (p8021q) { // always use 802.1q header if present
*p++ = 0x81;
*p++ = 0x00;
} else if (fOmitPayload) { // zero out protocol when filtered
*p++ = 0x00;
*p++ = 0x00;
} else {
*p++ = uiNetType >> 8;
*p++ = uiNetType & 0xff;
}
// ** Add unknown extensions **
while (iUnkExtSize > 0) {
unsigned char eType = *pExt & 0x7f;
unsigned int eLen = pExt[1];
if (eType != 0) {
if ((iUnkExtSize - (2 + eLen)) > 0)
*pExt |= 0x80; // more extensions
else
*pExt &= 0x7f; // last extension
// Add this unknown extension to the packet
memcpy (p, pExt, eLen + 2);
p += (2 + eLen);
iUnkExtSize -= (2 + eLen);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -