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