1 /** 2 * @file 3 * NetBIOS name service responder 4 */ 5 6 /** 7 * @defgroup netbiosns NETBIOS responder 8 * @ingroup apps 9 * 10 * This is an example implementation of a NetBIOS name server. 11 * It responds to name queries for a configurable name. 12 * Name resolving is not supported. 13 * 14 * Note that the device doesn't broadcast it's own name so can't 15 * detect duplicate names! 16 */ 17 18 /* 19 * Redistribution and use in source and binary forms, with or without modification, 20 * are permitted provided that the following conditions are met: 21 * 22 * 1. Redistributions of source code must retain the above copyright notice, 23 * this list of conditions and the following disclaimer. 24 * 2. Redistributions in binary form must reproduce the above copyright notice, 25 * this list of conditions and the following disclaimer in the documentation 26 * and/or other materials provided with the distribution. 27 * 3. The name of the author may not be used to endorse or promote products 28 * derived from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 31 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 32 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 33 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 35 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 39 * OF SUCH DAMAGE. 40 * 41 * This file is part of the lwIP TCP/IP stack. 42 * 43 * Modifications by Ray Abram to respond to NetBIOS name requests when Incoming name = * 44 * - based on code from "https://github.com/esp8266/Arduino/commit/1f7989b31d26d7df9776a08f36d685eae7ac8f99" 45 * - with permission to relicense to BSD from original author: 46 * http://www.xpablo.cz/?p=751#more-751 47 */ 48 49 #include "lwip/apps/netbiosns.h" 50 51 #if LWIP_IPV4 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */ 52 53 #include "lwip/def.h" 54 #include "lwip/udp.h" 55 #include "lwip/ip.h" 56 #include "lwip/netif.h" 57 #include "lwip/prot/iana.h" 58 59 #include <string.h> 60 61 /** size of a NetBIOS name */ 62 #define NETBIOS_NAME_LEN 16 63 64 /** The Time-To-Live for NetBIOS name responds (in seconds) 65 * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */ 66 #define NETBIOS_NAME_TTL 300000u 67 68 /** NetBIOS header flags */ 69 #define NETB_HFLAG_RESPONSE 0x8000U 70 #define NETB_HFLAG_OPCODE 0x7800U 71 #define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U 72 #define NETB_HFLAG_AUTHORATIVE 0x0400U 73 #define NETB_HFLAG_TRUNCATED 0x0200U 74 #define NETB_HFLAG_RECURS_DESIRED 0x0100U 75 #define NETB_HFLAG_RECURS_AVAILABLE 0x0080U 76 #define NETB_HFLAG_BROADCAST 0x0010U 77 #define NETB_HFLAG_REPLYCODE 0x0008U 78 #define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U 79 80 /* NetBIOS question types */ 81 #define NETB_QTYPE_NB 0x0020U 82 #define NETB_QTYPE_NBSTAT 0x0021U 83 84 /** NetBIOS name flags */ 85 #define NETB_NFLAG_UNIQUE 0x8000U 86 #define NETB_NFLAG_NODETYPE 0x6000U 87 #define NETB_NFLAG_NODETYPE_HNODE 0x6000U 88 #define NETB_NFLAG_NODETYPE_MNODE 0x4000U 89 #define NETB_NFLAG_NODETYPE_PNODE 0x2000U 90 #define NETB_NFLAG_NODETYPE_BNODE 0x0000U 91 92 #define NETB_NFLAG_NAME_IN_CONFLICT 0x0800U /* 1=Yes, 0=No */ 93 #define NETB_NFLAG_NAME_IS_ACTIVE 0x0400U /* 1=Yes, 0=No */ 94 #define NETB_NFLAG_NAME_IS_PERMANENT 0x0200U /* 1=Yes (Name is Permanent Node Name), 0=No */ 95 96 /** NetBIOS message header */ 97 #ifdef PACK_STRUCT_USE_INCLUDES 98 # include "arch/bpstruct.h" 99 #endif 100 PACK_STRUCT_BEGIN 101 struct netbios_hdr { 102 PACK_STRUCT_FIELD(u16_t trans_id); 103 PACK_STRUCT_FIELD(u16_t flags); 104 PACK_STRUCT_FIELD(u16_t questions); 105 PACK_STRUCT_FIELD(u16_t answerRRs); 106 PACK_STRUCT_FIELD(u16_t authorityRRs); 107 PACK_STRUCT_FIELD(u16_t additionalRRs); 108 } PACK_STRUCT_STRUCT; 109 PACK_STRUCT_END 110 #ifdef PACK_STRUCT_USE_INCLUDES 111 # include "arch/epstruct.h" 112 #endif 113 114 /** NetBIOS message question part */ 115 #ifdef PACK_STRUCT_USE_INCLUDES 116 # include "arch/bpstruct.h" 117 #endif 118 PACK_STRUCT_BEGIN 119 struct netbios_question_hdr { 120 PACK_STRUCT_FLD_8(u8_t nametype); 121 PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN * 2) + 1]); 122 PACK_STRUCT_FIELD(u16_t type); 123 PACK_STRUCT_FIELD(u16_t cls); 124 } PACK_STRUCT_STRUCT; 125 PACK_STRUCT_END 126 #ifdef PACK_STRUCT_USE_INCLUDES 127 # include "arch/epstruct.h" 128 #endif 129 130 /** NetBIOS message name part */ 131 #ifdef PACK_STRUCT_USE_INCLUDES 132 # include "arch/bpstruct.h" 133 #endif 134 PACK_STRUCT_BEGIN 135 struct netbios_name_hdr { 136 PACK_STRUCT_FLD_8(u8_t nametype); 137 PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN * 2) + 1]); 138 PACK_STRUCT_FIELD(u16_t type); 139 PACK_STRUCT_FIELD(u16_t cls); 140 PACK_STRUCT_FIELD(u32_t ttl); 141 PACK_STRUCT_FIELD(u16_t datalen); 142 PACK_STRUCT_FIELD(u16_t flags); 143 PACK_STRUCT_FLD_S(ip4_addr_p_t addr); 144 } PACK_STRUCT_STRUCT; 145 PACK_STRUCT_END 146 #ifdef PACK_STRUCT_USE_INCLUDES 147 # include "arch/epstruct.h" 148 #endif 149 150 /** NetBIOS message */ 151 #ifdef PACK_STRUCT_USE_INCLUDES 152 # include "arch/bpstruct.h" 153 #endif 154 PACK_STRUCT_BEGIN 155 struct netbios_resp { 156 struct netbios_hdr resp_hdr; 157 struct netbios_name_hdr resp_name; 158 } PACK_STRUCT_STRUCT; 159 PACK_STRUCT_END 160 #ifdef PACK_STRUCT_USE_INCLUDES 161 # include "arch/epstruct.h" 162 #endif 163 164 /** The NBNS Structure Responds to a Name Query */ 165 #ifdef PACK_STRUCT_USE_INCLUDES 166 # include "arch/bpstruct.h" 167 #endif 168 PACK_STRUCT_BEGIN 169 struct netbios_answer { 170 struct netbios_hdr answer_hdr; 171 /** the length of the next string */ 172 PACK_STRUCT_FIELD(u8_t name_size); 173 /** WARNING!!! this item may be of a different length (we use this struct for transmission) */ 174 PACK_STRUCT_FLD_8(u8_t query_name[(NETBIOS_NAME_LEN * 2) + 1]); 175 PACK_STRUCT_FIELD(u16_t packet_type); 176 PACK_STRUCT_FIELD(u16_t cls); 177 PACK_STRUCT_FIELD(u32_t ttl); 178 PACK_STRUCT_FIELD(u16_t data_length); 179 #define OFFSETOF_STRUCT_NETBIOS_ANSWER_NUMBER_OF_NAMES 56 180 /** number of names */ 181 PACK_STRUCT_FLD_8(u8_t number_of_names); 182 /** node name */ 183 PACK_STRUCT_FLD_8(u8_t answer_name[NETBIOS_NAME_LEN]); 184 /** node flags */ 185 PACK_STRUCT_FIELD(u16_t answer_name_flags); 186 /** Unit ID */ 187 PACK_STRUCT_FLD_8(u8_t unit_id[6]); 188 /** Jumpers */ 189 PACK_STRUCT_FLD_8(u8_t jumpers); 190 /** Test result */ 191 PACK_STRUCT_FLD_8(u8_t test_result); 192 /** Version number */ 193 PACK_STRUCT_FIELD(u16_t version_number); 194 /** Period of statistics */ 195 PACK_STRUCT_FIELD(u16_t period_of_statistics); 196 /** Statistics */ 197 PACK_STRUCT_FIELD(u16_t number_of_crcs); 198 /** Statistics */ 199 PACK_STRUCT_FIELD(u16_t number_of_alignment_errors); 200 /** Statistics */ 201 PACK_STRUCT_FIELD(u16_t number_of_collisions); 202 /** Statistics */ 203 PACK_STRUCT_FIELD(u16_t number_of_send_aborts); 204 /** Statistics */ 205 PACK_STRUCT_FIELD(u32_t number_of_good_sends); 206 /** Statistics */ 207 PACK_STRUCT_FIELD(u32_t number_of_good_receives); 208 /** Statistics */ 209 PACK_STRUCT_FIELD(u16_t number_of_retransmits); 210 /** Statistics */ 211 PACK_STRUCT_FIELD(u16_t number_of_no_resource_condition); 212 /** Statistics */ 213 PACK_STRUCT_FIELD(u16_t number_of_free_command_blocks); 214 /** Statistics */ 215 PACK_STRUCT_FIELD(u16_t total_number_of_command_blocks); 216 /** Statistics */ 217 PACK_STRUCT_FIELD(u16_t max_total_number_of_command_blocks); 218 /** Statistics */ 219 PACK_STRUCT_FIELD(u16_t number_of_pending_sessions); 220 /** Statistics */ 221 PACK_STRUCT_FIELD(u16_t max_number_of_pending_sessions); 222 /** Statistics */ 223 PACK_STRUCT_FIELD(u16_t max_total_sessions_possible); 224 /** Statistics */ 225 PACK_STRUCT_FIELD(u16_t session_data_packet_size); 226 } PACK_STRUCT_STRUCT; 227 PACK_STRUCT_END 228 #ifdef PACK_STRUCT_USE_INCLUDES 229 # include "arch/epstruct.h" 230 #endif 231 232 #ifdef NETBIOS_LWIP_NAME 233 #define NETBIOS_LOCAL_NAME NETBIOS_LWIP_NAME 234 #else 235 static char netbiosns_local_name[NETBIOS_NAME_LEN]; 236 #define NETBIOS_LOCAL_NAME netbiosns_local_name 237 #endif 238 239 static struct udp_pcb *netbiosns_pcb; 240 241 /** Decode a NetBIOS name (from packet to string) */ 242 static int 243 netbiosns_name_decode(const char *name_enc, char *name_dec, int name_dec_len) 244 { 245 const char *pname; 246 char cname; 247 char cnbname; 248 int idx = 0; 249 250 LWIP_UNUSED_ARG(name_dec_len); 251 252 /* Start decoding netbios name. */ 253 pname = name_enc; 254 for (;;) { 255 /* Every two characters of the first level-encoded name 256 * turn into one character in the decoded name. */ 257 cname = *pname; 258 if (cname == '\0') { 259 break; /* no more characters */ 260 } 261 if (cname == '.') { 262 break; /* scope ID follows */ 263 } 264 if (!lwip_isupper(cname)) { 265 /* Not legal. */ 266 return -1; 267 } 268 cname -= 'A'; 269 cnbname = cname << 4; 270 pname++; 271 272 cname = *pname; 273 if (!lwip_isupper(cname)) { 274 /* Not legal. */ 275 return -1; 276 } 277 cname -= 'A'; 278 cnbname |= cname; 279 pname++; 280 281 /* Do we have room to store the character? */ 282 if (idx < NETBIOS_NAME_LEN) { 283 /* Yes - store the character. */ 284 name_dec[idx++] = (cnbname != ' ' ? cnbname : '\0'); 285 } 286 } 287 288 return 0; 289 } 290 291 #if 0 /* function currently unused */ 292 /** Encode a NetBIOS name (from string to packet) - currently unused because 293 we don't ask for names. */ 294 static int 295 netbiosns_name_encode(char *name_enc, char *name_dec, int name_dec_len) 296 { 297 char *pname; 298 char cname; 299 unsigned char ucname; 300 int idx = 0; 301 302 /* Start encoding netbios name. */ 303 pname = name_enc; 304 305 for (;;) { 306 /* Every two characters of the first level-encoded name 307 * turn into one character in the decoded name. */ 308 cname = *pname; 309 if (cname == '\0') { 310 break; /* no more characters */ 311 } 312 if (cname == '.') { 313 break; /* scope ID follows */ 314 } 315 if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) { 316 /* Not legal. */ 317 return -1; 318 } 319 320 /* Do we have room to store the character? */ 321 if (idx >= name_dec_len) { 322 return -1; 323 } 324 325 /* Yes - store the character. */ 326 ucname = cname; 327 name_dec[idx++] = ('A' + ((ucname >> 4) & 0x0F)); 328 name_dec[idx++] = ('A' + ( ucname & 0x0F)); 329 pname++; 330 } 331 332 /* Fill with "space" coding */ 333 for (; idx < name_dec_len - 1;) { 334 name_dec[idx++] = 'C'; 335 name_dec[idx++] = 'A'; 336 } 337 338 /* Terminate string */ 339 name_dec[idx] = '\0'; 340 341 return 0; 342 } 343 #endif /* 0 */ 344 345 /** NetBIOS Name service recv callback */ 346 static void 347 netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) 348 { 349 LWIP_UNUSED_ARG(arg); 350 351 /* if packet is valid */ 352 if (p != NULL) { 353 char netbios_name[NETBIOS_NAME_LEN + 1]; 354 struct netbios_hdr *netbios_hdr = (struct netbios_hdr *)p->payload; 355 struct netbios_question_hdr *netbios_question_hdr = (struct netbios_question_hdr *)(netbios_hdr + 1); 356 357 /* is the packet long enough (we need the header in one piece) */ 358 if (p->len < (sizeof(struct netbios_hdr) + sizeof(struct netbios_question_hdr))) { 359 /* packet too short */ 360 pbuf_free(p); 361 return; 362 } 363 /* we only answer if we got a default interface */ 364 if (netif_default != NULL) { 365 /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */ 366 /* if the packet is a NetBIOS name query question */ 367 if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) && 368 ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) && 369 (netbios_hdr->questions == PP_NTOHS(1))) { 370 /* decode the NetBIOS name */ 371 netbiosns_name_decode((char *)(netbios_question_hdr->encname), netbios_name, sizeof(netbios_name)); 372 /* check the request type */ 373 if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NB)) { 374 /* if the packet is for us */ 375 if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) { 376 struct pbuf *q; 377 struct netbios_resp *resp; 378 379 q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM); 380 if (q != NULL) { 381 resp = (struct netbios_resp *)q->payload; 382 383 /* prepare NetBIOS header response */ 384 resp->resp_hdr.trans_id = netbios_hdr->trans_id; 385 resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | 386 NETB_HFLAG_OPCODE_NAME_QUERY | 387 NETB_HFLAG_AUTHORATIVE | 388 NETB_HFLAG_RECURS_DESIRED); 389 resp->resp_hdr.questions = 0; 390 resp->resp_hdr.answerRRs = PP_HTONS(1); 391 resp->resp_hdr.authorityRRs = 0; 392 resp->resp_hdr.additionalRRs = 0; 393 394 /* prepare NetBIOS header datas */ 395 MEMCPY( resp->resp_name.encname, netbios_question_hdr->encname, sizeof(netbios_question_hdr->encname)); 396 resp->resp_name.nametype = netbios_question_hdr->nametype; 397 resp->resp_name.type = netbios_question_hdr->type; 398 resp->resp_name.cls = netbios_question_hdr->cls; 399 resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL); 400 resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags) + sizeof(resp->resp_name.addr)); 401 resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE); 402 ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default)); 403 404 /* send the NetBIOS response */ 405 udp_sendto(upcb, q, addr, port); 406 407 /* free the "reference" pbuf */ 408 pbuf_free(q); 409 } 410 } 411 #if LWIP_NETBIOS_RESPOND_NAME_QUERY 412 } else if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) { 413 /* if the packet is for us or general query */ 414 if (!lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) || 415 !lwip_strnicmp(netbios_name, "*", sizeof(NETBIOS_LOCAL_NAME))) { 416 /* general query - ask for our IP address */ 417 struct pbuf *q; 418 struct netbios_answer *resp; 419 420 q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_answer), PBUF_RAM); 421 if (q != NULL) { 422 /* buffer to which a response is compiled */ 423 resp = (struct netbios_answer *) q->payload; 424 425 /* Init response to zero, especially the statistics fields */ 426 memset(resp, 0, sizeof(*resp)); 427 428 /* copy the query to the response ID */ 429 resp->answer_hdr.trans_id = netbios_hdr->trans_id; 430 /* acknowledgment of termination */ 431 resp->answer_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE); 432 /* resp->answer_hdr.questions = PP_HTONS(0); done by memset() */ 433 /* serial number of the answer */ 434 resp->answer_hdr.answerRRs = PP_HTONS(1); 435 /* resp->answer_hdr.authorityRRs = PP_HTONS(0); done by memset() */ 436 /* resp->answer_hdr.additionalRRs = PP_HTONS(0); done by memset() */ 437 /* we will copy the length of the station name */ 438 resp->name_size = netbios_question_hdr->nametype; 439 /* we will copy the queried name */ 440 MEMCPY(resp->query_name, netbios_question_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1); 441 /* NBSTAT */ 442 resp->packet_type = PP_HTONS(0x21); 443 /* Internet name */ 444 resp->cls = PP_HTONS(1); 445 /* resp->ttl = PP_HTONL(0); done by memset() */ 446 resp->data_length = PP_HTONS(sizeof(struct netbios_answer) - offsetof(struct netbios_answer, number_of_names)); 447 resp->number_of_names = 1; 448 449 /* make windows see us as workstation, not as a server */ 450 memset(resp->answer_name, 0x20, NETBIOS_NAME_LEN - 1); 451 /* strlen is checked to be < NETBIOS_NAME_LEN during initialization */ 452 MEMCPY(resp->answer_name, NETBIOS_LOCAL_NAME, strlen(NETBIOS_LOCAL_NAME)); 453 454 /* b-node, unique, active */ 455 resp->answer_name_flags = PP_HTONS(NETB_NFLAG_NAME_IS_ACTIVE); 456 457 /* Set responder netif MAC address */ 458 SMEMCPY(resp->unit_id, ip_current_input_netif()->hwaddr, sizeof(resp->unit_id)); 459 460 udp_sendto(upcb, q, addr, port); 461 pbuf_free(q); 462 } 463 } 464 #endif /* LWIP_NETBIOS_RESPOND_NAME_QUERY */ 465 } 466 } 467 } 468 /* free the pbuf */ 469 pbuf_free(p); 470 } 471 } 472 473 /** 474 * @ingroup netbiosns 475 * Init netbios responder 476 */ 477 void 478 netbiosns_init(void) 479 { 480 /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */ 481 #ifdef NETBIOS_LWIP_NAME 482 LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN); 483 #endif 484 485 netbiosns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); 486 if (netbiosns_pcb != NULL) { 487 /* we have to be allowed to send broadcast packets! */ 488 ip_set_option(netbiosns_pcb, SOF_BROADCAST); 489 udp_bind(netbiosns_pcb, IP_ANY_TYPE, LWIP_IANA_PORT_NETBIOS); 490 udp_recv(netbiosns_pcb, netbiosns_recv, netbiosns_pcb); 491 } 492 } 493 494 #ifndef NETBIOS_LWIP_NAME 495 /** 496 * @ingroup netbiosns 497 * Set netbios name. ATTENTION: the hostname must be less than 15 characters! 498 * the NetBIOS name spec says the name MUST be upper case, so incoming name is forced into uppercase :-) 499 */ 500 void 501 netbiosns_set_name(const char *hostname) 502 { 503 size_t i; 504 size_t copy_len = strlen(hostname); 505 LWIP_ASSERT_CORE_LOCKED(); 506 LWIP_ASSERT("NetBIOS name is too long!", copy_len < NETBIOS_NAME_LEN); 507 if (copy_len >= NETBIOS_NAME_LEN) { 508 copy_len = NETBIOS_NAME_LEN - 1; 509 } 510 511 /* make name into upper case */ 512 for (i = 0; i < copy_len; i++ ) { 513 netbiosns_local_name[i] = (char)lwip_toupper(hostname[i]); 514 } 515 netbiosns_local_name[copy_len] = '\0'; 516 } 517 #endif /* NETBIOS_LWIP_NAME */ 518 519 /** 520 * @ingroup netbiosns 521 * Stop netbios responder 522 */ 523 void 524 netbiosns_stop(void) 525 { 526 LWIP_ASSERT_CORE_LOCKED(); 527 if (netbiosns_pcb != NULL) { 528 udp_remove(netbiosns_pcb); 529 netbiosns_pcb = NULL; 530 } 531 } 532 533 #endif /* LWIP_IPV4 && LWIP_UDP */ 534