Webserver+3d print
cyclone_tcp/netbios/nbns_responder.c@0:8918a71cdbe9, 2017-02-04 (annotated)
- Committer:
- Sergunb
- Date:
- Sat Feb 04 18:15:49 2017 +0000
- Revision:
- 0:8918a71cdbe9
nothing else
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Sergunb | 0:8918a71cdbe9 | 1 | /** |
Sergunb | 0:8918a71cdbe9 | 2 | * @file nbns_responder.c |
Sergunb | 0:8918a71cdbe9 | 3 | * @brief NBNS responder (NetBIOS Name Service) |
Sergunb | 0:8918a71cdbe9 | 4 | * |
Sergunb | 0:8918a71cdbe9 | 5 | * @section License |
Sergunb | 0:8918a71cdbe9 | 6 | * |
Sergunb | 0:8918a71cdbe9 | 7 | * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. |
Sergunb | 0:8918a71cdbe9 | 8 | * |
Sergunb | 0:8918a71cdbe9 | 9 | * This file is part of CycloneTCP Open. |
Sergunb | 0:8918a71cdbe9 | 10 | * |
Sergunb | 0:8918a71cdbe9 | 11 | * This program is free software; you can redistribute it and/or |
Sergunb | 0:8918a71cdbe9 | 12 | * modify it under the terms of the GNU General Public License |
Sergunb | 0:8918a71cdbe9 | 13 | * as published by the Free Software Foundation; either version 2 |
Sergunb | 0:8918a71cdbe9 | 14 | * of the License, or (at your option) any later version. |
Sergunb | 0:8918a71cdbe9 | 15 | * |
Sergunb | 0:8918a71cdbe9 | 16 | * This program is distributed in the hope that it will be useful, |
Sergunb | 0:8918a71cdbe9 | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
Sergunb | 0:8918a71cdbe9 | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Sergunb | 0:8918a71cdbe9 | 19 | * GNU General Public License for more details. |
Sergunb | 0:8918a71cdbe9 | 20 | * |
Sergunb | 0:8918a71cdbe9 | 21 | * You should have received a copy of the GNU General Public License |
Sergunb | 0:8918a71cdbe9 | 22 | * along with this program; if not, write to the Free Software Foundation, |
Sergunb | 0:8918a71cdbe9 | 23 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
Sergunb | 0:8918a71cdbe9 | 24 | * |
Sergunb | 0:8918a71cdbe9 | 25 | * @author Oryx Embedded SARL (www.oryx-embedded.com) |
Sergunb | 0:8918a71cdbe9 | 26 | * @version 1.7.6 |
Sergunb | 0:8918a71cdbe9 | 27 | **/ |
Sergunb | 0:8918a71cdbe9 | 28 | |
Sergunb | 0:8918a71cdbe9 | 29 | //Switch to the appropriate trace level |
Sergunb | 0:8918a71cdbe9 | 30 | #define TRACE_LEVEL NBNS_TRACE_LEVEL |
Sergunb | 0:8918a71cdbe9 | 31 | |
Sergunb | 0:8918a71cdbe9 | 32 | //Dependencies |
Sergunb | 0:8918a71cdbe9 | 33 | #include "core/net.h" |
Sergunb | 0:8918a71cdbe9 | 34 | #include "netbios/nbns_responder.h" |
Sergunb | 0:8918a71cdbe9 | 35 | #include "netbios/nbns_common.h" |
Sergunb | 0:8918a71cdbe9 | 36 | #include "dns/dns_debug.h" |
Sergunb | 0:8918a71cdbe9 | 37 | #include "debug.h" |
Sergunb | 0:8918a71cdbe9 | 38 | |
Sergunb | 0:8918a71cdbe9 | 39 | //Check TCP/IP stack configuration |
Sergunb | 0:8918a71cdbe9 | 40 | #if (NBNS_RESPONDER_SUPPORT == ENABLED && IPV4_SUPPORT == ENABLED) |
Sergunb | 0:8918a71cdbe9 | 41 | |
Sergunb | 0:8918a71cdbe9 | 42 | |
Sergunb | 0:8918a71cdbe9 | 43 | /** |
Sergunb | 0:8918a71cdbe9 | 44 | * @brief Process NBNS query message |
Sergunb | 0:8918a71cdbe9 | 45 | * @param[in] interface Underlying network interface |
Sergunb | 0:8918a71cdbe9 | 46 | * @param[in] pseudoHeader UDP pseudo header |
Sergunb | 0:8918a71cdbe9 | 47 | * @param[in] udpHeader UDP header |
Sergunb | 0:8918a71cdbe9 | 48 | * @param[in] message Pointer to the NBNS query message |
Sergunb | 0:8918a71cdbe9 | 49 | * @param[in] length Length of the message |
Sergunb | 0:8918a71cdbe9 | 50 | **/ |
Sergunb | 0:8918a71cdbe9 | 51 | |
Sergunb | 0:8918a71cdbe9 | 52 | void nbnsProcessQuery(NetInterface *interface, const Ipv4PseudoHeader *pseudoHeader, |
Sergunb | 0:8918a71cdbe9 | 53 | const UdpHeader *udpHeader, const NbnsHeader *message, size_t length) |
Sergunb | 0:8918a71cdbe9 | 54 | { |
Sergunb | 0:8918a71cdbe9 | 55 | size_t pos; |
Sergunb | 0:8918a71cdbe9 | 56 | DnsQuestion *question; |
Sergunb | 0:8918a71cdbe9 | 57 | |
Sergunb | 0:8918a71cdbe9 | 58 | //The NBNS query shall contain one question |
Sergunb | 0:8918a71cdbe9 | 59 | if(ntohs(message->qdcount) != 1) |
Sergunb | 0:8918a71cdbe9 | 60 | return; |
Sergunb | 0:8918a71cdbe9 | 61 | |
Sergunb | 0:8918a71cdbe9 | 62 | //Parse NetBIOS name |
Sergunb | 0:8918a71cdbe9 | 63 | pos = nbnsParseName(message, length, sizeof(DnsHeader), NULL); |
Sergunb | 0:8918a71cdbe9 | 64 | |
Sergunb | 0:8918a71cdbe9 | 65 | //Invalid name? |
Sergunb | 0:8918a71cdbe9 | 66 | if(!pos) |
Sergunb | 0:8918a71cdbe9 | 67 | return; |
Sergunb | 0:8918a71cdbe9 | 68 | //Malformed NBNS query message? |
Sergunb | 0:8918a71cdbe9 | 69 | if((pos + sizeof(DnsQuestion)) > length) |
Sergunb | 0:8918a71cdbe9 | 70 | return; |
Sergunb | 0:8918a71cdbe9 | 71 | |
Sergunb | 0:8918a71cdbe9 | 72 | //Point to the corresponding entry |
Sergunb | 0:8918a71cdbe9 | 73 | question = DNS_GET_QUESTION(message, pos); |
Sergunb | 0:8918a71cdbe9 | 74 | |
Sergunb | 0:8918a71cdbe9 | 75 | //Check the class and the type of the request |
Sergunb | 0:8918a71cdbe9 | 76 | if(ntohs(question->qclass) != DNS_RR_CLASS_IN) |
Sergunb | 0:8918a71cdbe9 | 77 | return; |
Sergunb | 0:8918a71cdbe9 | 78 | if(ntohs(question->qtype) != DNS_RR_TYPE_NB) |
Sergunb | 0:8918a71cdbe9 | 79 | return; |
Sergunb | 0:8918a71cdbe9 | 80 | |
Sergunb | 0:8918a71cdbe9 | 81 | //Compare NetBIOS names |
Sergunb | 0:8918a71cdbe9 | 82 | if(nbnsCompareName(message, length, sizeof(DnsHeader), interface->hostname)) |
Sergunb | 0:8918a71cdbe9 | 83 | { |
Sergunb | 0:8918a71cdbe9 | 84 | uint16_t destPort; |
Sergunb | 0:8918a71cdbe9 | 85 | IpAddr destIpAddr; |
Sergunb | 0:8918a71cdbe9 | 86 | |
Sergunb | 0:8918a71cdbe9 | 87 | //A response packet is always sent to the source UDP port and |
Sergunb | 0:8918a71cdbe9 | 88 | //source IP address of the request packet |
Sergunb | 0:8918a71cdbe9 | 89 | destIpAddr.length = sizeof(Ipv4Addr); |
Sergunb | 0:8918a71cdbe9 | 90 | destIpAddr.ipv4Addr = pseudoHeader->srcAddr; |
Sergunb | 0:8918a71cdbe9 | 91 | |
Sergunb | 0:8918a71cdbe9 | 92 | //Convert the port number to host byte order |
Sergunb | 0:8918a71cdbe9 | 93 | destPort = ntohs(udpHeader->srcPort); |
Sergunb | 0:8918a71cdbe9 | 94 | |
Sergunb | 0:8918a71cdbe9 | 95 | //Send NBNS response |
Sergunb | 0:8918a71cdbe9 | 96 | nbnsSendResponse(interface, &destIpAddr, destPort, message->id); |
Sergunb | 0:8918a71cdbe9 | 97 | } |
Sergunb | 0:8918a71cdbe9 | 98 | } |
Sergunb | 0:8918a71cdbe9 | 99 | |
Sergunb | 0:8918a71cdbe9 | 100 | |
Sergunb | 0:8918a71cdbe9 | 101 | /** |
Sergunb | 0:8918a71cdbe9 | 102 | * @brief Send NBNS response message |
Sergunb | 0:8918a71cdbe9 | 103 | * @param[in] interface Underlying network interface |
Sergunb | 0:8918a71cdbe9 | 104 | * @param[in] destIpAddr Destination IP address |
Sergunb | 0:8918a71cdbe9 | 105 | * @param[in] destPort destination port |
Sergunb | 0:8918a71cdbe9 | 106 | * @param[in] id 16-bit identifier to be used when sending NBNS query |
Sergunb | 0:8918a71cdbe9 | 107 | **/ |
Sergunb | 0:8918a71cdbe9 | 108 | |
Sergunb | 0:8918a71cdbe9 | 109 | error_t nbnsSendResponse(NetInterface *interface, |
Sergunb | 0:8918a71cdbe9 | 110 | const IpAddr *destIpAddr, uint16_t destPort, uint16_t id) |
Sergunb | 0:8918a71cdbe9 | 111 | { |
Sergunb | 0:8918a71cdbe9 | 112 | error_t error; |
Sergunb | 0:8918a71cdbe9 | 113 | size_t length; |
Sergunb | 0:8918a71cdbe9 | 114 | size_t offset; |
Sergunb | 0:8918a71cdbe9 | 115 | NetBuffer *buffer; |
Sergunb | 0:8918a71cdbe9 | 116 | NbnsHeader *message; |
Sergunb | 0:8918a71cdbe9 | 117 | NbnsAddrEntry *addrEntry; |
Sergunb | 0:8918a71cdbe9 | 118 | DnsResourceRecord *record; |
Sergunb | 0:8918a71cdbe9 | 119 | |
Sergunb | 0:8918a71cdbe9 | 120 | //Allocate a memory buffer to hold the NBNS response message |
Sergunb | 0:8918a71cdbe9 | 121 | buffer = udpAllocBuffer(DNS_MESSAGE_MAX_SIZE, &offset); |
Sergunb | 0:8918a71cdbe9 | 122 | //Failed to allocate buffer? |
Sergunb | 0:8918a71cdbe9 | 123 | if(buffer == NULL) |
Sergunb | 0:8918a71cdbe9 | 124 | return ERROR_OUT_OF_MEMORY; |
Sergunb | 0:8918a71cdbe9 | 125 | |
Sergunb | 0:8918a71cdbe9 | 126 | //Point to the NBNS header |
Sergunb | 0:8918a71cdbe9 | 127 | message = netBufferAt(buffer, offset); |
Sergunb | 0:8918a71cdbe9 | 128 | |
Sergunb | 0:8918a71cdbe9 | 129 | //Take the identifier from the query message |
Sergunb | 0:8918a71cdbe9 | 130 | message->id = id; |
Sergunb | 0:8918a71cdbe9 | 131 | |
Sergunb | 0:8918a71cdbe9 | 132 | //Format NBNS response header |
Sergunb | 0:8918a71cdbe9 | 133 | message->qr = 1; |
Sergunb | 0:8918a71cdbe9 | 134 | message->opcode = DNS_OPCODE_QUERY; |
Sergunb | 0:8918a71cdbe9 | 135 | message->aa = 1; |
Sergunb | 0:8918a71cdbe9 | 136 | message->tc = 0; |
Sergunb | 0:8918a71cdbe9 | 137 | message->rd = 1; |
Sergunb | 0:8918a71cdbe9 | 138 | message->ra = 1; |
Sergunb | 0:8918a71cdbe9 | 139 | message->z = 0; |
Sergunb | 0:8918a71cdbe9 | 140 | message->b = 0; |
Sergunb | 0:8918a71cdbe9 | 141 | message->rcode = DNS_RCODE_NO_ERROR; |
Sergunb | 0:8918a71cdbe9 | 142 | |
Sergunb | 0:8918a71cdbe9 | 143 | //The NBNS response contains 1 answer resource record |
Sergunb | 0:8918a71cdbe9 | 144 | message->qdcount = 0; |
Sergunb | 0:8918a71cdbe9 | 145 | message->ancount = HTONS(1); |
Sergunb | 0:8918a71cdbe9 | 146 | message->nscount = 0; |
Sergunb | 0:8918a71cdbe9 | 147 | message->arcount = 0; |
Sergunb | 0:8918a71cdbe9 | 148 | |
Sergunb | 0:8918a71cdbe9 | 149 | //NBNS response message length |
Sergunb | 0:8918a71cdbe9 | 150 | length = sizeof(DnsHeader); |
Sergunb | 0:8918a71cdbe9 | 151 | |
Sergunb | 0:8918a71cdbe9 | 152 | //Encode the host name using the NBNS name notation |
Sergunb | 0:8918a71cdbe9 | 153 | length += nbnsEncodeName(interface->hostname, (uint8_t *) message + length); |
Sergunb | 0:8918a71cdbe9 | 154 | |
Sergunb | 0:8918a71cdbe9 | 155 | //Point to the corresponding resource record |
Sergunb | 0:8918a71cdbe9 | 156 | record = DNS_GET_RESOURCE_RECORD(message, length); |
Sergunb | 0:8918a71cdbe9 | 157 | //Fill in resource record |
Sergunb | 0:8918a71cdbe9 | 158 | record->rtype = HTONS(DNS_RR_TYPE_NB); |
Sergunb | 0:8918a71cdbe9 | 159 | record->rclass = HTONS(DNS_RR_CLASS_IN); |
Sergunb | 0:8918a71cdbe9 | 160 | record->ttl = HTONL(NBNS_DEFAULT_RESOURCE_RECORD_TTL); |
Sergunb | 0:8918a71cdbe9 | 161 | record->rdlength = HTONS(sizeof(NbnsAddrEntry)); |
Sergunb | 0:8918a71cdbe9 | 162 | |
Sergunb | 0:8918a71cdbe9 | 163 | //Point to the address entry array |
Sergunb | 0:8918a71cdbe9 | 164 | addrEntry = (NbnsAddrEntry *) record->rdata; |
Sergunb | 0:8918a71cdbe9 | 165 | //Fill in address entry |
Sergunb | 0:8918a71cdbe9 | 166 | addrEntry->flags = HTONS(NBNS_G_UNIQUE | NBNS_ONT_BNODE); |
Sergunb | 0:8918a71cdbe9 | 167 | addrEntry->addr = interface->ipv4Context.addr; |
Sergunb | 0:8918a71cdbe9 | 168 | |
Sergunb | 0:8918a71cdbe9 | 169 | //Update the length of the NBNS response message |
Sergunb | 0:8918a71cdbe9 | 170 | length += sizeof(DnsResourceRecord) + sizeof(NbnsAddrEntry); |
Sergunb | 0:8918a71cdbe9 | 171 | |
Sergunb | 0:8918a71cdbe9 | 172 | //Adjust the length of the multi-part buffer |
Sergunb | 0:8918a71cdbe9 | 173 | netBufferSetLength(buffer, offset + length); |
Sergunb | 0:8918a71cdbe9 | 174 | |
Sergunb | 0:8918a71cdbe9 | 175 | //Debug message |
Sergunb | 0:8918a71cdbe9 | 176 | TRACE_INFO("Sending NBNS message (%" PRIuSIZE " bytes)...\r\n", length); |
Sergunb | 0:8918a71cdbe9 | 177 | //Dump message |
Sergunb | 0:8918a71cdbe9 | 178 | dnsDumpMessage((DnsHeader *) message, length); |
Sergunb | 0:8918a71cdbe9 | 179 | |
Sergunb | 0:8918a71cdbe9 | 180 | //A response packet is always sent to the source UDP port and |
Sergunb | 0:8918a71cdbe9 | 181 | //source IP address of the request packet |
Sergunb | 0:8918a71cdbe9 | 182 | error = udpSendDatagramEx(interface, NBNS_PORT, destIpAddr, |
Sergunb | 0:8918a71cdbe9 | 183 | destPort, buffer, offset, IPV4_DEFAULT_TTL); |
Sergunb | 0:8918a71cdbe9 | 184 | |
Sergunb | 0:8918a71cdbe9 | 185 | //Free previously allocated memory |
Sergunb | 0:8918a71cdbe9 | 186 | netBufferFree(buffer); |
Sergunb | 0:8918a71cdbe9 | 187 | //Return status code |
Sergunb | 0:8918a71cdbe9 | 188 | return error; |
Sergunb | 0:8918a71cdbe9 | 189 | } |
Sergunb | 0:8918a71cdbe9 | 190 | |
Sergunb | 0:8918a71cdbe9 | 191 | #endif |
Sergunb | 0:8918a71cdbe9 | 192 |