r5118: added support for node status replies in nbtd. nmblookup -S now works against...
[samba.git] / source / librpc / ndr / ndr_basic.c
index 8c9664771d267295f94a0a97f96d345203111922..61b3c9ec4dcaaea8f11f23dee4db20d7caed4061 100644 (file)
@@ -118,9 +118,9 @@ NTSTATUS ndr_pull_ptr(struct ndr_pull *ndr, uint32_t *v)
 }
 
 /*
-  parse a uint64
+  parse a udlong
 */
-NTSTATUS ndr_pull_uint64(struct ndr_pull *ndr, uint64_t *v)
+NTSTATUS ndr_pull_udlong(struct ndr_pull *ndr, uint64_t *v)
 {
        NDR_PULL_ALIGN(ndr, 4);
        NDR_PULL_NEED_BYTES(ndr, 8);
@@ -131,20 +131,20 @@ NTSTATUS ndr_pull_uint64(struct ndr_pull *ndr, uint64_t *v)
 }
 
 /*
-  parse a int64
+  parse a dlong
 */
-NTSTATUS ndr_pull_int64(struct ndr_pull *ndr, int64_t *v)
+NTSTATUS ndr_pull_dlong(struct ndr_pull *ndr, int64_t *v)
 {
-       return ndr_pull_uint64(ndr, (uint64_t *)v);
+       return ndr_pull_udlong(ndr, (uint64_t *)v);
 }
 
 /*
-  parse a HYPER_T
+  parse a hyper
 */
-NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
+NTSTATUS ndr_pull_hyper(struct ndr_pull *ndr, uint64_t *v)
 {
        NDR_PULL_ALIGN(ndr, 8);
-       return ndr_pull_uint64(ndr, v);
+       return ndr_pull_udlong(ndr, v);
 }
 
 /*
@@ -249,16 +249,16 @@ NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *da
 }
 
 /*
-  pull a const array of HYPER_T
+  pull a const array of hyper
 */
-NTSTATUS ndr_pull_array_HYPER_T(struct ndr_pull *ndr, int ndr_flags, HYPER_T *data, uint32_t n)
+NTSTATUS ndr_pull_array_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *data, uint32_t n)
 {
        uint32_t i;
        if (!(ndr_flags & NDR_SCALARS)) {
                return NT_STATUS_OK;
        }
        for (i=0;i<n;i++) {
-               NDR_CHECK(ndr_pull_HYPER_T(ndr, &data[i]));
+               NDR_CHECK(ndr_pull_hyper(ndr, &data[i]));
        }
        return NT_STATUS_OK;
 }
@@ -330,7 +330,7 @@ NTSTATUS ndr_push_int32(struct ndr_push *ndr, int32_t v)
 /*
   push a uint64
 */
-NTSTATUS ndr_push_uint64(struct ndr_push *ndr, uint64_t v)
+NTSTATUS ndr_push_udlong(struct ndr_push *ndr, uint64_t v)
 {
        NDR_PUSH_ALIGN(ndr, 4);
        NDR_PUSH_NEED_BYTES(ndr, 8);
@@ -343,18 +343,18 @@ NTSTATUS ndr_push_uint64(struct ndr_push *ndr, uint64_t v)
 /*
   push a int64
 */
-NTSTATUS ndr_push_int64(struct ndr_push *ndr, int64_t v)
+NTSTATUS ndr_push_dlong(struct ndr_push *ndr, int64_t v)
 {
-       return ndr_push_uint64(ndr, (uint64_t)v);
+       return ndr_push_udlong(ndr, (uint64_t)v);
 }
 
 /*
-  push a HYPER_T
+  push a hyper
 */
-NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
+NTSTATUS ndr_push_hyper(struct ndr_push *ndr, uint64_t v)
 {
        NDR_PUSH_ALIGN(ndr, 8);
-       return ndr_push_uint64(ndr, v);
+       return ndr_push_udlong(ndr, v);
 }
 
 NTSTATUS ndr_push_align(struct ndr_push *ndr, size_t size)
@@ -433,22 +433,22 @@ NTSTATUS ndr_push_array_uint32(struct ndr_push *ndr, int ndr_flags, const uint32
 }
 
 /*
-  push an array of HYPER_T
+  push an array of hyper
 */
-NTSTATUS ndr_push_array_HYPER_T(struct ndr_push *ndr, int ndr_flags, const HYPER_T *data, uint32_t n)
+NTSTATUS ndr_push_array_hyper(struct ndr_push *ndr, int ndr_flags, const uint64_t *data, uint32_t n)
 {
        int i;
        if (!(ndr_flags & NDR_SCALARS)) {
                return NT_STATUS_OK;
        }
        for (i=0;i<n;i++) {
-               NDR_CHECK(ndr_push_HYPER_T(ndr, data[i]));
+               NDR_CHECK(ndr_push_hyper(ndr, data[i]));
        }
        return NT_STATUS_OK;
 }
 
 /*
-  push an array of HYPER_T
+  push an array of hyper
 */
 NTSTATUS ndr_push_array_WERROR(struct ndr_push *ndr, int ndr_flags, const WERROR *data, uint32_t n)
 {
@@ -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);
+                                    s, s_len,
+                                    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;
 
@@ -941,7 +946,7 @@ size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
 */
 NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
 {
-       NDR_CHECK(ndr_push_uint64(ndr, t));
+       NDR_CHECK(ndr_push_udlong(ndr, t));
        return NT_STATUS_OK;
 }
 
@@ -950,7 +955,7 @@ NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
 */
 NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
 {
-       NDR_CHECK(ndr_pull_uint64(ndr, t));
+       NDR_CHECK(ndr_pull_udlong(ndr, t));
        return NT_STATUS_OK;
 }
 
@@ -960,20 +965,38 @@ NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
 NTSTATUS ndr_push_NTTIME_1sec(struct ndr_push *ndr, NTTIME t)
 {
        t /= 10000000;
-       NDR_CHECK(ndr_push_HYPER_T(ndr, t));
+       NDR_CHECK(ndr_push_hyper(ndr, t));
        return NT_STATUS_OK;
 }
 
 /*
-  pull a NTTIME
+  pull a NTTIME_1sec
 */
 NTSTATUS ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, NTTIME *t)
 {
-       NDR_CHECK(ndr_pull_HYPER_T(ndr, t));
+       NDR_CHECK(ndr_pull_hyper(ndr, t));
        (*t) *= 10000000;
        return NT_STATUS_OK;
 }
 
