?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{FILE START}

library

?curdirlinks? - Rev 32

?prevdifflink? - Blame - ?getfile?

/*********************************************************************
 *
 *  NetBIOS Name Service (NBNS) Server
 *  Module for Microchip TCP/IP Stack
 *       -Responds to NBNS name requests to allow human name assignment 
 *        to the board.  i.e. allows nodes on the same IP subnet to use a 
 *    hostname to access the board instead of an IP address.
 *       -Reference: RFC 1002
 *
 *********************************************************************
 * FileName:        NBNS.c
 * Dependencies:    UDP
 * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
 * Compiler:        Microchip C32 v1.05 or higher
 *                                      Microchip C30 v3.12 or higher
 *                                      Microchip C18 v3.30 or higher
 *                                      HI-TECH PICC-18 PRO 9.63PL2 or higher
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 *
 * Copyright (C) 2002-2009 Microchip Technology Inc.  All rights
 * reserved.
 *
 * Microchip licenses to you the right to use, modify, copy, and
 * distribute:
 * (i)  the Software when embedded on a Microchip microcontroller or
 *      digital signal controller product ("Device") which is
 *      integrated into Licensee's product; or
 * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
 *              ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
 *              used in conjunction with a Microchip ethernet controller for
 *              the sole purpose of interfacing with the ethernet controller.
 *
 * You should refer to the license agreement accompanying this
 * Software for additional information regarding your rights and
 * obligations.
 *
 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
 *
 *
 * Author               Date    Comment
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * Howard Schlunder     8/01/06 Original
 ********************************************************************/
#define __NBNS_C

#include "TCPIPConfig.h"

#if defined(STACK_USE_NBNS)

#include "TCPIP Stack/TCPIP.h"

// NetBIOS Name Service port
#define NBNS_PORT               (137u)

// NBNS Header structure
typedef struct _NBNS_HEADER
{
        WORD_VAL TransactionID;
        WORD_VAL Flags;
        WORD_VAL Questions;
        WORD_VAL Answers;
        WORD_VAL AuthoritativeRecords;
        WORD_VAL AdditionalRecords;
} NBNS_HEADER;

static void NBNSPutName(BYTE *String);
static void NBNSGetName(BYTE *String);

extern NODE_INFO remoteNode;


/*********************************************************************
 * Function:        void NBNSTask(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends responses to NetBIOS name requests
 *
 * 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 && memcmp((void*)NameString, (void*)AppConfig.NetBIOSName, sizeof(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;
        }
}

/*********************************************************************
 * Function:        static void NBNSPutName (BYTE *String)
 *
 * PreCondition:    None
 *
 * Input:           String: The name to transmit
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Transmits the NetBIOS name across an open UDP
 *                  socket.
 *
 * Note:            None
 ********************************************************************/
static void NBNSPutName(BYTE *String)
{
        BYTE i, j;

        UDPPut(32);     // NetBIOS names are always 32 bytes long (16 decoded bytes)
        for(i = 0; i < 16u; i++)
        {
                j = *String++;
                UDPPut((j>>4) + 'A');
                UDPPut((j & 0x0F) + 'A');
        }
        
        UDPPut(0x00);
}

/*********************************************************************
 * Function:        static void NBNSGetName (BYTE *String)
 *
 * PreCondition:    None
 *
 * Input:           String: Pointer to an array into which
 *                  a received NetBIOS name should be copied.
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Reads the NetBIOS name from a UDP socket and
 *                  copies it into a user-specified buffer.
 *
 * Note:            None
 ********************************************************************/
static void NBNSGetName(BYTE *String)
{
        BYTE i, j, k;

        if(String == NULL)
        {
                UDPGet(&i);
                while(i--)
                {
                        UDPGet(&j);
                }
        }
        else
        {
                UDPGet(&i);
                if(i != 32u)
                {
                        *String = 0;
                        return;
                }
                while(i--)
                {
                        UDPGet(&j);
                        j -= 'A';
                        k = j<<4;
                        i--;
                        UDPGet(&j);
                        j -= 'A';
                        *String++ = k | j;
                }
        }
}


#endif //#if defined(STACK_USE_NBNS)
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3