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