Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
lwip_netbiosns.c
00001 /** 00002 * @file 00003 * NetBIOS name service responder 00004 */ 00005 00006 /** 00007 * @defgroup netbiosns NETBIOS responder 00008 * @ingroup apps 00009 * 00010 * This is an example implementation of a NetBIOS name server. 00011 * It responds to name queries for a configurable name. 00012 * Name resolving is not supported. 00013 * 00014 * Note that the device doesn't broadcast it's own name so can't 00015 * detect duplicate names! 00016 */ 00017 00018 /* 00019 * Redistribution and use in source and binary forms, with or without modification, 00020 * are permitted provided that the following conditions are met: 00021 * 00022 * 1. Redistributions of source code must retain the above copyright notice, 00023 * this list of conditions and the following disclaimer. 00024 * 2. Redistributions in binary form must reproduce the above copyright notice, 00025 * this list of conditions and the following disclaimer in the documentation 00026 * and/or other materials provided with the distribution. 00027 * 3. The name of the author may not be used to endorse or promote products 00028 * derived from this software without specific prior written permission. 00029 * 00030 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00031 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00032 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00033 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00034 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00035 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00036 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00037 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00038 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00039 * OF SUCH DAMAGE. 00040 * 00041 * This file is part of the lwIP TCP/IP stack. 00042 * 00043 * Modifications by Ray Abram to respond to NetBIOS name requests when Incoming name = * 00044 * - based on code from "https://github.com/esp8266/Arduino/commit/1f7989b31d26d7df9776a08f36d685eae7ac8f99" 00045 * - with permission to relicense to BSD from original author: 00046 * http://www.xpablo.cz/?p=751#more-751 00047 */ 00048 00049 #include "lwip/apps/netbiosns.h" 00050 00051 #if LWIP_IPV4 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */ 00052 00053 #include "lwip/def.h" 00054 #include "lwip/udp.h" 00055 #include "lwip/ip.h" 00056 #include "lwip/netif.h" 00057 #include "lwip/prot/iana.h" 00058 00059 #include <string.h> 00060 00061 /** size of a NetBIOS name */ 00062 #define NETBIOS_NAME_LEN 16 00063 00064 /** The Time-To-Live for NetBIOS name responds (in seconds) 00065 * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */ 00066 #define NETBIOS_NAME_TTL 300000u 00067 00068 /** NetBIOS header flags */ 00069 #define NETB_HFLAG_RESPONSE 0x8000U 00070 #define NETB_HFLAG_OPCODE 0x7800U 00071 #define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U 00072 #define NETB_HFLAG_AUTHORATIVE 0x0400U 00073 #define NETB_HFLAG_TRUNCATED 0x0200U 00074 #define NETB_HFLAG_RECURS_DESIRED 0x0100U 00075 #define NETB_HFLAG_RECURS_AVAILABLE 0x0080U 00076 #define NETB_HFLAG_BROADCAST 0x0010U 00077 #define NETB_HFLAG_REPLYCODE 0x0008U 00078 #define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U 00079 00080 /* NetBIOS question types */ 00081 #define NETB_QTYPE_NB 0x0020U 00082 #define NETB_QTYPE_NBSTAT 0x0021U 00083 00084 /** NetBIOS name flags */ 00085 #define NETB_NFLAG_UNIQUE 0x8000U 00086 #define NETB_NFLAG_NODETYPE 0x6000U 00087 #define NETB_NFLAG_NODETYPE_HNODE 0x6000U 00088 #define NETB_NFLAG_NODETYPE_MNODE 0x4000U 00089 #define NETB_NFLAG_NODETYPE_PNODE 0x2000U 00090 #define NETB_NFLAG_NODETYPE_BNODE 0x0000U 00091 00092 #define NETB_NFLAG_NAME_IN_CONFLICT 0x0800U /* 1=Yes, 0=No */ 00093 #define NETB_NFLAG_NAME_IS_ACTIVE 0x0400U /* 1=Yes, 0=No */ 00094 #define NETB_NFLAG_NAME_IS_PERMANENT 0x0200U /* 1=Yes (Name is Permanent Node Name), 0=No */ 00095 00096 /** NetBIOS message header */ 00097 #ifdef PACK_STRUCT_USE_INCLUDES 00098 # include "arch/bpstruct.h" 00099 #endif 00100 PACK_STRUCT_BEGIN 00101 struct netbios_hdr { 00102 PACK_STRUCT_FIELD(u16_t trans_id); 00103 PACK_STRUCT_FIELD(u16_t flags); 00104 PACK_STRUCT_FIELD(u16_t questions); 00105 PACK_STRUCT_FIELD(u16_t answerRRs); 00106 PACK_STRUCT_FIELD(u16_t authorityRRs); 00107 PACK_STRUCT_FIELD(u16_t additionalRRs); 00108 } PACK_STRUCT_STRUCT; 00109 PACK_STRUCT_END 00110 #ifdef PACK_STRUCT_USE_INCLUDES 00111 # include "arch/epstruct.h" 00112 #endif 00113 00114 /** NetBIOS message question part */ 00115 #ifdef PACK_STRUCT_USE_INCLUDES 00116 # include "arch/bpstruct.h" 00117 #endif 00118 PACK_STRUCT_BEGIN 00119 struct netbios_question_hdr { 00120 PACK_STRUCT_FLD_8(u8_t nametype); 00121 PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN * 2) + 1]); 00122 PACK_STRUCT_FIELD(u16_t type); 00123 PACK_STRUCT_FIELD(u16_t cls); 00124 } PACK_STRUCT_STRUCT; 00125 PACK_STRUCT_END 00126 #ifdef PACK_STRUCT_USE_INCLUDES 00127 # include "arch/epstruct.h" 00128 #endif 00129 00130 /** NetBIOS message name part */ 00131 #ifdef PACK_STRUCT_USE_INCLUDES 00132 # include "arch/bpstruct.h" 00133 #endif 00134 PACK_STRUCT_BEGIN 00135 struct netbios_name_hdr { 00136 PACK_STRUCT_FLD_8(u8_t nametype); 00137 PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN * 2) + 1]); 00138 PACK_STRUCT_FIELD(u16_t type); 00139 PACK_STRUCT_FIELD(u16_t cls); 00140 PACK_STRUCT_FIELD(u32_t ttl); 00141 PACK_STRUCT_FIELD(u16_t datalen); 00142 PACK_STRUCT_FIELD(u16_t flags); 00143 PACK_STRUCT_FLD_S(ip4_addr_p_t addr); 00144 } PACK_STRUCT_STRUCT; 00145 PACK_STRUCT_END 00146 #ifdef PACK_STRUCT_USE_INCLUDES 00147 # include "arch/epstruct.h" 00148 #endif 00149 00150 /** NetBIOS message */ 00151 #ifdef PACK_STRUCT_USE_INCLUDES 00152 # include "arch/bpstruct.h" 00153 #endif 00154 PACK_STRUCT_BEGIN 00155 struct netbios_resp { 00156 struct netbios_hdr resp_hdr; 00157 struct netbios_name_hdr resp_name; 00158 } PACK_STRUCT_STRUCT; 00159 PACK_STRUCT_END 00160 #ifdef PACK_STRUCT_USE_INCLUDES 00161 # include "arch/epstruct.h" 00162 #endif 00163 00164 /** The NBNS Structure Responds to a Name Query */ 00165 #ifdef PACK_STRUCT_USE_INCLUDES 00166 # include "arch/bpstruct.h" 00167 #endif 00168 PACK_STRUCT_BEGIN 00169 struct netbios_answer { 00170 struct netbios_hdr answer_hdr; 00171 /** the length of the next string */ 00172 PACK_STRUCT_FIELD(u8_t name_size); 00173 /** WARNING!!! this item may be of a different length (we use this struct for transmission) */ 00174 PACK_STRUCT_FLD_8(u8_t query_name[(NETBIOS_NAME_LEN * 2) + 1]); 00175 PACK_STRUCT_FIELD(u16_t packet_type); 00176 PACK_STRUCT_FIELD(u16_t cls); 00177 PACK_STRUCT_FIELD(u32_t ttl); 00178 PACK_STRUCT_FIELD(u16_t data_length); 00179 #define OFFSETOF_STRUCT_NETBIOS_ANSWER_NUMBER_OF_NAMES 56 00180 /** number of names */ 00181 PACK_STRUCT_FLD_8(u8_t number_of_names); 00182 /** node name */ 00183 PACK_STRUCT_FLD_8(u8_t answer_name[NETBIOS_NAME_LEN]); 00184 /** node flags */ 00185 PACK_STRUCT_FIELD(u16_t answer_name_flags); 00186 /** Unit ID */ 00187 PACK_STRUCT_FLD_8(u8_t unit_id[6]); 00188 /** Jumpers */ 00189 PACK_STRUCT_FLD_8(u8_t jumpers); 00190 /** Test result */ 00191 PACK_STRUCT_FLD_8(u8_t test_result); 00192 /** Version number */ 00193 PACK_STRUCT_FIELD(u16_t version_number); 00194 /** Period of statistics */ 00195 PACK_STRUCT_FIELD(u16_t period_of_statistics); 00196 /** Statistics */ 00197 PACK_STRUCT_FIELD(u16_t number_of_crcs); 00198 /** Statistics */ 00199 PACK_STRUCT_FIELD(u16_t number_of_alignment_errors); 00200 /** Statistics */ 00201 PACK_STRUCT_FIELD(u16_t number_of_collisions); 00202 /** Statistics */ 00203 PACK_STRUCT_FIELD(u16_t number_of_send_aborts); 00204 /** Statistics */ 00205 PACK_STRUCT_FIELD(u32_t number_of_good_sends); 00206 /** Statistics */ 00207 PACK_STRUCT_FIELD(u32_t number_of_good_receives); 00208 /** Statistics */ 00209 PACK_STRUCT_FIELD(u16_t number_of_retransmits); 00210 /** Statistics */ 00211 PACK_STRUCT_FIELD(u16_t number_of_no_resource_condition); 00212 /** Statistics */ 00213 PACK_STRUCT_FIELD(u16_t number_of_free_command_blocks); 00214 /** Statistics */ 00215 PACK_STRUCT_FIELD(u16_t total_number_of_command_blocks); 00216 /** Statistics */ 00217 PACK_STRUCT_FIELD(u16_t max_total_number_of_command_blocks); 00218 /** Statistics */ 00219 PACK_STRUCT_FIELD(u16_t number_of_pending_sessions); 00220 /** Statistics */ 00221 PACK_STRUCT_FIELD(u16_t max_number_of_pending_sessions); 00222 /** Statistics */ 00223 PACK_STRUCT_FIELD(u16_t max_total_sessions_possible); 00224 /** Statistics */ 00225 PACK_STRUCT_FIELD(u16_t session_data_packet_size); 00226 } PACK_STRUCT_STRUCT; 00227 PACK_STRUCT_END 00228 #ifdef PACK_STRUCT_USE_INCLUDES 00229 # include "arch/epstruct.h" 00230 #endif 00231 00232 #ifdef NETBIOS_LWIP_NAME 00233 #define NETBIOS_LOCAL_NAME NETBIOS_LWIP_NAME 00234 #else 00235 static char netbiosns_local_name[NETBIOS_NAME_LEN]; 00236 #define NETBIOS_LOCAL_NAME netbiosns_local_name 00237 #endif 00238 00239 static struct udp_pcb *netbiosns_pcb; 00240 00241 /** Decode a NetBIOS name (from packet to string) */ 00242 static int 00243 netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len) 00244 { 00245 char *pname; 00246 char cname; 00247 char cnbname; 00248 int idx = 0; 00249 00250 LWIP_UNUSED_ARG(name_dec_len); 00251 00252 /* Start decoding netbios name. */ 00253 pname = name_enc; 00254 for (;;) { 00255 /* Every two characters of the first level-encoded name 00256 * turn into one character in the decoded name. */ 00257 cname = *pname; 00258 if (cname == '\0') { 00259 break; /* no more characters */ 00260 } 00261 if (cname == '.') { 00262 break; /* scope ID follows */ 00263 } 00264 if (!lwip_isupper(cname)) { 00265 /* Not legal. */ 00266 return -1; 00267 } 00268 cname -= 'A'; 00269 cnbname = cname << 4; 00270 pname++; 00271 00272 cname = *pname; 00273 if (!lwip_isupper(cname)) { 00274 /* Not legal. */ 00275 return -1; 00276 } 00277 cname -= 'A'; 00278 cnbname |= cname; 00279 pname++; 00280 00281 /* Do we have room to store the character? */ 00282 if (idx < NETBIOS_NAME_LEN) { 00283 /* Yes - store the character. */ 00284 name_dec[idx++] = (cnbname != ' ' ? cnbname : '\0'); 00285 } 00286 } 00287 00288 return 0; 00289 } 00290 00291 #if 0 /* function currently unused */ 00292 /** Encode a NetBIOS name (from string to packet) - currently unused because 00293 we don't ask for names. */ 00294 static int 00295 netbiosns_name_encode(char *name_enc, char *name_dec, int name_dec_len) 00296 { 00297 char *pname; 00298 char cname; 00299 unsigned char ucname; 00300 int idx = 0; 00301 00302 /* Start encoding netbios name. */ 00303 pname = name_enc; 00304 00305 for (;;) { 00306 /* Every two characters of the first level-encoded name 00307 * turn into one character in the decoded name. */ 00308 cname = *pname; 00309 if (cname == '\0') { 00310 break; /* no more characters */ 00311 } 00312 if (cname == '.') { 00313 break; /* scope ID follows */ 00314 } 00315 if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) { 00316 /* Not legal. */ 00317 return -1; 00318 } 00319 00320 /* Do we have room to store the character? */ 00321 if (idx >= name_dec_len) { 00322 return -1; 00323 } 00324 00325 /* Yes - store the character. */ 00326 ucname = cname; 00327 name_dec[idx++] = ('A' + ((ucname >> 4) & 0x0F)); 00328 name_dec[idx++] = ('A' + ( ucname & 0x0F)); 00329 pname++; 00330 } 00331 00332 /* Fill with "space" coding */ 00333 for (; idx < name_dec_len - 1;) { 00334 name_dec[idx++] = 'C'; 00335 name_dec[idx++] = 'A'; 00336 } 00337 00338 /* Terminate string */ 00339 name_dec[idx] = '\0'; 00340 00341 return 0; 00342 } 00343 #endif /* 0 */ 00344 00345 /** NetBIOS Name service recv callback */ 00346 static void 00347 netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) 00348 { 00349 LWIP_UNUSED_ARG(arg); 00350 00351 /* if packet is valid */ 00352 if (p != NULL) { 00353 char netbios_name[NETBIOS_NAME_LEN + 1]; 00354 struct netbios_hdr *netbios_hdr = (struct netbios_hdr *)p->payload; 00355 struct netbios_question_hdr *netbios_question_hdr = (struct netbios_question_hdr *)(netbios_hdr + 1); 00356 00357 /* is the packet long enough (we need the header in one piece) */ 00358 if (p->len < (sizeof(struct netbios_hdr) + sizeof(struct netbios_question_hdr))) { 00359 /* packet too short */ 00360 pbuf_free(p); 00361 return; 00362 } 00363 /* we only answer if we got a default interface */ 00364 if (netif_default != NULL) { 00365 /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */ 00366 /* if the packet is a NetBIOS name query question */ 00367 if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) && 00368 ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) && 00369 (netbios_hdr->questions == PP_NTOHS(1))) { 00370 /* decode the NetBIOS name */ 00371 netbiosns_name_decode((char *)(netbios_question_hdr->encname), netbios_name, sizeof(netbios_name)); 00372 /* check the request type */ 00373 if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NB)) { 00374 /* if the packet is for us */ 00375 if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) { 00376 struct pbuf *q; 00377 struct netbios_resp *resp; 00378 00379 q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM); 00380 if (q != NULL) { 00381 resp = (struct netbios_resp *)q->payload; 00382 00383 /* prepare NetBIOS header response */ 00384 resp->resp_hdr.trans_id = netbios_hdr->trans_id; 00385 resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | 00386 NETB_HFLAG_OPCODE_NAME_QUERY | 00387 NETB_HFLAG_AUTHORATIVE | 00388 NETB_HFLAG_RECURS_DESIRED); 00389 resp->resp_hdr.questions = 0; 00390 resp->resp_hdr.answerRRs = PP_HTONS(1); 00391 resp->resp_hdr.authorityRRs = 0; 00392 resp->resp_hdr.additionalRRs = 0; 00393 00394 /* prepare NetBIOS header datas */ 00395 MEMCPY( resp->resp_name.encname, netbios_question_hdr->encname, sizeof(netbios_question_hdr->encname)); 00396 resp->resp_name.nametype = netbios_question_hdr->nametype; 00397 resp->resp_name.type = netbios_question_hdr->type; 00398 resp->resp_name.cls = netbios_question_hdr->cls; 00399 resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL); 00400 resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags) + sizeof(resp->resp_name.addr)); 00401 resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE); 00402 ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default)); 00403 00404 /* send the NetBIOS response */ 00405 udp_sendto(upcb, q, addr, port); 00406 00407 /* free the "reference" pbuf */ 00408 pbuf_free(q); 00409 } 00410 } 00411 #if LWIP_NETBIOS_RESPOND_NAME_QUERY 00412 } else if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) { 00413 /* if the packet is for us or general query */ 00414 if (!lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) || 00415 !lwip_strnicmp(netbios_name, "*", sizeof(NETBIOS_LOCAL_NAME))) { 00416 /* general query - ask for our IP address */ 00417 struct pbuf *q; 00418 struct netbios_answer *resp; 00419 00420 q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_answer), PBUF_RAM); 00421 if (q != NULL) { 00422 /* buffer to which a response is compiled */ 00423 resp = (struct netbios_answer *) q->payload; 00424 00425 /* Init response to zero, especially the statistics fields */ 00426 memset(resp, 0, sizeof(*resp)); 00427 00428 /* copy the query to the response ID */ 00429 resp->answer_hdr.trans_id = netbios_hdr->trans_id; 00430 /* acknowledgment of termination */ 00431 resp->answer_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE); 00432 /* resp->answer_hdr.questions = PP_HTONS(0); done by memset() */ 00433 /* serial number of the answer */ 00434 resp->answer_hdr.answerRRs = PP_HTONS(1); 00435 /* resp->answer_hdr.authorityRRs = PP_HTONS(0); done by memset() */ 00436 /* resp->answer_hdr.additionalRRs = PP_HTONS(0); done by memset() */ 00437 /* we will copy the length of the station name */ 00438 resp->name_size = netbios_question_hdr->nametype; 00439 /* we will copy the queried name */ 00440 MEMCPY(resp->query_name, netbios_question_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1); 00441 /* NBSTAT */ 00442 resp->packet_type = PP_HTONS(0x21); 00443 /* Internet name */ 00444 resp->cls = PP_HTONS(1); 00445 /* resp->ttl = PP_HTONL(0); done by memset() */ 00446 resp->data_length = PP_HTONS(sizeof(struct netbios_answer) - offsetof(struct netbios_answer, number_of_names)); 00447 resp->number_of_names = 1; 00448 00449 /* make windows see us as workstation, not as a server */ 00450 memset(resp->answer_name, 0x20, NETBIOS_NAME_LEN - 1); 00451 /* strlen is checked to be < NETBIOS_NAME_LEN during initialization */ 00452 MEMCPY(resp->answer_name, NETBIOS_LOCAL_NAME, strlen(NETBIOS_LOCAL_NAME)); 00453 00454 /* b-node, unique, active */ 00455 resp->answer_name_flags = PP_HTONS(NETB_NFLAG_NAME_IS_ACTIVE); 00456 00457 /* Set responder netif MAC address */ 00458 SMEMCPY(resp->unit_id, ip_current_input_netif()->hwaddr, sizeof(resp->unit_id)); 00459 00460 udp_sendto(upcb, q, addr, port); 00461 pbuf_free(q); 00462 } 00463 } 00464 #endif /* LWIP_NETBIOS_RESPOND_NAME_QUERY */ 00465 } 00466 } 00467 } 00468 /* free the pbuf */ 00469 pbuf_free(p); 00470 } 00471 } 00472 00473 /** 00474 * @ingroup netbiosns 00475 * Init netbios responder 00476 */ 00477 void 00478 netbiosns_init(void) 00479 { 00480 /* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */ 00481 #ifdef NETBIOS_LWIP_NAME 00482 LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN); 00483 #endif 00484 00485 netbiosns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); 00486 if (netbiosns_pcb != NULL) { 00487 /* we have to be allowed to send broadcast packets! */ 00488 ip_set_option(netbiosns_pcb, SOF_BROADCAST); 00489 udp_bind(netbiosns_pcb, IP_ANY_TYPE, LWIP_IANA_PORT_NETBIOS); 00490 udp_recv(netbiosns_pcb, netbiosns_recv, netbiosns_pcb); 00491 } 00492 } 00493 00494 #ifndef NETBIOS_LWIP_NAME 00495 /** 00496 * @ingroup netbiosns 00497 * Set netbios name. ATTENTION: the hostname must be less than 15 characters! 00498 * the NetBIOS name spec says the name MUST be upper case, so incoming name is forced into uppercase :-) 00499 */ 00500 void 00501 netbiosns_set_name(const char *hostname) 00502 { 00503 size_t i; 00504 size_t copy_len = strlen(hostname); 00505 LWIP_ASSERT_CORE_LOCKED(); 00506 LWIP_ASSERT("NetBIOS name is too long!", copy_len < NETBIOS_NAME_LEN); 00507 if (copy_len >= NETBIOS_NAME_LEN) { 00508 copy_len = NETBIOS_NAME_LEN - 1; 00509 } 00510 00511 /* make name into upper case */ 00512 for (i = 0; i < copy_len; i++ ) { 00513 netbiosns_local_name[i] = (char)lwip_toupper(hostname[i]); 00514 } 00515 netbiosns_local_name[copy_len] = '\0'; 00516 } 00517 #endif /* NETBIOS_LWIP_NAME */ 00518 00519 /** 00520 * @ingroup netbiosns 00521 * Stop netbios responder 00522 */ 00523 void 00524 netbiosns_stop(void) 00525 { 00526 LWIP_ASSERT_CORE_LOCKED(); 00527 if (netbiosns_pcb != NULL) { 00528 udp_remove(netbiosns_pcb); 00529 netbiosns_pcb = NULL; 00530 } 00531 } 00532 00533 #endif /* LWIP_IPV4 && LWIP_UDP */
Generated on Tue Jul 12 2022 13:54:29 by
 1.7.2
 1.7.2