/********************************************************************* * Function: void NBNSTask(void) * * PreCondition: None * * Input: None * * Output: Sends responses to NetBIOS name requests * * Side Effects: None * * Overview: None * * Note: None ********************************************************************/ void NBNSTask(void) { static UDP_SOCKET MySocket; BYTE i; WORD_VAL Type, Class; NBNS_HEADER NBNSHeader; BYTE NameString[16]; static enum { NBNS_HOME = 0, NBNS_OPEN_SOCKET, NBNS_LISTEN } smNBNS = NBNS_HOME; switch(smNBNS) { case NBNS_HOME: smNBNS++; break; case NBNS_OPEN_SOCKET: MySocket = UDPOpen(NBNS_PORT, NULL, NBNS_PORT); if(MySocket == INVALID_UDP_SOCKET) break; smNBNS++; case NBNS_LISTEN: if(!UDPIsGetReady(MySocket)) break; // Respond only to name requests sent to us from nodes on the same subnet // This prevents us from sending out the wrong IP address information if // we haven't gotten a DHCP lease yet. if((remoteNode.IPAddr.Val & AppConfig.MyMask.Val) != (AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val)) { UDPDiscard(); break; } // Retrieve the NBNS header and de-big-endian it UDPGet(&NBNSHeader.TransactionID.v[1]); UDPGet(&NBNSHeader.TransactionID.v[0]); UDPGet(&NBNSHeader.Flags.v[1]); UDPGet(&NBNSHeader.Flags.v[0]); UDPGet(&NBNSHeader.Questions.v[1]); UDPGet(&NBNSHeader.Questions.v[0]); UDPGet(&NBNSHeader.Answers.v[1]); UDPGet(&NBNSHeader.Answers.v[0]); UDPGet(&NBNSHeader.AuthoritativeRecords.v[1]); UDPGet(&NBNSHeader.AuthoritativeRecords.v[0]); UDPGet(&NBNSHeader.AdditionalRecords.v[1]); UDPGet(&NBNSHeader.AdditionalRecords.v[0]); // Remove all questions while(NBNSHeader.Questions.Val--) { NBNSGetName(NameString); UDPGet(&i); // <??> Trailing character on string UDPGet(&Type.v[1]); // Question type UDPGet(&Type.v[0]); UDPGet(&Class.v[1]); // Question class UDPGet(&Class.v[0]); if(Type.Val == 0x0020u && Class.Val == 0x0001u && strcmp((char*)NameString, (char*)AppConfig.NetBIOSName) == 0) { while(!UDPIsPutReady(MySocket)); NBNSHeader.Flags.Val = 0x8400; UDPPut(NBNSHeader.TransactionID.v[1]); UDPPut(NBNSHeader.TransactionID.v[0]); UDPPut(NBNSHeader.Flags.v[1]); UDPPut(NBNSHeader.Flags.v[0]); UDPPut(0x00); // 0x0000 Questions UDPPut(0x00); UDPPut(0x00); // 0x0001 Answers UDPPut(0x01); UDPPut(0x00); // 0x0000 Athoritative records UDPPut(0x00); UDPPut(0x00); // 0x0000 Additional records UDPPut(0x00); NBNSPutName(AppConfig.NetBIOSName); UDPPut(0x00); // 0x0020 Type: NetBIOS UDPPut(0x20); UDPPut(0x00); // 0x0001 Class: Internet UDPPut(0x01); UDPPut(0x00); // 0x00000000 Time To Live UDPPut(0x00); UDPPut(0x00); UDPPut(0x00); UDPPut(0x00); // 0x0006 Data length UDPPut(0x06); UDPPut(0x60); // 0x6000 Flags: H-node, Unique UDPPut(0x00); UDPPut(AppConfig.MyIPAddr.v[0]); // Put out IP address UDPPut(AppConfig.MyIPAddr.v[1]); UDPPut(AppConfig.MyIPAddr.v[2]); UDPPut(AppConfig.MyIPAddr.v[3]); // Change the destination address to the unicast address of the last received packet memcpy((void*)&UDPSocketInfo[MySocket].remoteNode, (const void*)&remoteNode, sizeof(remoteNode)); UDPFlush(); } } UDPDiscard(); break; } }
bool NBNSTask(TCPIP_NET_IF* pNetIf) { uint8_t i; TCPIP_UINT16_VAL Type, Class; NBNS_HEADER NBNSHeader; uint8_t NameString[16]; UDP_SOCKET s; int nbnsRxSize; int nbnsTxSize; s = nbnsDcpt.uSkt; switch(nbnsDcpt.sm) { case NBNS_HOME: nbnsDcpt.sm++; break; case NBNS_OPEN_SOCKET: s = UDPOpenServer(IP_ADDRESS_TYPE_IPV4, NBNS_PORT, 0); if(s == INVALID_UDP_SOCKET) break; if(!UDPRemoteBind(s, IP_ADDRESS_TYPE_IPV4, NBNS_PORT, 0)) { UDPClose(s); break; } nbnsDcpt.uSkt = s; nbnsDcpt.sm++; case NBNS_LISTEN: //if(!UDPIsGetReady(s)) nbnsRxSize = UDPIsGetReady(s); if(!nbnsRxSize) { break; } // Respond only to name requests sent to us from nodes on the same subnet // This prevents us from sending out the wrong IP address information if // we haven't gotten a DHCP lease yet. if((remoteNode.IPAddr.Val & pNetIf->netMask.Val) != (pNetIf->netIPAddr.Val & pNetIf->netMask.Val)) { UDPDiscard(s); break; } #ifdef _NBNS_DEBUG nbnsRxOks++; if(nbnsRxSize > nbnsRxMaxSize) { nbnsRxMaxSize = nbnsRxSize; } #endif // _NBNS_DEBUG // Retrieve the NBNS header and de-big-endian it UDPGet(s, &NBNSHeader.TransactionID.v[1]); UDPGet(s, &NBNSHeader.TransactionID.v[0]); UDPGet(s, &NBNSHeader.Flags.v[1]); UDPGet(s, &NBNSHeader.Flags.v[0]); UDPGet(s, &NBNSHeader.Questions.v[1]); UDPGet(s, &NBNSHeader.Questions.v[0]); UDPGet(s, &NBNSHeader.Answers.v[1]); UDPGet(s, &NBNSHeader.Answers.v[0]); UDPGet(s, &NBNSHeader.AuthoritativeRecords.v[1]); UDPGet(s, &NBNSHeader.AuthoritativeRecords.v[0]); UDPGet(s, &NBNSHeader.AdditionalRecords.v[1]); UDPGet(s, &NBNSHeader.AdditionalRecords.v[0]); // Remove all questions while(NBNSHeader.Questions.Val--) { NBNSGetName(s, NameString); UDPGet(s, &i); // <??> Trailing character on string UDPGet(s, &Type.v[1]); // Question type UDPGet(s, &Type.v[0]); UDPGet(s, &Class.v[1]); // Question class UDPGet(s, &Class.v[0]); if(Type.Val == 0x0020u && Class.Val == 0x0001u) { int nIfs, nIx; TCPIP_NET_IF* pIf; const char* netbName; nIfs = TCPIP_STACK_NetworksNo(); for(nIx = 0; nIx < nIfs; nIx++) { pIf = (TCPIP_NET_IF*)TCPIP_STACK_IxToNet(nIx); netbName = TCPIP_STACK_NetBIOSName(pIf); // this checks the IF is up! if(memcmp((void*)NameString, netbName, sizeof(pIf->NetBIOSName)) == 0) { // one of our interfaces has this name nbnsTxSize = UDPIsTxPutReady(s, 64); if(nbnsTxSize) { #ifdef _NBNS_DEBUG nbnsTxOks++; if(nbnsTxSize > nbnsTxMaxSize) { nbnsTxMaxSize = nbnsTxSize; } #endif // _NBNS_DEBUG NBNSHeader.Flags.Val = 0x8400; UDPPut(s, NBNSHeader.TransactionID.v[1]); UDPPut(s, NBNSHeader.TransactionID.v[0]); UDPPut(s, NBNSHeader.Flags.v[1]); UDPPut(s, NBNSHeader.Flags.v[0]); UDPPut(s, 0x00); // 0x0000 Questions UDPPut(s, 0x00); UDPPut(s, 0x00); // 0x0001 Answers UDPPut(s, 0x01); UDPPut(s, 0x00); // 0x0000 Athoritative records UDPPut(s, 0x00); UDPPut(s, 0x00); // 0x0000 Additional records UDPPut(s, 0x00); NBNSPutName(s, netbName); UDPPut(s, 0x00); // 0x0020 Type: NetBIOS UDPPut(s, 0x20); UDPPut(s, 0x00); // 0x0001 Class: Internet UDPPut(s, 0x01); UDPPut(s, 0x00); // 0x00000000 Time To Live UDPPut(s, 0x00); UDPPut(s, 0x00); UDPPut(s, 0x00); UDPPut(s, 0x00); // 0x0006 Data length UDPPut(s, 0x06); UDPPut(s, 0x60); // 0x6000 Flags: H-node, Unique UDPPut(s, 0x00); UDPPut(s, pIf->netIPAddr.v[0]); // Put out IP address UDPPut(s, pIf->netIPAddr.v[1]); UDPPut(s, pIf->netIPAddr.v[2]); UDPPut(s, pIf->netIPAddr.v[3]); // Change the destination address to the unicast address of the last received packet UDPSetDestinationIPAddress(s, IP_ADDRESS_TYPE_IPV4, (IP_MULTI_ADDRESS*)&remoteNode.IPAddr); memcpy((void*)&((IPV4_PACKET*)UDPSocketDcpt[s].pTxPkt)->remoteMACAddr, (const void*)&remoteNode.MACAddr, sizeof(remoteNode.MACAddr)); UDPFlush(s); } #ifdef _NBNS_DEBUG else { nbnsTxFails++; } #endif // _NBNS_DEBUG break; } } } } UDPDiscard(s); break; } return true; }
/********************************************************************* * Function: void NBNSTask(NET_CONFIG* pConfig) * * PreCondition: None * * Input: pConfig - interface * * Output: None * * Side Effects: None * * Overview: Sends responses to NetBIOS name requests * * Note: None ********************************************************************/ void NBNSTask(NET_CONFIG* pConfig) { uint8_t i; TCPIP_UINT16_VAL Type, Class; NBNS_HEADER NBNSHeader; uint8_t NameString[16]; int netIx; UDP_SOCKET s; netIx = _TCPIPStackNetIx(pConfig); s = MySocket[netIx]; switch(smNBNS[netIx]) { case NBNS_HOME: smNBNS[netIx]++; break; case NBNS_OPEN_SOCKET: MySocket[netIx] = UDPOpen(0,UDP_OPEN_SERVER,NBNS_PORT,NBNS_PORT); if(MySocket[netIx] == INVALID_UDP_SOCKET) break; UDPSocketSetNet(MySocket[netIx], pConfig); smNBNS[netIx]++; case NBNS_LISTEN: if(!UDPIsGetReady(s)) { break; } // Respond only to name requests sent to us from nodes on the same subnet // This prevents us from sending out the wrong IP address information if // we haven't gotten a DHCP lease yet. if((remoteNode.IPAddr.Val & pConfig->MyMask.Val) != (pConfig->MyIPAddr.Val & pConfig->MyMask.Val)) { UDPDiscard(s); break; } // Retrieve the NBNS header and de-big-endian it UDPGet(s, &NBNSHeader.TransactionID.v[1]); UDPGet(s, &NBNSHeader.TransactionID.v[0]); UDPGet(s, &NBNSHeader.Flags.v[1]); UDPGet(s, &NBNSHeader.Flags.v[0]); UDPGet(s, &NBNSHeader.Questions.v[1]); UDPGet(s, &NBNSHeader.Questions.v[0]); UDPGet(s, &NBNSHeader.Answers.v[1]); UDPGet(s, &NBNSHeader.Answers.v[0]); UDPGet(s, &NBNSHeader.AuthoritativeRecords.v[1]); UDPGet(s, &NBNSHeader.AuthoritativeRecords.v[0]); UDPGet(s, &NBNSHeader.AdditionalRecords.v[1]); UDPGet(s, &NBNSHeader.AdditionalRecords.v[0]); // Remove all questions while(NBNSHeader.Questions.Val--) { NBNSGetName(s, NameString); UDPGet(s, &i); // <??> Trailing character on string UDPGet(s, &Type.v[1]); // Question type UDPGet(s, &Type.v[0]); UDPGet(s, &Class.v[1]); // Question class UDPGet(s, &Class.v[0]); if(Type.Val == 0x0020u && Class.Val == 0x0001u && memcmp((void*)NameString, (void*)pConfig->NetBIOSName, sizeof(pConfig->NetBIOSName)) == 0) { if(UDPIsTxPutReady(s, 64)) { NBNSHeader.Flags.Val = 0x8400; UDPPut(s, NBNSHeader.TransactionID.v[1]); UDPPut(s, NBNSHeader.TransactionID.v[0]); UDPPut(s, NBNSHeader.Flags.v[1]); UDPPut(s, NBNSHeader.Flags.v[0]); UDPPut(s, 0x00); // 0x0000 Questions UDPPut(s, 0x00); UDPPut(s, 0x00); // 0x0001 Answers UDPPut(s, 0x01); UDPPut(s, 0x00); // 0x0000 Athoritative records UDPPut(s, 0x00); UDPPut(s, 0x00); // 0x0000 Additional records UDPPut(s, 0x00); NBNSPutName(s, pConfig->NetBIOSName); UDPPut(s, 0x00); // 0x0020 Type: NetBIOS UDPPut(s, 0x20); UDPPut(s, 0x00); // 0x0001 Class: Internet UDPPut(s, 0x01); UDPPut(s, 0x00); // 0x00000000 Time To Live UDPPut(s, 0x00); UDPPut(s, 0x00); UDPPut(s, 0x00); UDPPut(s, 0x00); // 0x0006 Data length UDPPut(s, 0x06); UDPPut(s, 0x60); // 0x6000 Flags: H-node, Unique UDPPut(s, 0x00); UDPPut(s, pConfig->MyIPAddr.v[0]); // Put out IP address UDPPut(s, pConfig->MyIPAddr.v[1]); UDPPut(s, pConfig->MyIPAddr.v[2]); UDPPut(s, pConfig->MyIPAddr.v[3]); // Change the destination address to the unicast address of the last received packet TCPIP_IPV4_SetDestAddress(UDPSocketDcpt[s].pTxPkt,remoteNode.IPAddr.Val); memcpy((void*)&UDPSocketDcpt[s].pTxPkt->remoteMACAddr, (const void*)&remoteNode.MACAddr, sizeof(remoteNode.MACAddr)); UDPFlush(s); } } } UDPDiscard(s); break; } }