encoding if it doesn't work out
*/
-interface nbt
+[ uuid("1-2-3-4"),
+ version(1.0),
+ depends(security)
+] interface nbt
{
const int NBT_NAME_SERVICE_PORT = 137;
const int NBT_DGRAM_SERVICE_PORT = 138;
/* the opcodes are in the operation field, masked with
NBT_OPCODE */
- const int NBT_OPCODE_QUERY = (0<<11);
- const int NBT_OPCODE_REGISTER = (5<<11);
- const int NBT_OPCODE_RELEASE = (6<<11);
- const int NBT_OPCODE_WACK = (7<<11);
- const int NBT_OPCODE_REFRESH = (8<<11);
+ typedef enum {
+ NBT_OPCODE_QUERY = (0x0<<11),
+ NBT_OPCODE_REGISTER = (0x5<<11),
+ NBT_OPCODE_RELEASE = (0x6<<11),
+ NBT_OPCODE_WACK = (0x7<<11),
+ NBT_OPCODE_REFRESH = (0x8<<11),
+ NBT_OPCODE_REFRESH2 = (0x9<<11),
+ NBT_OPCODE_MULTI_HOME_REG = (0xf<<11)
+ } nbt_opcode;
/* rcode values */
typedef enum {
+ NBT_RCODE_OK = 0x0,
NBT_RCODE_FMT = 0x1,
NBT_RCODE_SVR = 0x2,
NBT_RCODE_NAM = 0x3,
typedef struct {
nb_flags nb_flags;
- ipv4_addr ipaddr;
+ ipv4address ipaddr;
} nbt_rdata_address;
typedef struct {
nbt_res_rec additional[arcount];
[flag(NDR_REMAINING)] DATA_BLOB padding;
} nbt_name_packet;
+
+
+ /*
+ NBT DGRAM packets (UDP/138)
+ */
+
+ typedef [enum8bit] enum {
+ DGRAM_DIRECT_UNIQUE = 0x10,
+ DGRAM_DIRECT_GROUP = 0x11,
+ DGRAM_BCAST = 0x12,
+ DGRAM_ERROR = 0x13,
+ DGRAM_QUERY = 0x14,
+ DGRAM_QUERY_POSITIVE = 0x15,
+ DGRAM_QUERY_NEGATIVE = 0x16
+ } dgram_msg_type;
+
+ typedef [bitmap8bit] bitmap {
+ DGRAM_FLAG_MORE = 0x01,
+ DGRAM_FLAG_FIRST = 0x02,
+ DGRAM_FLAG_NODE_TYPE = 0x0C
+ } dgram_flags;
+
+ typedef [enum8bit] enum {
+ DGRAM_NODE_B = 0x00,
+ DGRAM_NODE_P = 0x04,
+ DGRAM_NODE_M = 0x08,
+ DGRAM_NODE_NBDD = 0x0C
+ } dgram_node_type;
+
+ /* a dgram_message is the main dgram body in general use */
+
+ /* the most common datagram type is a SMB_TRANSACTION
+ operation, where a SMB packet is used in the data section
+ of a dgram_message to hold a trans request, which in turn
+ holds a small command structure. It's a very strange beast
+ indeed. To make the code cleaner we define a basic SMB
+ packet in IDL here. This is not a general purpose SMB
+ packet, and won't be used in the core SMB client/server
+ code, but it does make working with these types of dgrams
+ easier */
+
+ const string NBT_MAILSLOT_NETLOGON = "\\MAILSLOT\\NET\\NETLOGON";
+ const string NBT_MAILSLOT_GETDC = "\\MAILSLOT\\GETDC";
+ const string NBT_MAILSLOT_BROWSE = "\\MAILSLOT\\BROWSE";
+
+ typedef [enum8bit] enum {
+ SMB_TRANSACTION = 0x25
+ } smb_command;
+
+ typedef struct {
+ [range(17,17),value(17)] uint8 wct;
+ uint16 total_param_count;
+ uint16 total_data_count;
+ uint16 max_param_count;
+ uint16 max_data_count;
+ uint8 max_setup_count;
+ uint8 pad;
+ uint16 trans_flags;
+ uint32 timeout;
+ uint16 reserved;
+ uint16 param_count;
+ uint16 param_offset;
+ uint16 data_count;
+ uint16 data_offset;
+ [range(3,3),value(3)] uint8 setup_count;
+ uint8 pad2;
+ uint16 opcode;
+ uint16 priority;
+ uint16 class;
+ [value(strlen(r->mailslot_name)+1+r->data.length)]
+ uint16 byte_count;
+ astring mailslot_name;
+ [flag(NDR_REMAINING)] DATA_BLOB data;
+ } smb_trans_body;
+
+ typedef [nodiscriminant] union {
+ [case(SMB_TRANSACTION)] smb_trans_body trans;
+ } smb_body;
+
+
+ typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN|NDR_PAHEX),public] struct {
+ smb_command smb_command;
+ uint8 err_class;
+ uint8 pad;
+ uint16 err_code;
+ uint8 flags;
+ uint16 flags2;
+ uint16 pid_high;
+ uint8 signature[8];
+ uint16 reserved;
+ uint16 tid;
+ uint16 pid;
+ uint16 vuid;
+ uint16 mid;
+ [switch_is(smb_command)] smb_body body;
+ } dgram_smb_packet;
+
+ typedef [v1_enum] enum {
+ DGRAM_SMB = 0xff534d42 /* 0xffSMB */
+ } dgram_body_type;
+
+ typedef [nodiscriminant] union {
+ [case(DGRAM_SMB)] dgram_smb_packet smb;
+ } dgram_message_body;
+
+ typedef struct {
+ uint16 length;
+ uint16 offset;
+ nbt_name source_name;
+ nbt_name dest_name;
+ dgram_body_type dgram_body_type;
+ [switch_is(dgram_body_type)] dgram_message_body body;
+ } dgram_message;
+
+ typedef [enum8bit] enum {
+ DGRAM_ERROR_NAME_NOT_PRESENT = 0x82,
+ DGRAM_ERROR_INVALID_SOURCE = 0x83,
+ DGRAM_ERROR_INVALID_DEST = 0x84
+ } dgram_err_code;
+
+ typedef [nodiscriminant] union {
+ [case(DGRAM_DIRECT_UNIQUE)] dgram_message msg;
+ [case(DGRAM_DIRECT_GROUP)] dgram_message msg;
+ [case(DGRAM_BCAST)] dgram_message msg;
+ [case(DGRAM_ERROR)] dgram_err_code error;
+ [case(DGRAM_QUERY)] nbt_name dest_name;
+ [case(DGRAM_QUERY_POSITIVE)] nbt_name dest_name;
+ [case(DGRAM_QUERY_NEGATIVE)] nbt_name dest_name;
+ } dgram_data;
+
+ typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
+ dgram_msg_type msg_type;
+ dgram_flags flags;
+ uint16 dgram_id;
+ ipv4address source;
+ uint16 src_port;
+ [switch_is(msg_type)] dgram_data data;
+ } nbt_dgram_packet;
+
+
+ /* \MAILSLOT\NET\NETLOGON mailslot requests */
+ typedef enum {
+ NETLOGON_QUERY_FOR_PDC = 0x7,
+ NETLOGON_ANNOUNCE_UAS = 0xa,
+ NETLOGON_RESPONSE_FROM_PDC = 0xc
+ } nbt_netlogon_command;
+
+ /* query for pdc request */
+ typedef struct {
+ astring computer_name;
+ astring mailslot_name;
+ [flag(NDR_ALIGN2)] DATA_BLOB _pad;
+ nstring unicode_name;
+ uint32 nt_version;
+ uint16 lmnt_token;
+ uint16 lm20_token;
+ } nbt_netlogon_query_for_pdc;
+
+ /* response from request */
+ typedef struct {
+ astring pdc_name;
+ [flag(NDR_ALIGN2)] DATA_BLOB _pad;
+ nstring unicode_pdc_name;
+ nstring domain_name;
+ uint32 nt_version;
+ uint16 lmnt_token;
+ uint16 lm20_token;
+ } nbt_netlogon_response_from_pdc;
+
+ /* announce change to UAS or SAM */
+ typedef struct {
+ uint32 db_index;
+ hyper serial;
+ NTTIME timestamp;
+ } nbt_db_change;
+
+ /* used to announce SAM changes */
+ typedef struct {
+ uint32 serial_lo;
+ time_t timestamp;
+ uint32 pulse;
+ uint32 random;
+ astring pdc_name;
+ astring domain;
+ [flag(NDR_ALIGN2)] DATA_BLOB _pad;
+ nstring unicode_pdc_name;
+ nstring unicode_domain;
+ uint32 db_count;
+ nbt_db_change dbchange[db_count];
+ [value(ndr_size_dom_sid(&r->sid))] uint32 sid_size;
+ uint16 unknown;
+ dom_sid sid;
+ uint32 nt_version;
+ uint16 lmnt_token;
+ uint16 lm20_token;
+ } nbt_netlogon_announce_uas;
+
+ typedef [nodiscriminant] union {
+ [case(NETLOGON_QUERY_FOR_PDC)] nbt_netlogon_query_for_pdc pdc;
+ [case(NETLOGON_ANNOUNCE_UAS)] nbt_netlogon_announce_uas uas;
+ [case(NETLOGON_RESPONSE_FROM_PDC)] nbt_netlogon_response_from_pdc response;
+ } nbt_netlogon_request;
+
+ typedef [flag(NDR_NOALIGN),public] struct {
+ nbt_netlogon_command command;
+ [switch_is(command)] nbt_netlogon_request req;
+ } nbt_netlogon_packet;
}