Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers nbns_responder.c Source File

nbns_responder.c

Go to the documentation of this file.
00001 /**
00002  * @file nbns_responder.c
00003  * @brief NBNS responder (NetBIOS Name Service)
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneTCP Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL NBNS_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include "core/net.h"
00034 #include "netbios/nbns_responder.h"
00035 #include "netbios/nbns_common.h"
00036 #include "dns/dns_debug.h"
00037 #include "debug.h"
00038 
00039 //Check TCP/IP stack configuration
00040 #if (NBNS_RESPONDER_SUPPORT == ENABLED && IPV4_SUPPORT == ENABLED)
00041 
00042 
00043 /**
00044  * @brief Process NBNS query message
00045  * @param[in] interface Underlying network interface
00046  * @param[in] pseudoHeader UDP pseudo header
00047  * @param[in] udpHeader UDP header
00048  * @param[in] message Pointer to the NBNS query message
00049  * @param[in] length Length of the message
00050  **/
00051 
00052 void nbnsProcessQuery(NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader,
00053    const UdpHeader *udpHeader, const NbnsHeader *message, size_t length)
00054 {
00055    size_t pos;
00056    DnsQuestion *question;
00057 
00058    //The NBNS query shall contain one question
00059    if(ntohs(message->qdcount) != 1)
00060       return;
00061 
00062    //Parse NetBIOS name
00063    pos = nbnsParseName(message, length, sizeof(DnsHeader), NULL);
00064 
00065    //Invalid name?
00066    if(!pos)
00067       return;
00068    //Malformed NBNS query message?
00069    if((pos + sizeof(DnsQuestion)) > length)
00070       return;
00071 
00072    //Point to the corresponding entry
00073    question = DNS_GET_QUESTION(message, pos);
00074 
00075    //Check the class and the type of the request
00076    if(ntohs(question->qclass) != DNS_RR_CLASS_IN)
00077       return;
00078    if(ntohs(question->qtype) != DNS_RR_TYPE_NB)
00079       return;
00080 
00081    //Compare NetBIOS names
00082    if(nbnsCompareName(message, length, sizeof(DnsHeader), interface->hostname))
00083    {
00084       uint16_t destPort;
00085       IpAddr destIpAddr;
00086 
00087       //A response packet is always sent to the source UDP port and
00088       //source IP address of the request packet
00089       destIpAddr.length = sizeof(Ipv4Addr);
00090       destIpAddr.ipv4Addr = pseudoHeader->srcAddr;
00091 
00092       //Convert the port number to host byte order
00093       destPort = ntohs(udpHeader->srcPort);
00094 
00095       //Send NBNS response
00096       nbnsSendResponse(interface, &destIpAddr, destPort, message->id);
00097    }
00098 }
00099 
00100 
00101 /**
00102  * @brief Send NBNS response message
00103  * @param[in] interface Underlying network interface
00104  * @param[in] destIpAddr Destination IP address
00105  * @param[in] destPort destination port
00106  * @param[in] id 16-bit identifier to be used when sending NBNS query
00107  **/
00108 
00109 error_t nbnsSendResponse(NetInterface *interface,
00110    const IpAddr *destIpAddr, uint16_t destPort, uint16_t id)
00111 {
00112    error_t error;
00113    size_t length;
00114    size_t offset;
00115    NetBuffer *buffer;
00116    NbnsHeader *message;
00117    NbnsAddrEntry *addrEntry;
00118    DnsResourceRecord *record;
00119 
00120    //Allocate a memory buffer to hold the NBNS response message
00121    buffer = udpAllocBuffer(DNS_MESSAGE_MAX_SIZE, &offset);
00122    //Failed to allocate buffer?
00123    if(buffer == NULL)
00124       return ERROR_OUT_OF_MEMORY;
00125 
00126    //Point to the NBNS header
00127    message = netBufferAt(buffer, offset);
00128 
00129    //Take the identifier from the query message
00130    message->id = id;
00131 
00132    //Format NBNS response header
00133    message->qr = 1;
00134    message->opcode = DNS_OPCODE_QUERY;
00135    message->aa = 1;
00136    message->tc = 0;
00137    message->rd = 1;
00138    message->ra = 1;
00139    message->z = 0;
00140    message->b = 0;
00141    message->rcode = DNS_RCODE_NO_ERROR;
00142 
00143    //The NBNS response contains 1 answer resource record
00144    message->qdcount = 0;
00145    message->ancount = HTONS(1);
00146    message->nscount = 0;
00147    message->arcount = 0;
00148 
00149    //NBNS response message length
00150    length = sizeof(DnsHeader);
00151 
00152    //Encode the host name using the NBNS name notation
00153    length += nbnsEncodeName(interface->hostname, (uint8_t *) message + length);
00154 
00155    //Point to the corresponding resource record
00156    record = DNS_GET_RESOURCE_RECORD(message, length);
00157    //Fill in resource record
00158    record->rtype = HTONS(DNS_RR_TYPE_NB);
00159    record->rclass = HTONS(DNS_RR_CLASS_IN);
00160    record->ttl = HTONL(NBNS_DEFAULT_RESOURCE_RECORD_TTL);
00161    record->rdlength = HTONS(sizeof(NbnsAddrEntry));
00162 
00163    //Point to the address entry array
00164    addrEntry = (NbnsAddrEntry *) record->rdata;
00165    //Fill in address entry
00166    addrEntry->flags = HTONS(NBNS_G_UNIQUE | NBNS_ONT_BNODE);
00167    addrEntry->addr = interface->ipv4Context.addr;
00168 
00169    //Update the length of the NBNS response message
00170    length += sizeof(DnsResourceRecord) + sizeof(NbnsAddrEntry);
00171 
00172    //Adjust the length of the multi-part buffer
00173    netBufferSetLength(buffer, offset + length);
00174 
00175    //Debug message
00176    TRACE_INFO("Sending NBNS message (%" PRIuSIZE " bytes)...\r\n", length);
00177    //Dump message
00178    dnsDumpMessage((DnsHeader *) message, length);
00179 
00180    //A response packet is always sent to the source UDP port and
00181    //source IP address of the request packet
00182    error = udpSendDatagramEx(interface, NBNS_PORT, destIpAddr,
00183       destPort, buffer, offset, IPV4_DEFAULT_TTL);
00184 
00185    //Free previously allocated memory
00186    netBufferFree(buffer);
00187    //Return status code
00188    return error;
00189 }
00190 
00191 #endif
00192