BOOL CBlueClickApp::GetHostMAC(CString &csMac) { NCB ncb; typedef struct _ASTAT_ { ADAPTER_STATUS adapt; NAME_BUFFER NameBuff [30]; }ASTAT, * PASTAT; ASTAT Adapter; typedef struct _LANA_ENUM { // le UCHAR length; UCHAR lana[MAX_LANA]; }LANA_ENUM ; LANA_ENUM lana_enum; UCHAR uRetCode; memset(&ncb, 0, sizeof(ncb)); memset(&lana_enum, 0, sizeof(lana_enum)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (unsigned char *)&lana_enum; ncb.ncb_length = sizeof(LANA_ENUM); uRetCode = Netbios(&ncb); if(uRetCode != NRC_GOODRET) return FALSE; for(int lana=0; lana<lana_enum.length; lana++) { ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = lana_enum.lana[lana]; uRetCode = Netbios(&ncb); if(uRetCode == NRC_GOODRET) break; } if(uRetCode != NRC_GOODRET) return FALSE; memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = lana_enum.lana[0]; strcpy((char*)ncb.ncb_callname, "*"); ncb.ncb_buffer = (unsigned char *)&Adapter; ncb.ncb_length = sizeof(Adapter); uRetCode = Netbios(&ncb); if(uRetCode != NRC_GOODRET) return FALSE; csMac.Format("%02X-%02X-%02X-%02X-%02X-%02X", Adapter.adapt.adapter_address[0], Adapter.adapt.adapter_address[1], Adapter.adapt.adapter_address[2], Adapter.adapt.adapter_address[3], Adapter.adapt.adapter_address[4], Adapter.adapt.adapter_address[5] ); return TRUE; }
//通过NetBIOS获取MAC地址 bool GetMacAddressByNetBIOS(std::string &mac_address) { ASTAT Adapter; NCB Ncb; UCHAR uRetCode; LANA_ENUM lenum; int i; memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (UCHAR *)&lenum; Ncb.ncb_length = sizeof(lenum); uRetCode = Netbios(&Ncb); for (i=0; i < lenum.length; ++i) { memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = lenum.lana[i]; uRetCode = Netbios(&Ncb); memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = lenum.lana[i]; strcpy((char *)Ncb.ncb_callname, "* "); Ncb.ncb_buffer = (unsigned char *)&Adapter; Ncb.ncb_length = sizeof(Adapter); uRetCode = Netbios(&Ncb); if (uRetCode == 0) { if (Adapter.adapt.adapter_address[0]+ Adapter.adapt.adapter_address[1]+ Adapter.adapt.adapter_address[2]+ Adapter.adapt.adapter_address[3]+ Adapter.adapt.adapter_address[4]+ Adapter.adapt.adapter_address[5]!=0) { StringPrintf(mac_address, "%02x-%02x-%02x-%02x-%02x-%02x", Adapter.adapt.adapter_address[0], Adapter.adapt.adapter_address[1], Adapter.adapt.adapter_address[2], Adapter.adapt.adapter_address[3], Adapter.adapt.adapter_address[4], Adapter.adapt.adapter_address[5]); return true; } } } return false; }
// // Function: Listen // // Description: // Post an asynchronous listen with a callback function. Create // an NCB structure for use by the callback (since it needs a // global scope). // int Listen(int lana, char *name) { PNCB pncb=NULL; pncb = (PNCB)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(NCB)); pncb->ncb_command = NCBLISTEN | ASYNCH; pncb->ncb_lana_num = lana; pncb->ncb_post = ListenCallback; // // This is the name clients will connect to // memset(pncb->ncb_name, ' ', NCBNAMSZ); strncpy(pncb->ncb_name, name, strlen(name)); // // An '*' means we'll take a client connection from anyone. By // specifying an actual name here you restrict connections to // clients with that name only. // memset(pncb->ncb_callname, ' ', NCBNAMSZ); pncb->ncb_callname[0] = '*'; if (Netbios(pncb) != NRC_GOODRET) { printf("ERROR: Netbios: NCBLISTEN: %d\n", pncb->ncb_retcode); return pncb->ncb_retcode; } return NRC_GOODRET; }
int __GetMAC(LPMAC_ADDRESS pMacAddr) { NCB ncb; UCHAR uRetCode; int num = 0; LANA_ENUM lana_enum; memset(&ncb, 0, sizeof(ncb) ); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (unsigned char *)&lana_enum; ncb.ncb_length = sizeof(lana_enum); ////向网卡发送NCBENUM命令,以获取当前机器的网卡信息,如有多少个网卡 ////每张网卡的编号等 uRetCode = Netbios(&ncb); if (uRetCode == 0) { num = lana_enum.length; //对每一张网卡,以其网卡编号为输入编号,获取其MAC地址 for (int i = 0; i < num; i++) { ASTAT Adapter; if(__GetAddressByIndex(lana_enum.lana[i],Adapter) == 0) { pMacAddr[i].b1 = Adapter.adapt.adapter_address[0]; pMacAddr[i].b2 = Adapter.adapt.adapter_address[1]; pMacAddr[i].b3 = Adapter.adapt.adapter_address[2]; pMacAddr[i].b4 = Adapter.adapt.adapter_address[3]; pMacAddr[i].b5 = Adapter.adapt.adapter_address[4]; pMacAddr[i].b6 = Adapter.adapt.adapter_address[5]; } } } return num; }
extern "C" lana_number_t lana_FindLoopback(void) { NCB ncb; LANA_ENUM lana_list; int status; int i; memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (UCHAR *) &lana_list; ncb.ncb_length = sizeof(lana_list); status = Netbios(&ncb); if (status != 0) { #ifndef NOLOGGING afsi_log("Netbios NCBENUM failed: status %ld", status); #endif return LANA_INVALID; } for (i = 0; i < lana_list.length; i++) { if (lana_IsLoopback(lana_list.lana[i],TRUE)) { // Found one, return it. #ifndef NOLOGGING afsi_log("lana_FindLoopback: Found LAN adapter %d", lana_list.lana[i]); #endif return lana_list.lana[i]; } } // Could not find a loopback adapter. return LANA_INVALID; }
/* Returns TRUE if all adapters are loopback adapters */ extern "C" BOOL lana_OnlyLoopback(void) { NCB ncb; LANA_ENUM lana_list; int status; int i; memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (UCHAR *) &lana_list; ncb.ncb_length = sizeof(lana_list); status = Netbios(&ncb); if (status != 0) { #ifndef NOLOGGING afsi_log("Netbios NCBENUM failed: status %ld", status); #endif return FALSE; } for (i = 0; i < lana_list.length; i++) { if (!lana_IsLoopback(lana_list.lana[i],FALSE)) { // Found one non-Loopback adapter return FALSE; } } // All adapters are loopback return TRUE; }
int CIRC::GetMACFromLanCard(int iLanCard, char *szMAC) { ResetNetBios(iLanCard); NCB nbCmd; ADAPTER_STATUS asStatus; nbCmd.ncb_command = NCBASTAT; nbCmd.ncb_lana_num = iLanCard; nbCmd.ncb_callname[0]='*'; nbCmd.ncb_callname[1]='\0'; nbCmd.ncb_length = sizeof(ADAPTER_STATUS); nbCmd.ncb_buffer = (unsigned char *)&asStatus; Netbios(&nbCmd); if(nbCmd.ncb_retcode==0) { sprintf(szMAC, " %0.2X-%0.2X-%0.2X-%0.2X-%0.2X-%0.2X", asStatus.adapter_address[0], asStatus.adapter_address[1], asStatus.adapter_address[2], asStatus.adapter_address[3], asStatus.adapter_address[4], asStatus.adapter_address[5]); return 0; } else { return -1; } }
std::string GetNetBiosMacAddresses() { NCB ncb; UCHAR uRetCode; LANA_ENUM lana_enum; memset( &ncb, 0, sizeof( ncb ) ); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (unsigned char *) &lana_enum; ncb.ncb_length = sizeof( lana_enum ); uRetCode = Netbios( &ncb ); //printf( "The NCBENUM return code is:0x%x \n", uRetCode ); std::string vAdd; if ( uRetCode == 0 ) { //printf( "Ethernet Count is : %d\n\n", lana_enum.length); for ( int i=0; i < lana_enum.length; ++i ) { std::string s = getmac_one( lana_enum.lana[i] ); if( ! s.empty() ) { vAdd.append( s ); } } } return vAdd; }
// // Function: LanaStatus // // Description: // Perform a LAN adapter status command. // int LanaStatus(int lana, char *name) { NCB ncb; MESSAGE_BUFFER mb; ZeroMemory(&mb, sizeof(MESSAGE_BUFFER)); ZeroMemory(&ncb, sizeof(NCB)); memset(ncb.ncb_callname, ' ', NCBNAMSZ); // // Check command line options to see if the call is // made locally or remotely. // if ((bLocalName == FALSE) && (bRemoteName == FALSE)) ncb.ncb_callname[0] = '*'; else strncpy(ncb.ncb_callname, name, strlen(name)); ncb.ncb_command = NCBASTAT; ncb.ncb_buffer = (UCHAR *)&mb; ncb.ncb_length = sizeof(MESSAGE_BUFFER); ncb.ncb_lana_num= lana; if (Netbios(&ncb) != NRC_GOODRET) { printf("Netbios: NCBASTAT failed: %d\n", ncb.ncb_retcode); return ncb.ncb_retcode; } PrintAdapterInfo(lana, mb.adapter); PrintNameInfo(mb.names, mb.adapter.name_count); return NRC_GOODRET; }
CString GetMacAddress(CString sNetBiosName) { ASTAT Adapter; NCB ncb; UCHAR uRetCode; memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = 0; uRetCode = Netbios(&ncb); memset(&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = 0; sNetBiosName.MakeUpper(); FillMemory(ncb.ncb_callname, NCBNAMSZ - 1, 0x20); strcpy((char *)ncb.ncb_callname, (LPCTSTR) sNetBiosName); ncb.ncb_callname[sNetBiosName.GetLength()] = 0x20; ncb.ncb_callname[NCBNAMSZ] = 0x0; ncb.ncb_buffer = (unsigned char *) &Adapter; ncb.ncb_length = sizeof(Adapter); uRetCode = Netbios(&ncb); CString sMacAddress; if (uRetCode == 0) { sMacAddress.Format(_T("%02x%02x%02x%02x%02x%02x"), Adapter.adapt.adapter_address[0], Adapter.adapt.adapter_address[1], Adapter.adapt.adapter_address[2], Adapter.adapt.adapter_address[3], Adapter.adapt.adapter_address[4], Adapter.adapt.adapter_address[5]); } return sMacAddress; }
// // Function: ClientThread // // Description: // This thread takes the NCB structure of a connected session // and waits for incoming data which it then sends back to the // client until the session is closed. // DWORD WINAPI ClientThread(PVOID lpParam) { PNCB pncb = (PNCB)lpParam; NCB ncb; char szRecvBuff[MAX_BUFFER], szClientName[NCBNAMSZ + 1]; DWORD dwBufferLen = MAX_BUFFER, dwRetVal = NRC_GOODRET; // Send and receive messages until the session is closed // FormatNetbiosName(pncb->ncb_callname, szClientName); while (1) { dwBufferLen = MAX_BUFFER; dwRetVal = Recv(pncb->ncb_lana_num, pncb->ncb_lsn, szRecvBuff, &dwBufferLen); if (dwRetVal != NRC_GOODRET) break; szRecvBuff[dwBufferLen] = 0; printf("READ [LANA=%d]: '%s'\n", pncb->ncb_lana_num, szRecvBuff); dwRetVal = Send(pncb->ncb_lana_num, pncb->ncb_lsn, szRecvBuff, dwBufferLen); if (dwRetVal != NRC_GOODRET) break; } printf("Client '%s' on LANA %d disconnected\n", szClientName, pncb->ncb_lana_num); // // If the error returned from a read or write is NRC_SCLOSED then // all is well; otherwise some other error occured so hangup the // connection from this side. // if (dwRetVal != NRC_SCLOSED) { ZeroMemory(&ncb, sizeof(NCB)); ncb.ncb_command = NCBHANGUP; ncb.ncb_lsn = pncb->ncb_lsn; ncb.ncb_lana_num = pncb->ncb_lana_num; if (Netbios(&ncb) != NRC_GOODRET) { printf("ERROR: Netbios: NCBHANGUP: %d\n", ncb.ncb_retcode); GlobalFree(pncb); dwRetVal = ncb.ncb_retcode; } } // The NCB structure passed in is dynamically allocated it so // delete it before we go. // GlobalFree(pncb); return NRC_GOODRET; }
std::string getmac_one( int lana_num ) { NCB ncb; UCHAR uRetCode; memset( &ncb, 0, sizeof( ncb ) ); ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = lana_num; uRetCode = Netbios( &ncb ); //printf( "The NCBRESET return code is:0x%x \n", uRetCode ); memset( &ncb, 0, sizeof( ncb ) ); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = lana_num; strcpy( (char *)ncb.ncb_callname, "* " ); ncb.ncb_buffer = ( unsigned char * ) &Adapter; ncb.ncb_length = sizeof( Adapter ); uRetCode = Netbios( &ncb ); // printf( "The NCBASTAT return code is: 0x%x \n", uRetCode ); std::string s; if ( uRetCode == 0 ) { int bAddressInt [ MACSESION ]; char CommarSeperatedAddress[ MACSESION * 3 ]={0}; for( int i = 0; i < MACSESION; ++i ) { bAddressInt[ i ] = Adapter.adapt.adapter_address[ i ]; bAddressInt[ i ] &= 0x000000ff; // avoid "ff" leading bytes when "char" is lager then 0x7f } sprintf( CommarSeperatedAddress, "%02x:%02x:%02x:%02x:%02x:%02x", bAddressInt[ 0 ], bAddressInt[ 1 ], bAddressInt[ 2 ], bAddressInt[ 3 ], bAddressInt[ 4 ], bAddressInt[ 5 ]); // Should use scl::FormatString inside s = CommarSeperatedAddress; } return s; }
void CIRC::ResetNetBios(int iLanCard) { NCB nbCmd; nbCmd.ncb_lana_num = iLanCard; nbCmd.ncb_command = NCBRESET; nbCmd.ncb_lsn = 0; Netbios(&nbCmd); }
UCHAR __GetAddressByIndex(int lana_num, ASTAT &Adapter) { NCB ncb; UCHAR uRetCode; memset(&ncb, 0, sizeof(ncb) ); ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = lana_num; //指定网卡号,首先对选定的网卡发送一个NCBRESET命令,以便进行初始化 uRetCode = Netbios(&ncb ); memset(&ncb, 0, sizeof(ncb) ); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = lana_num; //指定网卡号 strcpy((char *)ncb.ncb_callname,"* " ); ncb.ncb_buffer = (unsigned char *)&Adapter; //指定返回的信息存放的变量 ncb.ncb_length = sizeof(Adapter); //接着,可以发送NCBASTAT命令以获取网卡的信息 uRetCode = Netbios(&ncb ); return uRetCode; }
// 向本地名字表中添加名字 BOOL NBAddName (int nLana, LPCSTR szName) { NCB ncb; memset (&ncb, 0, sizeof (ncb)); // 清空ncb结构体 ncb.ncb_command = NCBADDNAME; // 执行NCBDDNAME命令,向本地名字表中添加一个唯一的名字 ncb.ncb_lana_num = nLana; // 设置lana_num资源,指定本地网络名字编号。 MakeNetbiosName ((char*) ncb.ncb_name, szName); // 将szName赋值到ncb.ncb_name中 Netbios (&ncb); // 执行NCBRESET命令 NBCheck (ncb); // 如果执行结果不正确,则输出ncb.ncb_retcode // 如果成功返回TRUE,否则返回FALSE return (NRC_GOODRET == ncb.ncb_retcode); }
void __stdcall getMacAddress(char *macAddr) { int lana_num = 6; NCB ncb; UCHAR uRetCode; // ASTAT adapter; // memset( &ncb, 0, sizeof(ncb) ); ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = lana_num; // uRetCode = Netbios( &ncb ); // memset( &ncb, 0, sizeof(ncb) ); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = lana_num; // // strcpy( (char *)ncb.ncb_callname, "*" ); memset( &adapter, 0, sizeof(adapter) ); ncb.ncb_buffer = (unsigned char *) &adapter; // // ncb.ncb_length = sizeof(adapter); // uRetCode = Netbios( &ncb ); // if ( uRetCode == 0 ) { // 00-10-A4-E4-58-02 wsprintf( macAddr, "%02X-%02X-%02X-%02X-%02X-%02X", int(adapter.adapt.adapter_address[0]), adapter.adapt.adapter_address[1],adapter.adapt.adapter_address[2], adapter.adapt.adapter_address[3],adapter.adapt.adapter_address[4], adapter.adapt.adapter_address[5]); } }
// // Function: ClientThread // // Description: // The client thread blocks for data sent from clients and // simply sends it back to them. This is a continuous loop // until the sessions is closed or an error occurs. If // the read or write fails with NRC_SCLOSED then the session // has closed gracefully so exit the loop. // DWORD WINAPI ClientThread(PVOID lpParam) { PNCB pncb = (PNCB)lpParam; NCB ncb; char szRecvBuff[MAX_BUFFER]; DWORD dwBufferLen=MAX_BUFFER, dwRetVal=NRC_GOODRET; char szClientName[NCBNAMSZ+1]; FormatNetbiosName(pncb->ncb_callname, szClientName); while (1) { dwBufferLen = MAX_BUFFER; dwRetVal = Recv(pncb->ncb_lana_num, pncb->ncb_lsn, szRecvBuff, &dwBufferLen); if (dwRetVal != NRC_GOODRET) break; szRecvBuff[dwBufferLen] = 0; printf("READ [LANA=%d]: '%s'\n", pncb->ncb_lana_num, szRecvBuff); dwRetVal = Send(pncb->ncb_lana_num, pncb->ncb_lsn, szRecvBuff, dwBufferLen); if (dwRetVal != NRC_GOODRET) break; } printf("Client '%s' on LANA %d disconnected\n", szClientName, pncb->ncb_lana_num); if (dwRetVal != NRC_SCLOSED) { // Some other error occured, hang up the connection // ZeroMemory(&ncb, sizeof(NCB)); ncb.ncb_command = NCBHANGUP; ncb.ncb_lsn = pncb->ncb_lsn; ncb.ncb_lana_num = pncb->ncb_lana_num; if (Netbios(&ncb) != NRC_GOODRET) { printf("ERROR: Netbios: NCBHANGUP: %d\n", ncb.ncb_retcode); dwRetVal = ncb.ncb_retcode; } GlobalFree(pncb); return dwRetVal; } GlobalFree(pncb); return NRC_GOODRET; }
// 清空本地名字和会话表 BOOL NBReset (int nLana, int nSessions, int nNames) { NCB ncb; memset (&ncb, 0, sizeof (ncb)); // 清空ncb结构体 ncb.ncb_command = NCBRESET; // 执行NCBRESET命令,复位局域网网络适配器,清空指定LANA编号上定义的本地名字表和会话表。 ncb.ncb_lsn = 0; // 分配新的lana_num资源,Netbios()函数成功执行了NCBCALL命令后返回的编号 ncb.ncb_lana_num = nLana; // 设置lana_num资源,指定本地网络名字编号。 ncb.ncb_callname[0] = nSessions; // 设置最大会话数 ncb.ncb_callname[2] = nNames; // 设置最大名字数 Netbios (&ncb); // 执行NCBRESET命令 NBCheck (ncb); // 如果执行结果不正确,则输出ncb.ncb_retcode // 如果成功返回TRUE,否则返回FALSE return (NRC_GOODRET == ncb.ncb_retcode); }
// @pymethod int|win32wnet|Netbios|Executes a Netbios call. PyObject * PyWinMethod_Netbios(PyObject *self, PyObject *args) { PyObject *obncb; // @pyparm <o NCB>|ncb||The NCB object to use for the call. if (!PyArg_ParseTuple(args, "O!:Netbios", &PyNCBType, &obncb)) return NULL; PyNCB *pyncb = (PyNCB *)obncb; UCHAR rc; Py_BEGIN_ALLOW_THREADS rc = Netbios(&pyncb->m_ncb); Py_END_ALLOW_THREADS return PyInt_FromLong((long)rc); }
// 获取指定LANA的网络适配器信息 // nLana, LANA编号 // pBuffer, 获取到的网络适配器缓冲区 // cbBuffer, 缓冲区长度 // szName, 主机名字 BOOL NBAdapterStatus (int nLana, PVOID pBuffer, int cbBuffer, LPCSTR szName) { NCB ncb; memset (&ncb, 0, sizeof (ncb)); // 清空ncb结构体 ncb.ncb_command = NCBASTAT; // 设置执行NCBASTAT命令,获取本地或远程网络适配器的状态 ncb.ncb_lana_num = nLana; // 设置LANA编号 ncb.ncb_buffer = (PUCHAR) pBuffer; // 将获取到的数据保存到参数pBuffer中 ncb.ncb_length = cbBuffer; // 设置缓冲区长度 MakeNetbiosName ((char*) ncb.ncb_callname, szName);// 设置参数ncb.ncb_callname Netbios (&ncb); // 执行NetBIOS命令 NBCheck (ncb); // 如果执行不成功,则输出返回值 // 如果成功返回TRUE,否则返回FALSE return (NRC_GOODRET == ncb.ncb_retcode); }
/* ** Name: GClanman_exit ** Description: ** ** ** History: ** 13-Apr-2010 (Bruce Lunsford) Sir 122679 ** Change return value from VOID to STATUS and add PCT entry ** as input parm, since caller expects it. ** */ STATUS GClanman_exit(GCC_PCE * pptr) { if ( In_Shutdown ) return OK; In_Shutdown = TRUE; memset( &Name_Ncb, 0, sizeof( NCB ) ); Name_Ncb.ncb_command = NCBDELNAME; STcopy( GCc_listen_port, Name_Ncb.ncb_name ); Name_Ncb.ncb_lana_num = lana_num; (void) Netbios( &Name_Ncb ); return OK; }
int __stdcall getAdapterNum() { NCB ncb; UCHAR uRetCode; LANA_ENUM lana_enum; memset( &ncb, 0, sizeof(ncb) ); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (unsigned char *) &lana_enum; ncb.ncb_length = sizeof(lana_enum); uRetCode = Netbios( &ncb ); if ( uRetCode == 0 ) return lana_enum.length; else return 0; }
void CIRC::GetMacOfAllCards(void) { NCB nbCmd; LANA_ENUM leCards; char szTemp[50]=""; nbCmd.ncb_command = NCBENUM; nbCmd.ncb_length = sizeof(LANA_ENUM); nbCmd.ncb_buffer = (unsigned char *)&leCards; Netbios(&nbCmd); SendMessage("Start of MAC listing"); for(int i=0; i<leCards.length; i++) { GetMACFromLanCard(leCards.lana[i], szTemp); SendMessage(szTemp); } SendMessage("End of MAC listing"); }
// // Function: Listen // // Description: // Post an asynchronous listen on the given LANA number. // The NCB structure passed in already has its ncb_event // field set to a valid Windows event handle. // int Listen(PNCB pncb, int lana, char *name) { pncb->ncb_command = NCBLISTEN | ASYNCH; pncb->ncb_lana_num = lana; // // This is the name clients will connect to // memset(pncb->ncb_name, ' ', NCBNAMSZ); strncpy(pncb->ncb_name, name, strlen(name)); // // An '*' means we'll accept connections from anyone. // You could specify a specific name which means only a // client with the specified name will be allowed to connect. // memset(pncb->ncb_callname, ' ', NCBNAMSZ); pncb->ncb_callname[0] = '*'; if (Netbios(pncb) != NRC_GOODRET) { printf("ERROR: Netbios: NCBLISTEN: %d\n", pncb->ncb_retcode); return pncb->ncb_retcode; } return NRC_GOODRET; }
ACE_BEGIN_VERSIONED_NAMESPACE_DECL int ACE_OS::getmacaddress (struct macaddr_node_t *node) { ACE_OS_TRACE ("ACE_OS::getmacaddress"); #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) # if !defined (ACE_HAS_PHARLAP) /** Define a structure for use with the netbios routine */ struct ADAPTERSTAT { ADAPTER_STATUS adapt; NAME_BUFFER NameBuff [30]; }; NCB ncb; LANA_ENUM lenum; unsigned char result; ACE_OS::memset (&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = reinterpret_cast<unsigned char*> (&lenum); ncb.ncb_length = sizeof(lenum); result = Netbios (&ncb); for(int i = 0; i < lenum.length; i++) { ACE_OS::memset (&ncb, 0, sizeof(ncb)); ncb.ncb_command = NCBRESET; ncb.ncb_lana_num = lenum.lana [i]; /** Reset the netbios */ result = Netbios (&ncb); if (ncb.ncb_retcode != NRC_GOODRET) { return -1; } ADAPTERSTAT adapter; ACE_OS::memset (&ncb, 0, sizeof (ncb)); ACE_OS::strcpy (reinterpret_cast<char*> (ncb.ncb_callname), "*"); ncb.ncb_command = NCBASTAT; ncb.ncb_lana_num = lenum.lana[i]; ncb.ncb_buffer = reinterpret_cast<unsigned char*> (&adapter); ncb.ncb_length = sizeof (adapter); result = Netbios (&ncb); if (result == 0) { ACE_OS::memcpy (node->node, adapter.adapt.adapter_address, 6); return 0; } } return 0; # else # if defined (ACE_HAS_PHARLAP_RT) DEVHANDLE ip_dev = (DEVHANDLE)0; EK_TCPIPCFG *devp = 0; size_t i; ACE_TCHAR dev_name[16]; for (i = 0; i < 10; i++) { // Ethernet. ACE_OS::sprintf (dev_name, "ether%d", i); ip_dev = EtsTCPGetDeviceHandle (dev_name); if (ip_dev != 0) break; } if (ip_dev == 0) return -1; devp = EtsTCPGetDeviceCfg (ip_dev); if (devp == 0) return -1; ACE_OS::memcpy (node->node, &devp->EthernetAddress[0], 6); return 0; # else ACE_UNUSED_ARG (node); ACE_NOTSUP_RETURN (-1); # endif /* ACE_HAS_PHARLAP_RT */ # endif /* ACE_HAS_PHARLAP */ #elif defined (sun) /** obtain the local host name */ char hostname [MAXHOSTNAMELEN]; ACE_OS::hostname (hostname, sizeof (hostname)); /** Get the hostent to use with ioctl */ struct hostent *phost = ACE_OS::gethostbyname (hostname); if (phost == 0) return -1; ACE_HANDLE handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (handle == ACE_INVALID_HANDLE) return -1; char **paddrs = phost->h_addr_list; struct arpreq ar; struct sockaddr_in *psa = (struct sockaddr_in *)&(ar.arp_pa); ACE_OS::memset (&ar, 0, sizeof (struct arpreq)); psa->sin_family = AF_INET; ACE_OS::memcpy (&(psa->sin_addr), *paddrs, sizeof (struct in_addr)); if (ACE_OS::ioctl (handle, SIOCGARP, &ar) == -1) { ACE_OS::close (handle); return -1; } ACE_OS::close (handle); ACE_OS::memcpy (node->node, ar.arp_ha.sa_data, 6); return 0; #elif defined (ACE_LINUX) && !defined (ACE_LACKS_NETWORKING) // It's easiest to know the first MAC-using interface. Use the BSD // getifaddrs function that simplifies access to connected interfaces. struct ifaddrs *ifap = 0; struct ifaddrs *p_if = 0; if (::getifaddrs (&ifap) != 0) return -1; for (p_if = ifap; p_if != 0; p_if = p_if->ifa_next) { if (p_if->ifa_addr == 0) continue; // Check to see if it's up and is not either PPP or loopback if ((p_if->ifa_flags & IFF_UP) == IFF_UP && (p_if->ifa_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0) break; } if (p_if == 0) { errno = ENODEV; ::freeifaddrs (ifap); return -1; } struct ifreq ifr; ACE_OS::strcpy (ifr.ifr_name, p_if->ifa_name); ::freeifaddrs (ifap); ACE_HANDLE handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0); if (handle == ACE_INVALID_HANDLE) return -1; if (ACE_OS::ioctl (handle/*s*/, SIOCGIFHWADDR, &ifr) < 0) { ACE_OS::close (handle); return -1; } struct sockaddr* sa = (struct sockaddr *) &ifr.ifr_addr; ACE_OS::close (handle); ACE_OS::memcpy (node->node, sa->sa_data, 6); return 0; #elif defined (ACE_HAS_SIOCGIFCONF) const long BUFFERSIZE = 4000; char buffer[BUFFERSIZE]; struct ifconf ifc; struct ifreq* ifr = 0; ACE_HANDLE handle = ACE_OS::socket (AF_INET, SOCK_DGRAM, 0); if (handle == ACE_INVALID_HANDLE) { return -1; } ifc.ifc_len = BUFFERSIZE; ifc.ifc_buf = buffer; if (ACE_OS::ioctl (handle, SIOCGIFCONF, &ifc) < 0) { ACE_OS::close (handle); return -1; } for(char* ptr=buffer; ptr < buffer + ifc.ifc_len; ) { ifr = (struct ifreq *) ptr; if (ifr->ifr_addr.sa_family == AF_LINK) { if(ACE_OS::strcmp (ifr->ifr_name, "en0") == 0) { struct sockaddr_dl* sdl = (struct sockaddr_dl *) &ifr->ifr_addr; ACE_OS::memcpy (node->node, LLADDR(sdl), 6); } } ptr += sizeof(ifr->ifr_name); if(sizeof(ifr->ifr_addr) > ifr->ifr_addr.sa_len) ptr += sizeof(ifr->ifr_addr); else ptr += ifr->ifr_addr.sa_len; } ACE_OS::close (handle); return 0; #else ACE_UNUSED_ARG (node); ACE_NOTSUP_RETURN (-1); #endif }
/* * Class: com_gemstone_gemfire_internal_SmHelper * Method: _getSystemId * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_gemstone_gemfire_internal_SmHelper__1getSystemId (JNIEnv *env, jclass klass) { unsigned char macAddr[6]; const char* id; char idbuff[256]; #ifdef FLG_UNIX #if defined(FLG_SOLARIS_UNIX) char provider[64]; char serial[64]; #if 0 const char* pNIC = "hme0"; // ethernet card device name // get mac-address memset(macAddr, 0, sizeof(macAddr)); int fdesc = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (fdesc != -1) { struct ifreq req; strcpy(req.ifr_name, pNIC); int err = ioctl(fdesc, SIOCGIFADDR, &req ); if (err != -1) { memcpy(macAddr, req.ifr_addr.sa_data, sizeof(macAddr)); } close(fdesc); } #endif char name[MAXHOSTNAMELEN]; memset(macAddr, 0, sizeof(macAddr)); if (gethostname(name, sizeof(name)) == 0) { struct hostent *phost; struct hostent hostentBuf; char hbuf[512]; int herr; phost = gethostbyname_r(name, &hostentBuf, hbuf, sizeof(hbuf), &herr); if (phost != 0) { int s; s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s != -1) { char **paddrs; struct arpreq ar; struct sockaddr_in * psa; paddrs = phost->h_addr_list; psa = ( struct sockaddr_in * )&( ar.arp_pa ); memset( &ar, 0, sizeof( struct arpreq ) ); psa->sin_family = AF_INET; memcpy( &( psa->sin_addr ), *paddrs, sizeof( struct in_addr ) ); if ( ioctl( s, SIOCGARP, &ar ) != -1 ) { int i; for (i = 0; i < 6; i++) { macAddr[i] = ar.arp_ha.sa_data[i]; } } close(s); } } } sysinfo(SI_HW_PROVIDER, provider, 64); sysinfo(SI_HW_SERIAL, serial, 64); sprintf(idbuff, "%lx %s-%s %02x-%02x-%02x-%02x-%02x-%02x", gethostid(), provider, serial, macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); #elif defined(FLG_OSX_UNIX) const char* pNIC = "en0"; // get mac-address memset(macAddr, 0, sizeof(macAddr)); size_t len; char *buf; struct if_msghdr *ifm; struct sockaddr_dl *sdl; int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0}; mib[5] = if_nametoindex(pNIC); UTL_ASSERT(mib[5] != 0); sysctl(mib, 6, NULL, &len, NULL, 0); buf = (char*)UtlMalloc(len, "OBTAIN MAC ADDRESS"); sysctl(mib, 6, buf, &len, NULL, 0); #ifdef X86_64 //The following code will have issues on 64bit Mac OS X +++ error #endif ifm = (struct if_msghdr *)buf; sdl = (struct sockaddr_dl *)(ifm + 1); memcpy(macAddr, (unsigned char *)LLADDR(sdl), sizeof(macAddr)); sprintf(idbuff, "%02x-%02x-%02x-%02x-%02x-%02x", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); #else const char* pNIC = "eth0"; // get mac-address memset(macAddr, 0, sizeof(macAddr)); int fdesc = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (fdesc != -1) { struct ifreq req; strcpy(req.ifr_name, pNIC); int err = ioctl(fdesc, SIOCGIFHWADDR, &req ); if (err != -1) { int i; struct sockaddr* sa = (struct sockaddr *) &req.ifr_addr; for (i = 0; i < 6; i++) { macAddr[i] = sa->sa_data[i]; } } close(fdesc); } sprintf(idbuff, "%02x-%02x-%02x-%02x-%02x-%02x", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); #endif #else /* windows */ DWORD serialNumber = 0; DWORD maxDirLength; DWORD flags; if (GetVolumeInformation("c:\\", NULL, 0, &serialNumber, &maxDirLength, &flags, NULL, 0)) { } { int lana_num = -1; /* LAN adapter number */ struct ASTAT { ADAPTER_STATUS adapt; NAME_BUFFER NameBuff[30]; } Adapter; NCB Ncb; { LANA_ENUM lenum; UCHAR uRetCode; int li = 0; memset(&Ncb,0,sizeof(Ncb)); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (UCHAR*)&lenum; Ncb.ncb_length = sizeof(lenum); uRetCode = Netbios(&Ncb); if (uRetCode != 0) return JNI_FALSE; for (; li < lenum.length; li++) { lana_num = lenum.lana[li]; /* prepare to get adapter status block */ memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = lana_num; if (Netbios(&Ncb) != NRC_GOODRET) continue; /* OK, lets go fetch ethernet address */ memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = lana_num; strcpy((char *) Ncb.ncb_callname, "*"); memset(&Adapter, 0, sizeof(Adapter)); Ncb.ncb_buffer = (unsigned char *)&Adapter; Ncb.ncb_length = sizeof(Adapter); /* if unable to determine, exit false */ if (Netbios(&Ncb) != 0) continue; /* if correct type, then see if its the one we want to check */ if ((Adapter.adapt.adapter_type & 0xff) == 0xfe) { int i; for (i = 0; i < 6; i++) { macAddr[i] = Adapter.adapt.adapter_address[i]; } break; } } } } sprintf(idbuff, "%lx %02x-%02x-%02x-%02x-%02x-%02x", serialNumber, macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); #endif id = idbuff; return (*env)->NewStringUTF(env, id); }
/* ** Name: GClanman_async_thread ** Description: ** This thread handles all the asynchronous I/O for a protocol driver. ** It will be woken up when GClanman() places a request on it's input ** Q. Then, this thread will move the request from the input Q to its ** processing Q and continue to process the request until complete. ** When complete, the request is finally moved to the completion ** Q. ** History: ** 04-Nov-93 (edg) ** Written. ** 29-jun-2000 (somsa01) ** Use GCc_listen_port for the server ncb_name. Also, make sure ** that we update GCc_client_name if we need a unique one. ** 06-Aug-2009 (Bruce Lunsford) Sir 122426 ** Since _beginthreadex() is now used to start this thread, ** use _endthreadex() to end it. */ VOID GClanman_async_thread( VOID * parms) { int status = OK; char callname[NCBNAMSZ+1]; DWORD wait_stat; HANDLE hSave; int processing_requests = 0; int pending_requests = 0; QUEUE *q; SECURITY_ATTRIBUTES sa; iimksec (&sa); GCTRACE(4)("LMAN THREAD: started.\n"); top: /* ** Wait for a request to come in from the primary gcc thread.... */ GCTRACE(4)("LMAN THREAD: waiting for event ... \n"); wait_stat = WaitForSingleObject( hEventThreadInQ, INFINITE ); GCTRACE(3)("LMAN THREAD: wait returned %d, handle = %d\n", wait_stat, hEventThreadInQ ); /* ** If wait failed, chances are it's a major hosure. Continue on any ** way -- there's a possibility that something useful may get done. */ if (wait_stat == WAIT_FAILED) { GCTRACE(1)("LMAN THREAD: wait failed %d\n", GetLastError() ); } /* ** Now get get the incoming requests and add up how many requests ** we're processing. */ processing_requests = GCget_incoming_reqs( Tptr, hMutexThreadInQ ); GCTRACE(2)("LMAN THREAD: Got %d new requests to process\n", processing_requests); /* ** Loop until there's no more requests being processed. */ while( processing_requests ) { pending_requests = 0; /* ** Now loop thru the inprocess request list. */ for ( q = Tptr->process_head.q_next; q != &Tptr->process_head; q = q->q_next ) { REQUEST_Q *rq = (REQUEST_Q *)q; GCC_P_PLIST *parm_list = rq->plist; PCB *pcb = (PCB *)parm_list->pcb; parm_list->generic_status = OK; CLEAR_ERR(&parm_list->system_status); switch (parm_list->function_invoked) { /****************************************************** ** Handle CONNECT *******************************************************/ case GCC_CONNECT: GCTRACE(4)("LMAN THREAD: process CONNECT\n"); if ( pcb == NULL || pcb->state.conn == INITIAL ) { GCTRACE(3)("LMAN THREAD: initial CONNECT\n"); /* ** Allocate the protocol control block. */ pcb = (PCB *) malloc( sizeof(PCB) ); parm_list->pcb = (char *)pcb; if (pcb == NULL) { status = errno; SETWIN32ERR(&parm_list->system_status, status, ER_alloc); pcb->state.conn = COMPLETED; parm_list->generic_status = GC_CONNECT_FAIL; break; } memset( pcb, 0, sizeof( *pcb ) ); GCTRACE(3)("LMAN THREAD: CONNECT allocated pcb\n"); /* ** Create send/recv event handles for ncb. */ if ((pcb->s_ncb.ncb_event = CreateEvent( &sa, TRUE, FALSE, NULL ))== NULL) { status = GetLastError(); pcb->state.conn = COMPLETED; SETWIN32ERR(&parm_list->system_status, status, ER_create); parm_list->generic_status = GC_CONNECT_FAIL; break; } if ((pcb->r_ncb.ncb_event = CreateEvent( &sa, TRUE, FALSE, NULL ))== NULL) { status = GetLastError(); CloseHandle( pcb->s_ncb.ncb_event ); pcb->state.conn = COMPLETED; SETWIN32ERR(&parm_list->system_status, status, ER_create); parm_list->generic_status = GC_CONNECT_FAIL; break; } GCTRACE(3)("LMAN THREAD: CONNECT created events\n"); pcb->state.conn = INITIAL; } /* end if pcb NULL */ /* ** If the PCB state is not INITIAL, just break because ** we're just waiting for connect to complete. */ if ( pcb->state.conn != INITIAL ) break; /* ** Use the send ncb in pcb for the connect -- add name. */ pcb->s_ncb.ncb_command = NCBADDNAME; pcb->s_ncb.ncb_buffer = Dummy_Buf; pcb->s_ncb.ncb_length = sizeof(Dummy_Buf); pcb->s_ncb.ncb_lana_num = lana_num; for (;;) { STprintf( GCc_client_name, "%s%-d", MyName, GCc_client_count++ ); STcopy( GCc_client_name, pcb->s_ncb.ncb_name ); GCTRACE(3)("LMAN THREAD: CONNECT doing ADDNAME %s\n", pcb->s_ncb.ncb_name ); /* ** Copy to local NCB struct -- Netbios seems to fark ** up if we don't. */ memcpy( &Name_Ncb, &pcb->s_ncb, sizeof( Name_Ncb ) ); Netbios( &Name_Ncb ); if (Name_Ncb.ncb_retcode == NRC_GOODRET) break; else if (Name_Ncb.ncb_retcode == NRC_DUPNAME) continue; else { status = (STATUS)Name_Ncb.ncb_retcode; CloseHandle( Name_Ncb.ncb_event ); pcb->s_ncb.ncb_event = NULL; CloseHandle( pcb->r_ncb.ncb_event ); pcb->r_ncb.ncb_event = NULL; pcb->state.conn = COMPLETED; SETWIN32ERR(&parm_list->system_status, status, ER_netbios); parm_list->generic_status = GC_CONNECT_FAIL; break; } } if (parm_list->generic_status == GC_CONNECT_FAIL) break; /* ** just in case ... */ ResetEvent( pcb->s_ncb.ncb_event ); /* ** OK, now make the call */ hSave = pcb->s_ncb.ncb_event; /* save handle */ memset( &pcb->s_ncb, 0, sizeof(NCB) ); pcb->s_ncb.ncb_event = hSave; /* restore handle */ pcb->s_ncb.ncb_buffer = parm_list->buffer_ptr; pcb->s_ncb.ncb_length = (WORD)parm_list->buffer_lng; pcb->s_ncb.ncb_command = NCBCALL | ASYNCH; pcb->s_ncb.ncb_lana_num = lana_num; STcopy( GCc_client_name, pcb->s_ncb.ncb_name ); STpolycat( 3, parm_list->function_parms.connect.node_id, "_", parm_list->function_parms.connect.port_id, callname ); CVupper( callname ); /* ** Loopback check to prevent mangling the name (?) */ if ( STcompare( parm_list->function_parms.connect.port_id, GCc_listen_port ) == 0 ) { STcopy( GCc_listen_port, pcb->s_ncb.ncb_callname ); } else { STcopy( callname, pcb->s_ncb.ncb_callname ); } GCTRACE(3)("LMAN THREAD: CONNECT doing CALL to %s\n", pcb->s_ncb.ncb_callname ); if ( Netbios( &pcb->s_ncb ) != NRC_GOODRET ) { status = (STATUS)pcb->s_ncb.ncb_retcode; CloseHandle( pcb->s_ncb.ncb_event ); pcb->s_ncb.ncb_event = NULL; CloseHandle( pcb->r_ncb.ncb_event ); pcb->r_ncb.ncb_event = NULL; pcb->state.conn = COMPLETED; SETWIN32ERR(&parm_list->system_status, status, ER_netbios); parm_list->generic_status = GC_CONNECT_FAIL; break; } GCTRACE(3)("LMAN THREAD: Async CALL OK\n" ); pcb->state.conn = COMPLETING; break; /******************************************************* ** Handle SEND *******************************************************/ case GCC_SEND: GCTRACE(4)("LMAN THREAD: process SEND\n"); if ( pcb->state.send != INITIAL ) { break; } pcb->s_ncb.ncb_buffer = parm_list->buffer_ptr; pcb->s_ncb.ncb_length = (WORD)parm_list->buffer_lng; pcb->s_ncb.ncb_lana_num = lana_num; pcb->s_ncb.ncb_command = NCBSEND | ASYNCH; if ( Netbios( &pcb->s_ncb ) != NRC_GOODRET ) { status = (STATUS)pcb->s_ncb.ncb_retcode; pcb->state.send = COMPLETED; SETWIN32ERR(&parm_list->system_status, status, ER_netbios); parm_list->generic_status = GC_SEND_FAIL; } pcb->state.send = COMPLETING; break; /******************************************************* ** Handle RECEIVE *******************************************************/ case GCC_RECEIVE: GCTRACE(4)("LMAN THREAD: process RECEIVE\n"); if ( pcb->state.recv != INITIAL ) { pending_requests++; break; } pcb->r_ncb.ncb_buffer = parm_list->buffer_ptr; pcb->r_ncb.ncb_length = (WORD)parm_list->buffer_lng; pcb->r_ncb.ncb_lana_num = lana_num; pcb->r_ncb.ncb_command = NCBRECV | ASYNCH; if ( Netbios( &pcb->r_ncb ) != NRC_GOODRET ) { status = (STATUS)pcb->r_ncb.ncb_retcode; pcb->state.recv = COMPLETED; SETWIN32ERR(&parm_list->system_status, status, ER_netbios); parm_list->generic_status = GC_RECEIVE_FAIL; } pcb->state.recv = COMPLETING; break; /******************************************************* ** Handle DISCONNECT *******************************************************/ case GCC_DISCONNECT: GCTRACE(4)("LMAN THREAD: process DISCONNECT\n"); if ( pcb && pcb->state.disc == INITIAL ) { pcb->s_ncb.ncb_buffer = parm_list->buffer_ptr; pcb->s_ncb.ncb_length = (WORD)parm_list->buffer_lng; pcb->s_ncb.ncb_command = NCBHANGUP | ASYNCH; pcb->s_ncb.ncb_lana_num = lana_num; if ( pcb->s_ncb.ncb_lsn == 0 ) pcb->s_ncb.ncb_lsn = pcb->r_ncb.ncb_lsn; if ( Netbios( &pcb->s_ncb ) != NRC_GOODRET ) { status = (STATUS)pcb->s_ncb.ncb_retcode; pcb->state.disc = COMPLETED; SETWIN32ERR(&parm_list->system_status, status, ER_netbios); parm_list->generic_status = GC_DISCONNECT_FAIL; break; } pcb->state.disc = COMPLETING; } break; } /* end switch */ } /* end for process q loop */ /* ** Now go thru the inprocess Q and look for any requests that ** have been completed. This will be indicated by one of: ** parm_list->pcb == NULL (bad connect or after disconnect) or ** pcb->state == COMPLETED, or WaitForSingleObject indicates ** completion. */ GCTRACE(4)("LMAN THREAD: processing completed. . . \n"); q = Tptr->process_head.q_next; while( q != &Tptr->process_head ) { REQUEST_Q *rq = (REQUEST_Q *)q; GCC_P_PLIST *pl = rq->plist; PCB *pcb = (PCB *)pl->pcb; bool completed = FALSE; switch ( pl->function_invoked ) { case GCC_CONNECT: if ( pcb == NULL || pcb->state.conn == COMPLETED || WaitForSingleObject( pcb->s_ncb.ncb_event, 0) == WAIT_OBJECT_0 ) { if (pcb) { ResetEvent( pcb->s_ncb.ncb_event ); pcb->r_ncb.ncb_lsn = pcb->s_ncb.ncb_lsn; if ( pcb->s_ncb.ncb_lsn == 0 || pcb->s_ncb.ncb_retcode != NRC_GOODRET ) { pl->generic_status = GC_CONNECT_FAIL; status = (STATUS)pcb->s_ncb.ncb_retcode; SETWIN32ERR( &pl->system_status, status , ER_revent); CloseHandle( pcb->s_ncb.ncb_event ); CloseHandle( pcb->r_ncb.ncb_event ); free( pcb ); pl->pcb = NULL; } } completed = TRUE; } break; case GCC_SEND: if ( pcb == NULL || pcb->state.send == COMPLETED || WaitForSingleObject( pcb->s_ncb.ncb_event, 0) == WAIT_OBJECT_0 ) { ResetEvent( pcb->s_ncb.ncb_event ); if ( pcb->s_ncb.ncb_lsn == 0 || pcb->s_ncb.ncb_retcode != NRC_GOODRET ) { pl->generic_status = GC_SEND_FAIL; status = (STATUS)pcb->s_ncb.ncb_retcode; SETWIN32ERR( &pl->system_status, status , ER_revent); } else { GCTRACE(2)( "LMAN THREAD: Send COMP pl len %d pcb len %d\n", pl->buffer_lng, pcb->s_ncb.ncb_length); pl->buffer_lng = pcb->s_ncb.ncb_length; } completed = TRUE; } break; case GCC_RECEIVE: if ( pcb == NULL || pcb->state.recv == COMPLETED || WaitForSingleObject( pcb->r_ncb.ncb_event, 0) == WAIT_OBJECT_0 ) { ResetEvent( pcb->r_ncb.ncb_event ); if ( pcb->s_ncb.ncb_lsn == 0 || pcb->r_ncb.ncb_retcode != NRC_GOODRET ) { pl->generic_status = GC_RECEIVE_FAIL; status = (STATUS)pcb->r_ncb.ncb_retcode; SETWIN32ERR( &pl->system_status, status , ER_revent); } else { pl->buffer_lng = pcb->r_ncb.ncb_length; } completed = TRUE; } break; case GCC_DISCONNECT: if ( pcb == NULL || pcb->state.disc == COMPLETED || WaitForSingleObject( pcb->s_ncb.ncb_event, 0) == WAIT_OBJECT_0 ) { if (pcb) { if ( pcb->s_ncb.ncb_lsn == 0 || pcb->s_ncb.ncb_retcode != NRC_GOODRET ) { pl->generic_status = GC_DISCONNECT_FAIL; status = (STATUS)pcb->s_ncb.ncb_retcode; SETWIN32ERR( &pl->system_status, status , ER_revent); } pcb->s_ncb.ncb_command = NCBDELNAME; Netbios( &pcb->s_ncb ); CloseHandle( pcb->s_ncb.ncb_event ); CloseHandle( pcb->r_ncb.ncb_event ); free( pcb ); pl->pcb = NULL; } completed = TRUE; } break; } /* end switch */ if ( completed ) { QUEUE *nq = q->q_next; GCTRACE(3)("LMAN THREAD: Complete! PCB = %x PARM = %x \n", pcb, pl); GCcomplete_request( q ); q = nq; processing_requests--; GCTRACE(3)("LMAN THREAD: processed completed \n"); GCTRACE(3)(" : total now = %d \n", processing_requests); } /* end if req completed */ else { q = q->q_next; } } /* end for -- look for complete req */ /* ** Do a quick, non-blocking check to see if any new requests ** came in during processing. */ GCTRACE(4)("LMAN THREAD: quick look for new reqs \n"); if ( WaitForSingleObject( hEventThreadInQ, 0 ) == WAIT_OBJECT_0 ) { processing_requests += GCget_incoming_reqs( Tptr, hMutexThreadInQ ); } GCTRACE(4)("LMAN THREAD: process reqs now = %d\n", processing_requests); if (processing_requests && pending_requests == processing_requests) { i4 Sleeptime = 1; Sleep(Sleeptime); } } /* end while processing requests */ if (In_Shutdown) { _endthreadex(0); return; } /* ** we're done for now, go back to the top and sleep. */ GCTRACE(3)("LMAN THREAD: No more reqs, going back to top\n" ); goto top; }
/* ** Name: GClanman_open ** Description: ** Open the listen channel for LANMAN. Called from GClanman(). This ** routine should only be called once at server startup. ** History: ** 11-nov-93 (edg) ** created. ** 03-may-1996 (canor01) ** Allow for more than the default number of sessions. ** 29-jun-2000 (somsa01) ** Use GCc_listen_port for the ncb_name, making sure that we ** update GCc_listen_port if we need a unique one. ** 06-Aug-2009 (Bruce Lunsford) Sir 122426 ** Remove mutexing around calls to GCA service completion routine ** as it is no longer necessary, since GCA is thread-safe...removes ** calls to GCwaitCompletion + GCrestart. Should improve peformance. */ STATUS GClanman_open( GCC_P_PLIST *parm_list ) { STATUS status; LANA_ENUM lanas; i4 subport = 0; /* ** Find available adapters */ memset( &Listen_Ncb, 0, sizeof(NCB) ); Listen_Ncb.ncb_buffer = &lanas; Listen_Ncb.ncb_length = sizeof(LANA_ENUM); Listen_Ncb.ncb_command = NCBENUM; Netbios( &Listen_Ncb ); if ( lanas.length == 0 ) { status = (STATUS)Listen_Ncb.ncb_retcode; GCTRACE(1)("GClanman_open: No LANA adapters %d\n", status ); parm_list->generic_status = GC_OPEN_FAIL; SETWIN32ERR(&parm_list->system_status, status, ER_listen); goto err_exit; } /* use first available LANA */ lana_num = lanas.lana[0]; /* ** Use Listen_Ncb to 1st do a reset to start things out ... */ memset( &Listen_Ncb, 0, sizeof(NCB) ); Listen_Ncb.ncb_buffer = Dummy_Buf; Listen_Ncb.ncb_length = sizeof(Dummy_Buf); Listen_Ncb.ncb_lana_num = lana_num; Listen_Ncb.ncb_callname[0] = 255; /* max number of sessions */ Listen_Ncb.ncb_callname[2] = 255; /* max number of names */ Listen_Ncb.ncb_command = NCBRESET; Netbios( &Listen_Ncb ); /* ** Add Name we'll be listening on. */ memset( &Listen_Ncb, 0, sizeof(NCB) ); Listen_Ncb.ncb_buffer = Dummy_Buf; Listen_Ncb.ncb_length = sizeof(Dummy_Buf); Listen_Ncb.ncb_lana_num = lana_num; Listen_Ncb.ncb_command = NCBADDNAME; for (;;) { if (subport) STprintf(Listen_Ncb.ncb_name, "%s%d", GCc_listen_port, subport); else STcopy( GCc_listen_port, Listen_Ncb.ncb_name ); Netbios( &Listen_Ncb ); if (Listen_Ncb.ncb_retcode == NRC_GOODRET) break; else if (Listen_Ncb.ncb_retcode == NRC_DUPNAME && (++subport) < 8) continue; else { status = (STATUS)Listen_Ncb.ncb_retcode; GCTRACE(1)("GClanman_open: Error ADDNAME returned %d\n", status ); parm_list->generic_status = GC_OPEN_FAIL; SETWIN32ERR(&parm_list->system_status, status, ER_listen); goto err_exit; } } /* ** Set listen port in parm list. */ STcopy(Listen_Ncb.ncb_name, GCc_listen_port); if (subport) { STprintf(parm_list->pce->pce_port, "%s%d", parm_list->function_parms.open.port_id, subport); } parm_list->function_parms.open.lsn_port = GCc_listen_port; err_exit: /* ** Should completion be driven here? */ (*parm_list->compl_exit) (parm_list->compl_id); return OK; }
/* ** Name: GClanman_listen ** Description: ** This is the listen thread for lanman. It runs a syncronous accept() ** on the listen socket. When complete it Q's the completetion to ** the completed event Q. When accept completes, this thread returns. ** A new one will be created when GClanman() gets the request to ** repost the listen. ** History: ** 11-nov-93 (edg) ** created. ** 29-jun-2000 (somsa01) ** Use GCc_listen_port for the ncb_name. ** 16-mar-2001 (somsa01) ** Set node_id to ncb_callname. ** 06-Aug-2009 (Bruce Lunsford) Sir 122426 ** Convert GCC completion queue mutex to a critical section ** to improve performance (less overhead). ** Since _beginthreadex() is now used to start this thread, ** use _endthreadex() to end it. */ VOID GClanman_listen( VOID *parms ) { GCC_P_PLIST *parm_list = (GCC_P_PLIST *)parms; PCB *pcb; STATUS status = OK; REQUEST_Q *rq; SECURITY_ATTRIBUTES sa; iimksec (&sa); /* ** Initialize the listen node_id to NULL. */ parm_list->function_parms.listen.node_id = NULL; /* ** Initialize fields of the Listen_Ncb */ memset( &Listen_Ncb, 0, sizeof(NCB) ); Listen_Ncb.ncb_buffer = parm_list->buffer_ptr; Listen_Ncb.ncb_length = (USHORT)parm_list->buffer_lng; Listen_Ncb.ncb_command = NCBLISTEN; Listen_Ncb.ncb_lana_num = lana_num; *Listen_Ncb.ncb_callname = (unsigned char)NULL; STmove( "*", ' ', NCBNAMSZ, Listen_Ncb.ncb_callname ); *Listen_Ncb.ncb_name = (unsigned char)NULL; STcopy( GCc_listen_port, Listen_Ncb.ncb_name ); /* ** Now we can do the NCBLISTEN request. Block until it completes. */ Netbios( &Listen_Ncb ); if ( Listen_Ncb.ncb_retcode != NRC_GOODRET ) { status = (int)Listen_Ncb.ncb_retcode; goto sys_err; } /* ** Allocate Protcol Control Block specific to this driver and put into ** parm list */ pcb = (PCB *) malloc( sizeof(PCB) ); if (pcb == NULL) { status = errno; goto sys_err; } memset( pcb, 0, sizeof( *pcb ) ); parm_list->pcb = (char *)pcb; /* ** Set node_id to the node name of the partner. */ parm_list->function_parms.listen.node_id = STalloc(Listen_Ncb.ncb_callname); /* ** Now assign the pcb's send and receive NCB's the local session number ** returned by listen for further communications. */ pcb->s_ncb.ncb_lsn = pcb->r_ncb.ncb_lsn = Listen_Ncb.ncb_lsn; /* ** Now create handles for the read and write event handles in the ** NCB. These are created with manual reset as cautioned by the ** programmer's guide so a ResetEvent MUST be done on them. */ if ((pcb->s_ncb.ncb_event = CreateEvent( &sa, TRUE, FALSE, NULL ))== NULL) { status = GetLastError(); goto sys_err; } if ((pcb->r_ncb.ncb_event = CreateEvent( &sa, TRUE, FALSE, NULL ))== NULL) { status = GetLastError(); CloseHandle( pcb->s_ncb.ncb_event ); pcb->s_ncb.ncb_event = NULL; goto sys_err; } sys_err: if (status != OK) { SETWIN32ERR(&parm_list->system_status, status, ER_create); parm_list->generic_status = GC_LISTEN_FAIL; } /* ** Now allocate a request q structure, stick it into complete q, and ** raise the GCC_COMPLETE event. */ if ( (rq = (REQUEST_Q *)MEreqmem(0, sizeof(*rq), TRUE, NULL ) ) != NULL ) { rq->plist = parm_list; /* ** Get critical section for completion Q. */ EnterCriticalSection( &GccCompleteQCritSect ); /* ** Now insert the completed request into the completed Q. */ QUinsert( &rq->req_q, &IIGCc_proto_threads.completed_head ); /* ** Exit/leave critical section for completion Q */ LeaveCriticalSection( &GccCompleteQCritSect ); /* ** raise the completion event to wake up GCexec. */ if ( !SetEvent( hAsyncEvents[GCC_COMPLETE] ) ) { /* ** ruh roh. We're screwed if this event can't be signaled. */ status = GetLastError(); GCTRACE(1)("GClanman_listen, SetEvent error = %d\n", status ); } } else { /* ** ruh-roh. MEreqmem failed. Selious tlouble. Not sure what to ** do about it at this point since if it failed we can't notify ** the completion routine. For now, just return (exit thread) ** which will probably have the effect of blocking all incoming ** connections. */ } _endthreadex(0); }
static DNS_STATUS dns_do_query_netbios( PCSTR name, DNS_RECORDA **recp ) { NCB ncb; UCHAR ret; DNS_RRSET rrset; FIND_NAME_BUFFER *buffer; FIND_NAME_HEADER *header; DNS_RECORDA *record = NULL; unsigned int i, len; DNS_STATUS status = ERROR_INVALID_NAME; len = strlen( name ); if (len >= NCBNAMSZ) return DNS_ERROR_RCODE_NAME_ERROR; DNS_RRSET_INIT( rrset ); memset( &ncb, 0, sizeof(ncb) ); ncb.ncb_command = NCBFINDNAME; memset( ncb.ncb_callname, ' ', sizeof(ncb.ncb_callname) ); memcpy( ncb.ncb_callname, name, len ); ncb.ncb_callname[NCBNAMSZ - 1] = '\0'; ret = Netbios( &ncb ); if (ret != NRC_GOODRET) return ERROR_INVALID_NAME; header = (FIND_NAME_HEADER *)ncb.ncb_buffer; buffer = (FIND_NAME_BUFFER *)((char *)header + sizeof(FIND_NAME_HEADER)); for (i = 0; i < header->node_count; i++) { record = dns_zero_alloc( sizeof(DNS_RECORDA) ); if (!record) { status = ERROR_NOT_ENOUGH_MEMORY; goto exit; } else { record->pName = dns_strdup_u( name ); if (!record->pName) { status = ERROR_NOT_ENOUGH_MEMORY; goto exit; } record->wType = DNS_TYPE_A; record->Flags.S.Section = DnsSectionAnswer; record->Flags.S.CharSet = DnsCharSetUtf8; record->dwTtl = DEFAULT_TTL; /* FIXME: network byte order? */ record->Data.A.IpAddress = *(DWORD *)((char *)buffer[i].destination_addr + 2); DNS_RRSET_ADD( rrset, (DNS_RECORD *)record ); } } status = ERROR_SUCCESS; exit: DNS_RRSET_TERMINATE( rrset ); if (status != ERROR_SUCCESS) DnsRecordListFree( rrset.pFirstRR, DnsFreeRecordList ); else *recp = (DNS_RECORDA *)rrset.pFirstRR; return status; }