1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SMB_NETBIOS_H_ 27 #define _SMB_NETBIOS_H_ 28 29 #include <stdio.h> 30 #include <synch.h> 31 #include <pthread.h> 32 #include <strings.h> 33 #include <netinet/in.h> 34 35 #include <smbsrv/libsmbns.h> 36 37 #include <smbsrv/smbinfo.h> 38 #include <smbsrv/netbios.h> 39 40 #define QUEUE_INSERT_TAIL(q, e) \ 41 ((e)->back) = (void *)((q)->back); \ 42 ((e)->forw) = (void *)(q); \ 43 ((q)->back->forw) = (void *)(e); \ 44 ((q)->back) = (void *)(e); 45 46 #define QUEUE_CLIP(e) \ 47 (e)->forw->back = (e)->back; \ 48 (e)->back->forw = (e)->forw; \ 49 (e)->forw = 0; \ 50 (e)->back = 0; 51 52 #define NETBIOS_NAME_SVC_LAUNCHED 0x00001 53 #define NETBIOS_NAME_SVC_RUNNING 0x00002 54 #define NETBIOS_NAME_SVC_FAILED 0x00004 55 56 #define NETBIOS_DATAGRAM_SVC_LAUNCHED 0x00010 57 #define NETBIOS_DATAGRAM_SVC_RUNNING 0x00020 58 #define NETBIOS_DATAGRAM_SVC_FAILED 0x00040 59 60 #define NETBIOS_TIMER_LAUNCHED 0x00100 61 #define NETBIOS_TIMER_RUNNING 0x00200 62 #define NETBIOS_TIMER_FAILED 0x00400 63 64 #define NETBIOS_BROWSER_LAUNCHED 0x01000 65 #define NETBIOS_BROWSER_RUNNING 0x02000 66 #define NETBIOS_BROWSER_FAILED 0x04000 67 68 #define NETBIOS_SHUTTING_DOWN 0x10000 69 #define NETBIOS_SHUT_DOWN 0x20000 70 71 char smb_node_type; 72 73 #define SMB_NODETYPE_B 'B' 74 #define SMB_NODETYPE_P 'P' 75 #define SMB_NODETYPE_M 'M' 76 #define SMB_NODETYPE_H 'H' 77 78 typedef struct { 79 mutex_t mtx; 80 cond_t cv; 81 uint32_t state; 82 } netbios_status_t; 83 extern netbios_status_t nb_status; 84 85 /* 86 * NAME service definitions 87 */ 88 #define ADDR_FLAG_INVALID 0x0000 89 #define ADDR_FLAG_VALID 0x0001 90 91 typedef struct addr_entry { 92 struct addr_entry *forw; 93 struct addr_entry *back; 94 uint32_t attributes; 95 uint32_t conflict_timer; 96 uint32_t refresh_ttl; 97 uint32_t ttl; 98 struct sockaddr_in sin; 99 int sinlen; 100 uint32_t flags; 101 } addr_entry_t; 102 103 /* 104 * The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries 105 * of NODE_NAME records. Each NODE_NAME entry represents an active 106 * name in the same NetBIOS scope as the requesting name in the 107 * local name table of the responder. RR_NAME is the requesting 108 * name. 109 * 110 * NODE_NAME Entry: 111 * 112 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 113 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 114 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 115 * | | 116 * +--- ---+ 117 * | | 118 * +--- NETBIOS FORMAT NAME ---+ 119 * | | 120 * +--- ---+ 121 * | | 122 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 123 * | NAME_FLAGS | 124 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 125 * 126 * The NAME_FLAGS field: 127 * 128 * 1 1 1 1 1 1 129 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 130 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 131 * | G | ONT |DRG|CNF|ACT|PRM| RESERVED | 132 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 133 * 134 * The NAME_FLAGS field is defined as: 135 * 136 * Symbol Bit(s) Description: 137 * 138 * RESERVED 7-15 Reserved for future use. Must be zero (0). 139 * PRM 6 Permanent Name Flag. If one (1) then entry 140 * is for the permanent node name. Flag is zero 141 * (0) for all other names. 142 * ACT 5 Active Name Flag. All entries have this flag 143 * set to one (1). 144 * CNF 4 Conflict Flag. If one (1) then name on this 145 * node is in conflict. 146 * DRG 3 Deregister Flag. If one (1) then this name 147 * is in the process of being deleted. 148 * ONT 1,2 Owner Node Type: 149 * 00 = B node 150 * 01 = P node 151 * 10 = M node 152 * 11 = Reserved for future use 153 * G 0 Group Name Flag. 154 * name. 155 * If zero (0) then it is a UNIQUE NetBIOS name. 156 */ 157 158 typedef struct name_entry { 159 struct name_entry *forw; 160 struct name_entry *back; 161 unsigned char name[NETBIOS_NAME_SZ]; 162 unsigned char scope[NETBIOS_DOMAIN_NAME_MAX]; 163 unsigned short attributes; 164 struct addr_entry addr_list; 165 mutex_t mtx; 166 } name_entry_t; 167 168 struct name_question { 169 struct name_entry *name; 170 unsigned question_type; 171 unsigned question_class; 172 }; 173 174 struct resource_record { 175 /* 176 * These two flags and address are contained within RDATA 177 * when rr_type==0x0020 (NB - NetBIOS general Name Service) 178 * and rr_class==0x01 (IN - Internet Class). 179 */ 180 181 struct name_entry *name; 182 unsigned short rr_type; 183 unsigned short rr_class; 184 uint32_t ttl; 185 unsigned short rdlength; 186 unsigned char *rdata; 187 }; 188 189 struct name_packet { 190 unsigned short name_trn_id; 191 unsigned short info; 192 193 unsigned qdcount; /* question entries */ 194 unsigned ancount; /* answer recs */ 195 unsigned nscount; /* authority recs */ 196 unsigned arcount; /* additional recs */ 197 198 struct name_question *question; 199 struct resource_record *answer; 200 struct resource_record *authority; 201 struct resource_record *additional; 202 203 unsigned char block_data[4]; /* begining of space */ 204 }; 205 206 #define NAME_OPCODE_R 0x8000 /* RESPONSE flag: 1 bit */ 207 #define NAME_OPCODE_OPCODE_MASK 0x7800 /* OPCODE Field: 4 bits */ 208 #define NAME_OPCODE_QUERY 0x0000 209 #define NAME_OPCODE_REGISTRATION 0x2800 210 #define NAME_OPCODE_RELEASE 0x3000 211 #define NAME_OPCODE_WACK 0x3800 212 #define NAME_OPCODE_REFRESH 0x4000 213 #define NAME_OPCODE_MULTIHOME 0x7800 214 #define NAME_NM_FLAGS_AA 0x0400 /* Authoritative Answer:1 bit */ 215 #define NAME_NM_FLAGS_TC 0x0200 /* Truncation: 1 bit */ 216 #define NAME_NM_FLAGS_RD 0x0100 /* Recursion desired: 1 bit */ 217 #define NAME_NM_FLAGS_RA 0x0080 /* Recursion available: 1 bit */ 218 #define NAME_NM_FLAGS_x2 0x0040 /* reserved, mbz: 1 bit */ 219 #define NAME_NM_FLAGS_x1 0x0020 /* reserved, mbz: 1 bit */ 220 #define NAME_NM_FLAGS_B 0x0010 /* Broadcast: 1 bit */ 221 #define NAME_RCODE_MASK 0x000f /* RCODE Field: 4 bits */ 222 #define RCODE_FMT_ERR 0x0001 223 #define RCODE_SRV_ERR 0x0002 224 #define RCODE_NAM_ERR 0x0003 225 #define RCODE_IMP_ERR 0x0004 226 #define RCODE_RFS_ERR 0x0005 227 #define RCODE_ACT_ERR 0x0006 228 #define RCODE_CFT_ERR 0x0007 229 230 #define NM_FLAGS_UNICAST 0 231 #define NM_FLAGS_BROADCAST NAME_NM_FLAGS_B 232 233 #define PACKET_TYPE(x) ((x) & (NAME_OPCODE_R | NAME_OPCODE_OPCODE_MASK | \ 234 NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD)) 235 236 #define RCODE(x) ((x) & NAME_RCODE_MASK) 237 #define POSITIVE_RESPONSE(x) (RCODE(x) == 0) 238 #define NEGATIVE_RESPONSE(x) (RCODE(x) != 0) 239 240 #define END_NODE_CHALLENGE_REGISTRATION_REQUEST \ 241 (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD) 242 #define END_NODE_CHALLENGE_NAME_REGISTRATION_RESPONSE \ 243 (NAME_OPCODE_R | END_NODE_CHALLENGE_REGISTRATION_REQUEST) 244 245 #define NAME_QUERY_REQUEST \ 246 (NAME_OPCODE_QUERY | NAME_NM_FLAGS_RD) 247 #define NAME_QUERY_RESPONSE \ 248 (NAME_OPCODE_R | NAME_QUERY_REQUEST | \ 249 NAME_NM_FLAGS_AA | NAME_NM_FLAGS_RD) 250 251 #define NODE_STATUS_REQUEST \ 252 (NAME_OPCODE_QUERY) 253 #define NODE_STATUS_RESPONSE \ 254 (NAME_OPCODE_R | NODE_STATUS_REQUEST | NAME_NM_FLAGS_AA) 255 256 #define REDIRECT_NAME_QUERY_RESPONSE \ 257 (NAME_OPCODE_R | NAME_QUERY_REQUEST | NAME_NM_FLAGS_RD) 258 259 #define NAME_REFRESH_REQUEST \ 260 (NAME_OPCODE_REFRESH) 261 #define NAME_REGISTRATION_REQUEST \ 262 (NAME_OPCODE_REGISTRATION | NAME_NM_FLAGS_RD) 263 #define NAME_MULTIHOME_REGISTRATION_REQUEST \ 264 (NAME_OPCODE_MULTIHOME | NAME_NM_FLAGS_RD) 265 #define NAME_REGISTRATION_RESPONSE \ 266 (NAME_OPCODE_R | NAME_REGISTRATION_REQUEST | NAME_NM_FLAGS_AA) 267 268 #define NAME_RELEASE_REQUEST \ 269 (NAME_OPCODE_RELEASE) 270 #define NAME_RELEASE_RESPONSE \ 271 (NAME_OPCODE_R | NAME_RELEASE_REQUEST | NAME_NM_FLAGS_AA) 272 273 #define WACK_RESPONSE \ 274 (NAME_OPCODE_R | NAME_OPCODE_WACK | NAME_NM_FLAGS_AA) 275 276 #define NAME_QUESTION_TYPE_NB 0x0020 277 #define NAME_QUESTION_TYPE_NBSTAT 0x0021 278 #define NAME_QUESTION_CLASS_IN 0x0001 279 280 281 #define NAME_RR_TYPE_A 0x0001 /* IP Address */ 282 #define NAME_RR_TYPE_NS 0x0002 /* Name Server */ 283 #define NAME_RR_TYPE_NULL 0x000A /* NULL */ 284 #define NAME_RR_TYPE_NB 0x0020 /* NetBIOS Name Service */ 285 #define NAME_RR_TYPE_NBSTAT 0x0021 /* NetBIOS Node Status */ 286 287 #define NAME_RR_CLASS_IN 0x0001 /* NetBIOS Node Status */ 288 289 #define NAME_NB_FLAGS_ONT_MASK (3<<13) 290 #define NAME_NB_FLAGS_ONT_B (0<<13) /* B-node (broadcast) */ 291 #define NAME_NB_FLAGS_ONT_P (1<<13) /* P-node (point-to-point) */ 292 #define NAME_NB_FLAGS_ONT_M (2<<13) /* M-node (multicast) */ 293 #define NAME_NB_FLAGS_ONT_resv (3<<13) 294 #define NAME_NB_FLAGS_G (1<<15) /* Group Name */ 295 296 #define UNICAST 0 297 #define BROADCAST 1 298 #define POINTCAST 2 299 300 #define NAME_ATTR_UNIQUE 0x0000 301 #define NAME_ATTR_GROUP 0x8000 302 #define NAME_ATTR_OWNER_NODE_TYPE 0x6000 303 #define NAME_ATTR_OWNER_TYPE_BNODE 0x0000 304 #define NAME_ATTR_OWNER_TYPE_PNODE 0x2000 305 #define NAME_ATTR_OWNER_TYPE_MNODE 0x4000 306 #define NAME_ATTR_OWNER_TYPE_HNODE 0x6000 307 #define NAME_ATTR_DEREGISTER 0x1000 308 #define NAME_ATTR_CONFLICT 0x0800 309 #define NAME_ATTR_ACTIVE_NAME 0x0400 310 #define NAME_ATTR_PERMANENT 0x0200 311 #define NAME_ATTR_RESERVED 0x01FF 312 #define NAME_ATTR_LOCAL 0x0001 313 314 #define NODE_TYPE(x) ((x) & NAME_ATTR_OWNER_NODE_TYPE)) 315 #define IS_BNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_BNODE) 316 #define IS_PNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_PNODE) 317 #define IS_MNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_MNODE) 318 #define IS_HNODE(x) (NODE_TYPE(x) == NAME_ATTR_OWNER_TYPE_HNODE) 319 320 #define IS_UNIQUE(x) (((x) & NAME_ATTR_GROUP) == 0) 321 #define IS_GROUP(x) (((x) & NAME_ATTR_GROUP) != 0) 322 #define IS_PERMANENT(x) (((x) & NAME_ATTR_PERMANENT) != 0) 323 #define IS_CONFLICTING(x) (((x) & NAME_ATTR_CONFLICT) != 0) 324 #define IS_ACTIVE(x) (((x) & NAME_ATTR_ACTIVE) != 0) 325 #define IS_DEGREGISTERED(x) (((x) & NAME_ATTR_ACTIVE) != 0) 326 327 #define IS_LOCAL(x) (((x) & NAME_ATTR_LOCAL) != 0) 328 #define IS_PUBLIC(x) (((x) & NAME_ATTR_LOCAL) == 0) 329 #define PUBLIC_BITS(x) ((x) & ~NAME_ATTR_RESERVED) 330 331 #define SAME_SCOPE(scope, e) (strcmp((scope), ((e)->scope)) == 0) 332 333 /* 334 * STATISTICS Field of the NODE STATUS RESPONSE: 335 * 336 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 337 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 338 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 339 * | UNIT_ID (Unique unit ID) | 340 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 341 * | UNIT_ID,continued | JUMPERS | TEST_RESULT | 342 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 343 * | VERSION_NUMBER | PERIOD_OF_STATISTICS | 344 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 345 * | NUMBER_OF_CRCs | NUMBER_ALIGNMENT_ERRORS | 346 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 347 * | NUMBER_OF_COLLISIONS | NUMBER_SEND_ABORTS | 348 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 349 * | NUMBER_GOOD_SENDS | 350 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 351 * | NUMBER_GOOD_RECEIVES | 352 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 353 * | NUMBER_RETRANSMITS | NUMBER_NO_RESOURCE_CONDITIONS | 354 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 355 * | NUMBER_FREE_COMMAND_BLOCKS | TOTAL_NUMBER_COMMAND_BLOCKS | 356 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 357 * |MAX_TOTAL_NUMBER_COMMAND_BLOCKS| NUMBER_PENDING_SESSIONS | 358 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 359 * | MAX_NUMBER_PENDING_SESSIONS | MAX_TOTAL_SESSIONS_POSSIBLE | 360 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 361 * | SESSION_DATA_PACKET_SIZE | 362 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 363 */ 364 365 typedef struct { 366 unsigned char unit_id[6]; 367 unsigned char jumpers; 368 unsigned char test_result; 369 unsigned short version_number; 370 unsigned short statistical_period; 371 unsigned short crc_errors; 372 unsigned short alignment_errors; 373 unsigned short collisions; 374 unsigned short send_aborts; 375 unsigned int good_sends; 376 unsigned int good_receives; 377 unsigned short retransmits; 378 unsigned short no_resource_conditions; 379 unsigned short free_command_blocks; 380 unsigned short total_command_blocks; 381 unsigned short max_total_command_blocks; 382 unsigned short pending_sessions; 383 unsigned short max_pending_sessions; 384 unsigned short total_possible_sessions; 385 unsigned short session_data_packet_size; 386 } node_status_response; 387 388 /* 389 * 4.4.1. NetBIOS DATAGRAM HEADER 390 * 391 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 392 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 393 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 394 * | MSG_TYPE | FLAGS | DGM_ID | 395 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 396 * | SOURCE_IP | 397 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 398 * | SOURCE_PORT | DGM_LENGTH | 399 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 400 * | PACKET_OFFSET | 401 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 402 */ 403 typedef struct { 404 unsigned char msg_type; 405 unsigned char flags; 406 unsigned short dgm_id; 407 uint32_t source_ip; 408 unsigned short source_port; 409 unsigned short dgm_length; 410 unsigned short packet_offset; 411 } datagram_header; 412 413 /* 414 * MSG_TYPE values (in hexidecimal): 415 * 416 * 10 - DIRECT_UNIQUE DATAGRAM 417 * 11 - DIRECT_GROUP DATAGRAM 418 * 12 - BROADCAST DATAGRAM 419 * 13 - DATAGRAM ERROR 420 * 14 - DATAGRAM QUERY REQUEST 421 * 15 - DATAGRAM POSITIVE QUERY RESPONSE 422 * 16 - DATAGRAM NEGATIVE QUERY RESPONSE 423 */ 424 #define DATAGRAM_TYPE_DIRECT_UNIQUE 0x10 425 #define DATAGRAM_TYPE_DIRECT_GROUP 0x11 426 #define DATAGRAM_TYPE_BROADCAST 0x12 427 #define DATAGRAM_TYPE_ERROR_DATAGRAM 0x13 428 #define DATAGRAM_TYPE_QUERY_REQUEST 0x14 429 #define DATAGRAM_TYPE_POSITIVE_RESPONSE 0x15 430 #define DATAGRAM_TYPE_NEGATIVE_RESPONSE 0x16 431 432 433 /* 434 * Bit definitions of the FLAGS field: 435 * 436 * 0 1 2 3 4 5 6 7 437 * +---+---+---+---+---+---+---+---+ 438 * | 0 | 0 | 0 | 0 | SNT | F | M | 439 * +---+---+---+---+---+---+---+---+ 440 * 441 * Symbol Bit(s) Description 442 * 443 * M 7 MORE flag, If set then more NetBIOS datagram 444 * fragments follow. 445 * 446 * F 6 FIRST packet flag, If set then this is first 447 * (and possibly only) fragment of NetBIOS 448 * datagram 449 * 450 * SNT 4,5 Source End-Node type: 451 * 00 = B node 452 * 01 = P node 453 * 10 = M node 454 * 11 = H node 455 * RESERVED 0-3 Reserved, must be zero (0) 456 */ 457 #define DATAGRAM_FLAGS_MORE 0x01 458 #define DATAGRAM_FLAGS_FIRST 0x02 459 #define DATAGRAM_FLAGS_SRC_TYPE 0x0c 460 #define DATAGRAM_FLAGS_B_NODE 0x00 461 #define DATAGRAM_FLAGS_P_NODE 0x04 462 #define DATAGRAM_FLAGS_M_NODE 0x08 463 #define DATAGRAM_FLAGS_H_NODE 0x0C 464 #define DATAGRAM_FLAGS_NBDD 0x0c 465 #define DATAGRAM_FLAGS_RESERVED 0xf0 466 467 /* 468 * 4.4.2. DIRECT_UNIQUE, DIRECT_GROUP, & BROADCAST DATAGRAM 469 * 470 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 471 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 472 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 473 * | MSG_TYPE | FLAGS | DGM_ID | 474 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 475 * | SOURCE_IP | 476 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 477 * | SOURCE_PORT | DGM_LENGTH | 478 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 479 * | PACKET_OFFSET | | 480 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 481 * | | 482 * / SOURCE_NAME / 483 * / / 484 * | | 485 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 486 * | | 487 * / DESTINATION_NAME / 488 * / / 489 * | | 490 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 491 * | | 492 * / USER_DATA / 493 * / / 494 * | | 495 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 496 */ 497 typedef struct { 498 datagram_header header; 499 unsigned char *source_name; 500 unsigned char *destination_name; 501 unsigned char *user_data; 502 } datagram_packet; 503 504 505 /* 506 * 4.4.3. DATAGRAM ERROR PACKET 507 * 508 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 509 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 510 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 511 * | MSG_TYPE | FLAGS | DGM_ID | 512 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 513 * | SOURCE_IP | 514 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 515 * | SOURCE_PORT | ERROR_CODE | 516 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 517 * 518 * ERROR_CODE values (in hexidecimal): 519 * 520 * 82 - DESTINATION NAME NOT PRESENT 521 * 83 - INVALID SOURCE NAME FORMAT 522 * 84 - INVALID DESTINATION NAME FORMAT 523 */ 524 525 typedef struct { 526 unsigned char msg_type; 527 unsigned char flags; 528 unsigned short dgm_id; 529 uint32_t source_ip; 530 unsigned short source_port; 531 unsigned char error; 532 } datagram_error_packet; 533 534 /* 535 * 4.4.4. DATAGRAM QUERY REQUEST 536 * 537 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 538 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 539 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 540 * | MSG_TYPE | FLAGS | DGM_ID | 541 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 542 * | SOURCE_IP | 543 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 544 * | SOURCE_PORT | | 545 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 546 * | | 547 * / DESTINATION_NAME / 548 * / / 549 * | | 550 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 551 * 552 * 4.4.5. DATAGRAM POSITIVE AND NEGATIVE QUERY RESPONSE 553 * 554 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 555 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 556 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 557 * | MSG_TYPE | FLAGS | DGM_ID | 558 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 559 * | SOURCE_IP | 560 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 561 * | SOURCE_PORT | | 562 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 563 * | | 564 * / DESTINATION_NAME / 565 * / / 566 * | | 567 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 568 */ 569 570 typedef struct datagram_query_packet { 571 unsigned char msg_type; 572 unsigned char flags; 573 unsigned short dgm_id; 574 uint32_t source_ip; 575 unsigned short source_port; 576 unsigned char destination_name[MAX_NAME_LENGTH]; 577 } datagram_query_packet; 578 579 580 typedef struct datagram { 581 struct datagram *forw; 582 struct datagram *back; 583 struct addr_entry inaddr; 584 int discard_timer; 585 unsigned char packet_type; 586 unsigned char flags; 587 unsigned short datagram_id; 588 struct name_entry src; 589 struct name_entry dest; 590 unsigned short offset; 591 unsigned short data_length; 592 unsigned char *data; 593 unsigned int rawbytes; 594 unsigned char rawbuf[MAX_DATAGRAM_LENGTH]; 595 } datagram; 596 597 typedef struct datagram_queue { 598 struct datagram *forw; 599 struct datagram *back; 600 } datagram_queue; 601 602 typedef struct name_queue { 603 struct name_entry head; 604 mutex_t mtx; 605 } name_queue_t; 606 607 typedef struct nbcache_iter { 608 HT_ITERATOR nbc_hti; 609 struct name_entry *nbc_entry; 610 } nbcache_iter_t; 611 612 #define NETBIOS_EMPTY_NAME (unsigned char *)"" 613 614 #define NETBIOS_NAME_IS_STAR(name) \ 615 (bcmp(name, "*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NETBIOS_NAME_SZ) == 0) 616 617 void smb_netbios_chg_status(uint32_t status, int set); 618 619 /* 620 * Name Cache Functions 621 */ 622 int smb_netbios_cache_init(void); 623 void smb_netbios_cache_fini(void); 624 void smb_netbios_cache_dump(void); 625 int smb_netbios_cache_count(void); 626 void smb_netbios_cache_clean(void); 627 void smb_netbios_cache_reset_ttl(void); 628 void smb_netbios_cache_delete_locals(name_queue_t *); 629 void smb_netbios_cache_refresh(name_queue_t *); 630 631 int smb_netbios_cache_insert(struct name_entry *name); 632 int smb_netbios_cache_insert_list(struct name_entry *name); 633 void smb_netbios_cache_delete(struct name_entry *name); 634 int smb_netbios_cache_delete_addr(struct name_entry *name); 635 struct name_entry *smb_netbios_cache_lookup(struct name_entry *name); 636 struct name_entry *smb_netbios_cache_lookup_addr(struct name_entry *name); 637 void smb_netbios_cache_update_entry(struct name_entry *, struct name_entry *); 638 void smb_netbios_cache_unlock_entry(struct name_entry *); 639 unsigned char *smb_netbios_cache_status(unsigned char *, int, unsigned char *); 640 int smb_netbios_cache_getfirst(nbcache_iter_t *); 641 int smb_netbios_cache_getnext(nbcache_iter_t *); 642 643 void smb_netbios_name_dump(struct name_entry *entry); 644 void smb_netbios_name_logf(struct name_entry *entry); 645 void smb_netbios_name_freeaddrs(struct name_entry *entry); 646 struct name_entry *smb_netbios_name_dup(struct name_entry *, int); 647 648 /* Name service functions */ 649 void *smb_netbios_name_service_daemon(void *); 650 void smb_init_name_struct(unsigned char *, char, unsigned char *, uint32_t, 651 unsigned short, uint32_t, uint32_t, struct name_entry *); 652 653 struct name_entry *smb_name_find_name(struct name_entry *name); 654 int smb_name_add_name(struct name_entry *name); 655 int smb_name_delete_name(struct name_entry *name); 656 void smb_name_unlock_name(struct name_entry *name); 657 658 void smb_netbios_name_config(void); 659 void smb_netbios_name_unconfig(void); 660 void smb_netbios_name_tick(void); 661 662 int smb_first_level_name_encode(struct name_entry *, unsigned char *, int); 663 int smb_first_level_name_decode(unsigned char *, struct name_entry *); 664 void smb_encode_netbios_name(unsigned char *, char, unsigned char *, 665 struct name_entry *); 666 667 /* Datagram service functions */ 668 void *smb_netbios_datagram_service_daemon(void *); 669 int smb_netbios_datagram_send(struct name_entry *, 670 struct name_entry *, unsigned char *, int); 671 void smb_netbios_datagram_tick(void); 672 673 /* browser functions */ 674 void *smb_browser_dispatch(void *arg); 675 void *smb_browser_daemon(void *); 676 int smb_browser_load_transact_header(unsigned char *, int, int, int, char *); 677 678 /* Netlogon function */ 679 void smb_netlogon_receive(struct datagram *, char *, unsigned char *, int); 680 void smb_netlogon_request(struct name_entry *, char *); 681 682 #endif /* _SMB_NETBIOS_H_ */ 683