summaryrefslogtreecommitdiff
path: root/source4/librpc
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-21 06:54:10 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:09:01 -0500
commitea923fb4a26f88664a1db36e1a93a2c96239a7a4 (patch)
tree23456be2c837e5c0f56706f9be119b66d32b9590 /source4/librpc
parente0d2080219c7d52559a5bbcc7294995fccbd5e52 (diff)
downloadsamba-ea923fb4a26f88664a1db36e1a93a2c96239a7a4.tar.gz
samba-ea923fb4a26f88664a1db36e1a93a2c96239a7a4.tar.bz2
samba-ea923fb4a26f88664a1db36e1a93a2c96239a7a4.zip
r4885: added a new NBT client library. Features include:
- structures defined using IDL in nbt.idl - build around our events structure, and talloc - fully async - supports all NBT packet fields as per rfc1002 - easy interfaces for name query and status For the moment there are just a couple of test functions in namequery.c, test_name_query() and test_name_status(). These will be removed when we hook the new library into libcli/ fully The new library will also be a fairly good basis for a nbt server. Although it can't be a server as-is, I wrote it with the needs of a server in mind (for example, extremely scalable idtree based packet handling) (This used to be commit ae7e625bfa4b4a3ee32c64566064b6a4c84ee4b9)
Diffstat (limited to 'source4/librpc')
-rw-r--r--source4/librpc/config.mk9
-rw-r--r--source4/librpc/idl/idl_types.h6
-rw-r--r--source4/librpc/idl/nbt.idl166
-rw-r--r--source4/librpc/ndr/libndr.h3
-rw-r--r--source4/librpc/ndr/ndr.c21
-rw-r--r--source4/librpc/ndr/ndr_basic.c34
6 files changed, 226 insertions, 13 deletions
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 3fbd5dadbc..75582c2adc 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -287,6 +287,13 @@ INIT_OBJ_FILES = librpc/gen_ndr/ndr_schannel.o
NOPROTO = YES
REQUIRED_SUBSYSTEMS = LIBNDR
+[SUBSYSTEM::NDR_NBT]
+INIT_OBJ_FILES = librpc/gen_ndr/ndr_nbt.o
+INIT_FUNCTION = dcerpc_nbt_init
+NOPROTO = YES
+REQUIRED_SUBSYSTEMS = LIBNDR
+
+
[SUBSYSTEM::NDR_ALL]
REQUIRED_SUBSYSTEMS = NDR_AUDIOSRV NDR_ECHO NDR_DCERPC NDR_EXCHANGE \
NDR_DSBACKUP NDR_EFS NDR_MISC NDR_LSA NDR_DFS NDR_DRSUAPI \
@@ -295,7 +302,7 @@ REQUIRED_SUBSYSTEMS = NDR_AUDIOSRV NDR_ECHO NDR_DCERPC NDR_EXCHANGE \
NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_DCOM NDR_OXIDRESOLVER \
NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \
NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
- NDR_ROT NDR_DRSBLOBS NDR_SVCCTL LIB_SECURITY_NDR
+ NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT LIB_SECURITY_NDR
[SUBSYSTEM::RPC_NDR_ROT]
ADD_OBJ_FILES = librpc/gen_ndr/ndr_rot_c.o
diff --git a/source4/librpc/idl/idl_types.h b/source4/librpc/idl/idl_types.h
index 9463fe0c47..1db778476c 100644
--- a/source4/librpc/idl/idl_types.h
+++ b/source4/librpc/idl/idl_types.h
@@ -6,6 +6,7 @@
#define STR_NULLTERM LIBNDR_FLAG_STR_NULLTERM
#define STR_BYTESIZE LIBNDR_FLAG_STR_BYTESIZE
#define STR_FIXLEN32 LIBNDR_FLAG_STR_FIXLEN32
+#define STR_FIXLEN15 LIBNDR_FLAG_STR_FIXLEN15
#define STR_CONFORMANT LIBNDR_FLAG_STR_CONFORMANT
#define STR_CHARLEN LIBNDR_FLAG_STR_CHARLEN
#define STR_UTF8 LIBNDR_FLAG_STR_UTF8
@@ -37,6 +38,11 @@
#define string32 [flag(STR_FIXLEN32)] string
/*
+ fixed length 16 character ascii string
+*/
+#define astring15 [flag(STR_ASCII|STR_FIXLEN15)] string
+
+/*
an ascii string prefixed with [size] [offset] [length], all 32 bits
null terminated
*/
diff --git a/source4/librpc/idl/nbt.idl b/source4/librpc/idl/nbt.idl
new file mode 100644
index 0000000000..909ff502e8
--- /dev/null
+++ b/source4/librpc/idl/nbt.idl
@@ -0,0 +1,166 @@
+#include "idl_types.h"
+
+/*
+ IDL structures for NBT operations
+
+ NBT is not traditionally encoded using IDL/NDR. This is a bit of an
+ experiment, and I may well switch us back to a more traditional
+ encoding if it doesn't work out
+*/
+
+interface nbt
+{
+ const int NBT_NAME_SERVICE_PORT = 137;
+ const int NBT_DGRAM_SERVICE_PORT = 138;
+
+ typedef [bitmap16bit] bitmap {
+ NBT_RCODE = 0x000F,
+ NBT_FLAG_BROADCAST = 0x0010,
+ NBT_FLAG_RECURSION_AVAIL = 0x0080,
+ NBT_FLAG_RECURSION_DESIRED = 0x0100,
+ NBT_FLAG_TRUNCATION = 0x0200,
+ NBT_FLAG_AUTHORITIVE = 0x0400,
+ NBT_OPCODE = 0x7800,
+ NBT_FLAG_REPLY = 0x8000
+ } nbt_operation;
+
+ /* 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);
+
+ /* rcode values */
+ typedef enum {
+ NBT_RCODE_FMT = 0x1,
+ NBT_RCODE_SVR = 0x2,
+ NBT_RCODE_NAM = 0x3,
+ NBT_RCODE_IMP = 0x4,
+ NBT_RCODE_RFS = 0x5,
+ NBT_RCODE_ACT = 0x6,
+ NBT_RCODE_CFT = 0x7
+ } nbt_rcode;
+
+ /* we support any 8bit name type, but by defining the common
+ ones here we get better debug displays */
+ typedef [enum8bit] enum {
+ NBT_NAME_CLIENT = 0x00,
+ NBT_NAME_MS = 0x01,
+ NBT_NAME_USER = 0x03,
+ NBT_NAME_SERVER = 0x20,
+ NBT_NAME_PDC = 0x1B,
+ NBT_NAME_LOGON = 0x1C,
+ NBT_NAME_MASTER = 0x1D,
+ NBT_NAME_BROWSER = 0x1E
+ } nbt_name_type;
+
+ /* the ndr parser for nbt_name is separately defined in
+ nbtname.c */
+ typedef [nopull,nopush] struct {
+ string name;
+ string scope;
+ nbt_name_type type;
+ } nbt_name;
+
+ typedef [enum16bit] enum {
+ NBT_QCLASS_IP = 0x01
+ } nbt_qclass;
+
+ typedef [enum16bit] enum {
+ NBT_QTYPE_ADDRESS = 0x0001,
+ NBT_QTYPE_NAMESERVICE = 0x0002,
+ NBT_QTYPE_NULL = 0x000A,
+ NBT_QTYPE_NETBIOS = 0x0020,
+ NBT_QTYPE_STATUS = 0x0021
+ } nbt_qtype;
+
+ typedef struct {
+ nbt_name name;
+ nbt_qtype question_type;
+ nbt_qclass question_class;
+ } nbt_name_question;
+
+ typedef [bitmap16bit] bitmap {
+ NBT_NM_PERMANENT = 0x0200,
+ NBT_NM_ACTIVE = 0x0400,
+ NBT_NM_CONFLICT = 0x0800,
+ NBT_NM_DEREGISTER = 0x1000,
+ NBT_NM_OWNER_TYPE = 0x6000,
+ NBT_NM_GROUP = 0x8000
+ } nb_flags;
+
+ typedef struct {
+ nb_flags nb_flags;
+ uint32 ipaddr;
+ } nbt_rdata_netbios;
+
+
+ typedef struct {
+ uint8 unit_id[6];
+ uint8 jumpers;
+ uint8 test_result;
+ uint16 version_number;
+ uint16 period_of_statistics;
+ uint16 number_of_crcs;
+ uint16 number_alignment_errors;
+ uint16 number_of_collisions;
+ uint16 number_send_aborts;
+ uint32 number_good_sends;
+ uint32 number_good_receives;
+ uint16 number_retransmits;
+ uint16 number_no_resource_conditions;
+ uint16 number_free_command_blocks;
+ uint16 total_number_command_blocks;
+ uint16 max_total_number_command_blocks;
+ uint16 number_pending_sessions;
+ uint16 max_number_pending_sessions;
+ uint16 max_total_sessions_possible;
+ uint16 session_data_packet_size;
+ } nbt_statistics;
+
+ typedef struct {
+ astring15 name;
+ nbt_name_type type;
+ nb_flags nb_flags;
+ } nbt_status_name;
+
+ typedef struct {
+ uint8 num_names;
+ nbt_status_name names[num_names];
+ nbt_statistics statistics;
+ } nbt_rdata_status;
+
+ typedef struct {
+ nbt_operation operation;
+ } nbt_rdata_wack;
+
+ typedef [nodiscriminant] union {
+ [case(NBT_QTYPE_NETBIOS)] nbt_rdata_netbios netbios;
+ [case(NBT_QTYPE_STATUS)] nbt_rdata_status status;
+ [case(NBT_QTYPE_NULL)] nbt_rdata_wack wack;
+ } nbt_rdata;
+
+ typedef [flag(LIBNDR_PRINT_ARRAY_HEX)] struct {
+ nbt_name name;
+ nbt_qtype rr_type;
+ nbt_qclass rr_class;
+ uint32 ttl;
+ [subcontext(2),switch_is(rr_type)] nbt_rdata rdata;
+ } nbt_res_rec;
+
+ typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
+ uint16 name_trn_id;
+ nbt_operation operation;
+ uint16 qdcount;
+ uint16 ancount;
+ uint16 nscount;
+ uint16 arcount;
+ nbt_name_question questions[qdcount];
+ nbt_res_rec answers[ancount];
+ nbt_res_rec nsrecs[nscount];
+ nbt_res_rec additional[arcount];
+ [flag(NDR_REMAINING)] DATA_BLOB padding;
+ } nbt_name_packet;
+}
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 288e753cca..b5a5573448 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -102,7 +102,8 @@ struct ndr_print {
#define LIBNDR_FLAG_STR_CONFORMANT (1<<10)
#define LIBNDR_FLAG_STR_CHARLEN (1<<11)
#define LIBNDR_FLAG_STR_UTF8 (1<<12)
-#define LIBNDR_STRING_FLAGS (0x1FFC)
+#define LIBNDR_FLAG_STR_FIXLEN15 (1<<13)
+#define LIBNDR_STRING_FLAGS (0x3FFC)
#define LIBNDR_FLAG_REF_ALLOC (1<<20)
diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c
index 7cc832c68e..8a25e27cc1 100644
--- a/source4/librpc/ndr/ndr.c
+++ b/source4/librpc/ndr/ndr.c
@@ -883,3 +883,24 @@ size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push)
talloc_free(ndr);
return ret;
}
+
+/*
+ generic ndr_size_*() handler for unions
+*/
+size_t ndr_size_union(const void *p, int flags, uint32_t level, ndr_push_union_fn_t push)
+{
+ struct ndr_push *ndr;
+ NTSTATUS status;
+ size_t ret;
+
+ ndr = ndr_push_init_ctx(NULL);
+ if (!ndr) return 0;
+ ndr->flags |= flags;
+ status = push(ndr, NDR_SCALARS|NDR_BUFFERS, level, discard_const(p));
+ if (!NT_STATUS_IS_OK(status)) {
+ return 0;
+ }
+ ret = ndr->offset;
+ talloc_free(ndr);
+ return ret;
+}
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
index 29a3009af6..6476f58764 100644
--- a/source4/librpc/ndr/ndr_basic.c
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -718,8 +718,9 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
*s = as;
break;
+ case LIBNDR_FLAG_STR_FIXLEN15:
case LIBNDR_FLAG_STR_FIXLEN32:
- len1 = 32;
+ len1 = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
NDR_PULL_NEED_BYTES(ndr, len1*byte_mul);
ret = convert_string_talloc(ndr, chset, CH_UNIX,
ndr->data+ndr->offset,
@@ -733,7 +734,6 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
*s = as;
break;
-
default:
return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
ndr->flags & LIBNDR_STRING_FLAGS);
@@ -748,7 +748,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
*/
NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
{
- ssize_t s_len, c_len;
+ ssize_t s_len, c_len, d_len;
int ret;
int chset = CH_UTF16;
unsigned flags = ndr->flags;
@@ -882,16 +882,18 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
ndr->offset += c_len*byte_mul;
break;
+ case LIBNDR_FLAG_STR_FIXLEN15:
case LIBNDR_FLAG_STR_FIXLEN32:
- NDR_PUSH_NEED_BYTES(ndr, byte_mul*32);
+ d_len = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
+ NDR_PUSH_NEED_BYTES(ndr, byte_mul*d_len);
ret = convert_string(CH_UNIX, chset,
s, s_len + 1,
- ndr->data+ndr->offset, byte_mul*32);
+ ndr->data+ndr->offset, byte_mul*d_len);
if (ret == -1) {
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
- ndr->offset += byte_mul*32;
+ ndr->offset += byte_mul*d_len;
break;
default:
@@ -915,6 +917,9 @@ size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
if (flags & LIBNDR_FLAG_STR_FIXLEN32) {
return 32;
}
+ if (flags & LIBNDR_FLAG_STR_FIXLEN15) {
+ return 15;
+ }
c_len = s?strlen_m(s):0;
@@ -1029,11 +1034,18 @@ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type,
void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint_t flag, uint_t value)
{
- /* size can be later used to print something like:
- * ...1.... .........: FLAG1_NAME
- * .....0.. .........: FLAG2_NAME
- */
- ndr->print(ndr, "%s: %-25s", (flag & value)?"1":"0", flag_name);
+ /* this is an attempt to support multi-bit bitmap masks */
+ value &= flag;
+
+ while (!(flag & 1)) {
+ flag >>= 1;
+ value >>= 1;
+ }
+ if (flag == 1) {
+ ndr->print(ndr, " %d: %-25s", value, flag_name);
+ } else {
+ ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value);
+ }
}
void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)