+/*
+  pull a NTTIME_hyper
+*/
+NTSTATUS ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, NTTIME *t)
+{
+       NDR_CHECK(ndr_pull_hyper(ndr, t));
+       return NT_STATUS_OK;
+}
+
+/*
+  push a NTTIME_hyper
+*/
+NTSTATUS ndr_push_NTTIME_hyper(struct ndr_push *ndr, NTTIME t)
+{
+       NDR_CHECK(ndr_push_hyper(ndr, t));
+       return NT_STATUS_OK;
+}
+
 /*
   push a time_t
 */
@@ -1002,16 +1025,27 @@ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
 void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type, 
                    const char *val, uint_t value)
 {
-       ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
+       if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
+               ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
+       } else {
+               ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
+       }
 }
 
 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)
@@ -1034,7 +1068,7 @@ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v)
        ndr->print(ndr, "%-25s: %d", name, v);
 }
 
-void ndr_print_uint64(struct ndr_print *ndr, const char *name, uint64_t v)
+void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v)
 {
        ndr->print(ndr, "%-25s: 0x%08x%08x (%llu)", name,
                   (uint32_t)(v >> 32),
@@ -1042,7 +1076,7 @@ void ndr_print_uint64(struct ndr_print *ndr, const char *name, uint64_t v)
                   v);
 }
 
-void ndr_print_int64(struct ndr_print *ndr, const char *name, int64_t v)
+void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v)
 {
        ndr->print(ndr, "%-25s: 0x%08x%08x (%lld)", name, 
                   (uint32_t)(v >> 32), 
@@ -1050,9 +1084,9 @@ void ndr_print_int64(struct ndr_print *ndr, const char *name, int64_t v)
                   v);
 }
 
-void ndr_print_HYPER_T(struct ndr_print *ndr, const char *name, HYPER_T v)
+void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v)
 {
-       ndr->print(ndr, "%-25s: 0x%08x%08x", name, (uint32_t)(v >> 32), (uint32_t)(v & 0xFFFFFFFF));
+       ndr_print_dlong(ndr, name, v);
 }
 
 void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
@@ -1079,6 +1113,14 @@ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
 }
 
 void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
+{
+       /* this is a standard NTTIME here
+        * as it's already converted in the pull/push code
+        */
+       ndr_print_NTTIME(ndr, name, t);
+}
+
+void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t)
 {
        ndr_print_NTTIME(ndr, name, t);
 }
@@ -1120,8 +1162,8 @@ void ndr_print_array_WERROR(struct ndr_print *ndr, const char *name,
        ndr->depth--;   
 }
 
-void ndr_print_array_HYPER_T(struct ndr_print *ndr, const char *name, 
-                           const HYPER_T *data, uint32_t count)
+void ndr_print_array_hyper(struct ndr_print *ndr, const char *name, 
+                           const uint64_t *data, uint32_t count)
 {
        int i;
 
@@ -1131,7 +1173,7 @@ void ndr_print_array_HYPER_T(struct ndr_print *ndr, const char *name,
                char *idx=NULL;
                asprintf(&idx, "[%d]", i);
                if (idx) {
-                       ndr_print_HYPER_T(ndr, idx, data[i]);
+                       ndr_print_hyper(ndr, idx, data[i]);
                        free(idx);
                }
        }