📄 ethsock.cxx
字号:
{ if (!IsOpen()) return SetErrorValues(NotOpen, EBADF); DWORD filter = 0; if (!driver->QueryOid(OID_GEN_CURRENT_PACKET_FILTER, filter)) return SetErrorValues(Miscellaneous, driver->GetLastError()|PWIN32ErrorFlag); if (filter == 0) return PEthSocket::FilterDirected; mask = 0; for (PINDEX i = 0; i < PARRAYSIZE(FilterMasks); i++) { if ((filter&FilterMasks[i].ndis) != 0) mask |= FilterMasks[i].pwlib; } type = (WORD)filterType; return TRUE;}BOOL PEthSocket::SetFilter(unsigned filter, WORD type){ if (!IsOpen()) return SetErrorValues(NotOpen, EBADF); DWORD bits = 0; for (PINDEX i = 0; i < PARRAYSIZE(FilterMasks); i++) { if ((filter&FilterMasks[i].pwlib) != 0) bits |= FilterMasks[i].ndis; } if (!driver->SetOid(OID_GEN_CURRENT_PACKET_FILTER, bits)) return SetErrorValues(Miscellaneous, driver->GetLastError()|PWIN32ErrorFlag); filterType = type; return TRUE;}PEthSocket::MediumTypes PEthSocket::GetMedium(){ if (!IsOpen()) { SetErrorValues(NotOpen, EBADF); return NumMediumTypes; } DWORD medium = 0xffffffff; if (!driver->QueryOid(OID_GEN_MEDIA_SUPPORTED, medium) || medium == 0xffffffff) { SetErrorValues(Miscellaneous, driver->GetLastError()|PWIN32ErrorFlag); return NumMediumTypes; } static const DWORD MediumValues[NumMediumTypes] = { 0xffffffff, NdisMedium802_3, NdisMediumWan, 0xffffffff }; for (int type = Medium802_3; type < NumMediumTypes; type++) { if (MediumValues[type] == medium) return (MediumTypes)type; } return MediumUnknown;}BOOL PEthSocket::Read(void * data, PINDEX length){ if (!IsOpen()) return SetErrorValues(NotOpen, EBADF, LastReadError); PINDEX idx; PINDEX numBuffers = readBuffers.GetSize(); do { HANDLE handles[MAXIMUM_WAIT_OBJECTS]; for (idx = 0; idx < numBuffers; idx++) { PWin32PacketBuffer & buffer = readBuffers[idx]; if (buffer.InProgress()) { if (WaitForSingleObject(buffer.GetEvent(), 0) == WAIT_OBJECT_0) if (!buffer.ReadComplete(*driver)) return ConvertOSError(-1, LastReadError); } else { if (!buffer.ReadAsync(*driver)) return ConvertOSError(-1, LastReadError); } if (buffer.IsCompleted() && buffer.IsType(filterType)) { lastReadCount = buffer.GetData(data, length); return TRUE; } handles[idx] = buffer.GetEvent(); } DWORD result; PINDEX retries = 100; for (;;) { result = WaitForMultipleObjects(numBuffers, handles, FALSE, INFINITE); if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + (DWORD)numBuffers) break; if (::GetLastError() != ERROR_INVALID_HANDLE || retries == 0) return ConvertOSError(-1, LastReadError); retries--; } idx = result - WAIT_OBJECT_0; if (!readBuffers[idx].ReadComplete(*driver)) return ConvertOSError(-1, LastReadError); } while (!readBuffers[idx].IsType(filterType)); lastReadCount = readBuffers[idx].GetData(data, length); return TRUE;}BOOL PEthSocket::Write(const void * data, PINDEX length){ if (!IsOpen()) return SetErrorValues(NotOpen, EBADF, LastWriteError); HANDLE handles[MAXIMUM_WAIT_OBJECTS]; PINDEX numBuffers = writeBuffers.GetSize(); PINDEX idx; for (idx = 0; idx < numBuffers; idx++) { PWin32PacketBuffer & buffer = writeBuffers[idx]; if (buffer.InProgress()) { if (WaitForSingleObject(buffer.GetEvent(), 0) == WAIT_OBJECT_0) if (!buffer.WriteComplete(*driver)) return ConvertOSError(-1, LastWriteError); } if (!buffer.InProgress()) { lastWriteCount = buffer.PutData(data, length); return ConvertOSError(buffer.WriteAsync(*driver) ? 0 : -1, LastWriteError); } handles[idx] = buffer.GetEvent(); } DWORD result = WaitForMultipleObjects(numBuffers, handles, FALSE, INFINITE); if (result < WAIT_OBJECT_0 || result >= WAIT_OBJECT_0 + (DWORD) numBuffers) return ConvertOSError(-1, LastWriteError); idx = result - WAIT_OBJECT_0; if (!writeBuffers[idx].WriteComplete(*driver)) return ConvertOSError(-1, LastWriteError); lastWriteCount = writeBuffers[idx].PutData(data, length); return ConvertOSError(writeBuffers[idx].WriteAsync(*driver) ? 0 : -1, LastWriteError);}///////////////////////////////////////////////////////////////////////////////PWin32PacketBuffer::PWin32PacketBuffer(PINDEX sz) : PBYTEArray(sz){ status = Uninitialised; count = 0;}PINDEX PWin32PacketBuffer::GetData(void * buf, PINDEX size){ if (count > (DWORD)size) count = size; memcpy(buf, theArray, count); return count;}PINDEX PWin32PacketBuffer::PutData(const void * buf, PINDEX length){ count = min(GetSize(), length); memcpy(theArray, buf, count); return count;}BOOL PWin32PacketBuffer::ReadAsync(PWin32PacketDriver & pkt){ if (status == Progressing) return FALSE; status = Uninitialised; if (!pkt.BeginRead(theArray, GetSize(), count, overlap)) return FALSE; if (pkt.GetLastError() == ERROR_SUCCESS) status = Completed; else status = Progressing; return TRUE;}BOOL PWin32PacketBuffer::ReadComplete(PWin32PacketDriver & pkt){ if (status != Progressing) return status == Completed; if (!pkt.CompleteIO(count, overlap)) { status = Uninitialised; return FALSE; } status = Completed; return TRUE;}BOOL PWin32PacketBuffer::WriteAsync(PWin32PacketDriver & pkt){ if (status == Progressing) return FALSE; status = Uninitialised; if (!pkt.BeginWrite(theArray, count, overlap)) return FALSE; if (pkt.GetLastError() == ERROR_SUCCESS) status = Completed; else status = Progressing; return TRUE;}BOOL PWin32PacketBuffer::WriteComplete(PWin32PacketDriver & pkt){ if (status != Progressing) return status == Completed; DWORD dummy; if (pkt.CompleteIO(dummy, overlap)) { status = Completed; return TRUE; } status = Uninitialised; return FALSE;}BOOL PWin32PacketBuffer::IsType(WORD filterType) const{ if (filterType == PEthSocket::TypeAll) return TRUE; const PEthSocket::Frame * frame = (const PEthSocket::Frame *)theArray; WORD len_or_type = ntohs(frame->snap.length); if (len_or_type > sizeof(*frame)) return len_or_type == filterType; if (frame->snap.dsap == 0xaa && frame->snap.ssap == 0xaa) return ntohs(frame->snap.type) == filterType; // SNAP header if (frame->snap.dsap == 0xff && frame->snap.ssap == 0xff) return PEthSocket::TypeIPX == filterType; // Special case for Novell netware's stuffed up 802.3 if (frame->snap.dsap == 0xe0 && frame->snap.ssap == 0xe0) return PEthSocket::TypeIPX == filterType; // Special case for Novell netware's 802.2 return frame->snap.dsap == filterType; // A pure 802.2 protocol id}////////////////////////////////////////////////////////////////////////////////*static PMutex & GetSNMPMutex(){ static PMutex snmpmutex; return snmpmutex;}*/BOOL PIPSocket::GetGatewayAddress(Address & addr){ PWaitAndSignal m(GetSNMPMutex()); PWin32SnmpLibrary & snmp = PWin32SnmpLibrary::Current(); PWin32AsnOid gatewayOid = "1.3.6.1.2.1.4.21.1.7.0.0.0.0"; return snmp.GetOid(gatewayOid, addr);}PString PIPSocket::GetGatewayInterface(){ PWaitAndSignal m(GetSNMPMutex()); PWin32SnmpLibrary & snmp = PWin32SnmpLibrary::Current(); AsnInteger ifNum = -1; PWin32AsnOid gatewayOid = "1.3.6.1.2.1.4.21.1.2.0.0.0.0"; if (!snmp.GetOid(gatewayOid, ifNum) && ifNum >= 0) return PString::Empty(); return snmp.GetInterfaceName(ifNum);}PIPSocket::Address PIPSocket::GetGatewayInterfaceAddress(){ PWaitAndSignal m(GetSNMPMutex()); PWin32SnmpLibrary & snmp = PWin32SnmpLibrary::Current(); AsnInteger ifNum = -1; PWin32AsnOid gatewayOid = "1.3.6.1.2.1.4.21.1.2.0.0.0.0"; if (!snmp.GetOid(gatewayOid, ifNum) && ifNum >= 0) return PString::Empty(); return snmp.GetInterfaceAddress(ifNum);}BOOL PIPSocket::GetRouteTable(RouteTable & table){ PWaitAndSignal m(GetSNMPMutex()); PWin32SnmpLibrary & snmp = snmp.Current(); table.RemoveAll(); PWin32AsnOid baseOid = "1.3.6.1.2.1.4.21.1"; PWin32AsnOid oid = baseOid; DWORD lastVariable = 1; PWin32AsnAny value; PLongArray ifNum; PINDEX idx = 0; while (snmp.GetNextOid(oid, value) && (baseOid *= oid)) { if (lastVariable != oid[9]) { lastVariable = oid[9]; if (lastVariable == 2) ifNum.SetSize(table.GetSize()); idx = 0; } switch (lastVariable) { case 1 : // network address { Address addr; if (!value.GetIpAddress(addr)) return FALSE; // Very confused route table table.Append(new RouteEntry(addr)); break; } case 2 : // device interface if (!value.GetInteger(ifNum[idx])) return FALSE; break; case 3 : // metric if (!value.GetInteger(table[idx].metric)) return FALSE; break; case 7 : // Get destination (next hop) if (!value.GetIpAddress(table[idx].destination)) return FALSE; break; case 11 : // Get mask if (!value.GetIpAddress(table[idx].net_mask)) return FALSE; break; } idx++; } for (idx = 0; idx < table.GetSize(); idx++) table[idx].interfaceName = snmp.GetInterfaceName(ifNum[idx]); return TRUE;}unsigned PIPSocket::AsNumeric(PIPSocket::Address addr) { return ((addr.Byte1() << 24) | (addr.Byte2() << 16) | (addr.Byte3() << 8) | addr.Byte4()); }PIPSocket::Address PIPSocket::GetRouteAddress(PIPSocket::Address RemoteAddress){Address localaddr; if (!RemoteAddress.IsRFC1918()) { // Remote Address is not Local if (!GetNetworkInterface(localaddr)) { // User not connected directly to Internet localaddr = GetGatewayInterfaceAddress(); // Get the default Gateway NIC address if ( localaddr != 0 ) // No connection to the Internet? return localaddr; } } else { PIPSocket::InterfaceTable interfaceTable; if (PIPSocket::GetInterfaceTable(interfaceTable)) { PINDEX i; for (i = 0; i < interfaceTable.GetSize(); ++i) { localaddr = interfaceTable[i].GetAddress(); if (!localaddr.IsLoopback() && localaddr.IsRFC1918()) { if (IsAddressReachable(localaddr, interfaceTable[i].GetNetMask(),RemoteAddress)) return localaddr; } } } } return 0;}BOOL PIPSocket::IsAddressReachable(PIPSocket::Address LocalIP, PIPSocket::Address LocalMask, PIPSocket::Address RemoteIP){ BYTE t = 255; int t1=t,t2=t,t3 =t,t4=t; int b1=0,b2=0,b3=0,b4=0; if ((int)LocalMask.Byte1() > 0) { t1 = LocalIP.Byte1() + (t-LocalMask.Byte1()); b1 = LocalIP.Byte1();} if ((int)LocalMask.Byte2() > 0) { t2 = LocalIP.Byte2() + (t-LocalMask.Byte2()); b2 = LocalIP.Byte2();} if ((int)LocalMask.Byte3() > 0) { t3 = LocalIP.Byte3() + (t-LocalMask.Byte3()); b3 = LocalIP.Byte3();} if ((int)LocalMask.Byte4() > 0) { t4 = LocalIP.Byte4() + (t-LocalMask.Byte4()); b4 = LocalIP.Byte4();} Address lt = Address((BYTE)t1,(BYTE)t2,(BYTE)t3,(BYTE)t4); Address lb = Address((BYTE)b1,(BYTE)b2,(BYTE)b3,(BYTE)b4); if (AsNumeric(RemoteIP) > AsNumeric(lb) && AsNumeric(lt) > AsNumeric(RemoteIP)) return TRUE; return FALSE;}PString PIPSocket::GetInterface(PIPSocket::Address addr){ PIPSocket::InterfaceTable if_table; if (PIPSocket::GetInterfaceTable( if_table ) ) { for (PINDEX i=0; i < if_table.GetSize(); i++) { PIPSocket::InterfaceEntry if_entry = if_table[i]; if (if_entry.GetAddress() == addr) return if_entry.GetName(); } } return PString();}BOOL PIPSocket::GetInterfaceTable(InterfaceTable & table){ PWin32SnmpLibrary & snmp = snmp.Current(); PWaitAndSignal m(GetSNMPMutex()); table.RemoveAll(); /* if (!snmp.IsLoaded()) { // Error loading the SNMP library, fail safe to using whatever the // address of the local host is. Address ipAddr; if (!GetHostAddress(ipAddr)) return FALSE; Address netMask(255,255,255,255); table.Append(new InterfaceEntry("FailSafe Interface", ipAddr, netMask, PString::Empty())); table.Append(new InterfaceEntry("localhost", PIPSocket::Address(), netMask, PString::Empty())); return TRUE; } */ PWin32AsnOid baseOid = "1.3.6.1.2.1.4.20.1"; PWin32AsnOid oid = baseOid; PWin32AsnAny value; while (snmp.GetNextOid(oid, value)) { if (!(baseOid *= oid)) break; if (value.asnType != ASN_IPADDRESS) break; Address ipAddr; value.GetIpAddress(ipAddr); oid[9] = 3; Address netMask; if (!snmp.GetOid(oid, netMask)) break; oid[9] = 2; AsnInteger ifIndex = -1; if (!snmp.GetOid(oid, ifIndex)) break; PString macAddr; PEthSocket::Address ifPhysAddress(""); PWin32AsnOid ifOid = "1.3.6.1.2.1.2.2.1.6.0"; ifOid[10] = ifIndex; UINT len; if (snmp.GetOid(ifOid, &ifPhysAddress, sizeof(ifPhysAddress), &len) && len > 0) macAddr = ifPhysAddress; PString name = snmp.GetInterfaceName(ipAddr); if (name.IsEmpty()) { PWin32AsnOid nameOid = "1.3.6.1.2.1.2.2.1.2.0"; nameOid[10] = ifIndex; if (!snmp.GetOid(nameOid, name)) break; name.MakeMinimumSize(); }#ifdef _WIN32_WCE // Getting rid of ghost ips if ( !name.IsEmpty() )#endif table.Append(new InterfaceEntry(name, ipAddr, netMask, macAddr)); oid[9] = 1; } return TRUE;}///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -