2 Unix SMB/CIFS implementation.
4 routines for marshalling/unmarshalling basic types
6 Copyright (C) Andrew Tridgell 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #define NDR_BE(ndr) (((ndr)->flags & (LIBNDR_FLAG_BIGENDIAN|LIBNDR_FLAG_LITTLE_ENDIAN)) == LIBNDR_FLAG_BIGENDIAN)
26 #define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
27 #define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
28 #define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
29 #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
34 NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, uint8_t *v)
36 NDR_PULL_NEED_BYTES(ndr, 1);
37 *v = CVAL(ndr->data, ndr->offset);
46 NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16_t *v)
48 NDR_PULL_ALIGN(ndr, 2);
49 NDR_PULL_NEED_BYTES(ndr, 2);
50 *v = NDR_SVAL(ndr, ndr->offset);
59 NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32_t *v)
61 NDR_PULL_ALIGN(ndr, 4);
62 NDR_PULL_NEED_BYTES(ndr, 4);
63 *v = NDR_IVAL(ndr, ndr->offset);
71 NTSTATUS ndr_pull_ptr(struct ndr_pull *ndr, uint32_t *v)
74 status = ndr_pull_uint32(ndr, v);
84 NTSTATUS ndr_pull_uint64(struct ndr_pull *ndr, uint64_t *v)
86 NDR_PULL_ALIGN(ndr, 4);
87 NDR_PULL_NEED_BYTES(ndr, 8);
88 *v = NDR_IVAL(ndr, ndr->offset);
89 *v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32;
97 NTSTATUS ndr_pull_int64(struct ndr_pull *ndr, int64_t *v)
99 return ndr_pull_uint64(ndr, (uint64_t *)v);
105 NTSTATUS ndr_pull_HYPER_T(struct ndr_pull *ndr, HYPER_T *v)
107 NDR_PULL_ALIGN(ndr, 8);
108 return ndr_pull_uint64(ndr, v);
114 NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, NTSTATUS *status)
117 NDR_CHECK(ndr_pull_uint32(ndr, &v));
118 *status = NT_STATUS(v);
125 NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, NTSTATUS status)
127 return ndr_push_uint32(ndr, NT_STATUS_V(status));
130 void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS *r)
132 ndr->print(ndr, "%-25s: %s", name, nt_errstr(*r));
138 NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, WERROR *status)
141 NDR_CHECK(ndr_pull_uint32(ndr, &v));
142 *status = W_ERROR(v);
149 NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, WERROR status)
151 return ndr_push_uint32(ndr, W_ERROR_V(status));
154 void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR *r)
156 ndr->print(ndr, "%-25s: %s", name, win_errstr(*r));
162 NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32_t n)
164 NDR_PULL_NEED_BYTES(ndr, n);
165 memcpy(data, ndr->data + ndr->offset, n);
171 pull an array of uint8
173 NTSTATUS ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, char *data, uint32_t n)
175 if (!(ndr_flags & NDR_SCALARS)) {
178 return ndr_pull_bytes(ndr, data, n);
183 pull an array of uint16
185 NTSTATUS ndr_pull_array_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *data, uint32_t n)
188 if (!(ndr_flags & NDR_SCALARS)) {
192 NDR_CHECK(ndr_pull_uint16(ndr, &data[i]));
198 pull a const array of uint32_t
200 NTSTATUS ndr_pull_array_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *data, uint32_t n)
203 if (!(ndr_flags & NDR_SCALARS)) {
207 NDR_CHECK(ndr_pull_uint32(ndr, &data[i]));
213 pull a const array of HYPER_T
215 NTSTATUS ndr_pull_array_HYPER_T(struct ndr_pull *ndr, int ndr_flags, HYPER_T *data, uint32_t n)
218 if (!(ndr_flags & NDR_SCALARS)) {
222 NDR_CHECK(ndr_pull_HYPER_T(ndr, &data[i]));
230 NTSTATUS ndr_push_uint8(struct ndr_push *ndr, uint8_t v)
232 NDR_PUSH_NEED_BYTES(ndr, 1);
233 SCVAL(ndr->data, ndr->offset, v);
241 NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16_t v)
243 NDR_PUSH_ALIGN(ndr, 2);
244 NDR_PUSH_NEED_BYTES(ndr, 2);
245 NDR_SSVAL(ndr, ndr->offset, v);
253 NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32_t v)
255 NDR_PUSH_ALIGN(ndr, 4);
256 NDR_PUSH_NEED_BYTES(ndr, 4);
257 NDR_SIVAL(ndr, ndr->offset, v);
265 NTSTATUS ndr_push_uint64(struct ndr_push *ndr, uint64_t v)
267 NDR_PUSH_ALIGN(ndr, 4);
268 NDR_PUSH_NEED_BYTES(ndr, 8);
269 NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
270 NDR_SIVAL(ndr, ndr->offset+4, (v>>32));
278 NTSTATUS ndr_push_int64(struct ndr_push *ndr, int64_t v)
280 return ndr_push_uint64(ndr, (uint64_t)v);
286 NTSTATUS ndr_push_HYPER_T(struct ndr_push *ndr, HYPER_T v)
288 NDR_PUSH_ALIGN(ndr, 8);
289 return ndr_push_uint64(ndr, v);
292 NTSTATUS ndr_push_align(struct ndr_push *ndr, size_t size)
294 NDR_PUSH_ALIGN(ndr, size);
298 NTSTATUS ndr_pull_align(struct ndr_pull *ndr, size_t size)
300 NDR_PULL_ALIGN(ndr, size);
307 NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32_t n)
309 NDR_PUSH_NEED_BYTES(ndr, n);
310 memcpy(ndr->data + ndr->offset, data, n);
318 NTSTATUS ndr_push_zero(struct ndr_push *ndr, uint32_t n)
320 NDR_PUSH_NEED_BYTES(ndr, n);
321 memset(ndr->data + ndr->offset, 0, n);
327 push an array of uint8
329 NTSTATUS ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const char *data, uint32_t n)
331 if (!(ndr_flags & NDR_SCALARS)) {
334 return ndr_push_bytes(ndr, data, n);
338 push an array of uint16
340 NTSTATUS ndr_push_array_uint16(struct ndr_push *ndr, int ndr_flags, const uint16_t *data, uint32_t n)
343 if (!(ndr_flags & NDR_SCALARS)) {
347 NDR_CHECK(ndr_push_uint16(ndr, data[i]));
353 push an array of uint32_t
355 NTSTATUS ndr_push_array_uint32(struct ndr_push *ndr, int ndr_flags, const uint32_t *data, uint32_t n)
358 if (!(ndr_flags & NDR_SCALARS)) {
362 NDR_CHECK(ndr_push_uint32(ndr, data[i]));
368 push an array of HYPER_T
370 NTSTATUS ndr_push_array_HYPER_T(struct ndr_push *ndr, int ndr_flags, const HYPER_T *data, uint32_t n)
373 if (!(ndr_flags & NDR_SCALARS)) {
377 NDR_CHECK(ndr_push_HYPER_T(ndr, data[i]));
383 save the current position
385 void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save)
387 save->offset = ndr->offset;
393 void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
395 ndr->offset = save->offset;
399 push a 1 if a pointer is non-NULL, otherwise 0
401 NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
405 /* we do this to ensure that we generate unique ref ids,
406 which means we can handle the case where a MS programmer
407 forgot to mark a pointer as unique */
409 ptr = ndr->ptr_count;
411 return ndr_push_uint32(ndr, ptr);
416 pull a general string from the wire
418 NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
421 uint32_t len1, ofs, len2;
426 if (!(ndr_flags & NDR_SCALARS)) {
434 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
435 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
436 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
437 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
438 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
439 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
441 return ndr_pull_error(ndr, NDR_ERR_STRING,
442 "Bad string lengths len1=%u ofs=%u len2=%u\n",
446 *s = talloc_strdup(ndr->mem_ctx, "");
449 NDR_PULL_NEED_BYTES(ndr, len2*2);
450 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
451 ndr->data+ndr->offset,
455 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
456 "Bad character conversion");
458 NDR_CHECK(ndr_pull_advance(ndr, len2*2));
460 /* this is a way of detecting if a string is sent with the wrong
462 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
463 if (strlen(as) < len2) {
464 DEBUG(6,("short string '%s'\n", as));
467 if (strlen(as) == len2) {
468 DEBUG(6,("long string '%s'\n", as));
474 case LIBNDR_FLAG_STR_SIZE4:
475 case LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
476 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
477 NDR_PULL_NEED_BYTES(ndr, len1*2);
479 *s = talloc_strdup(ndr->mem_ctx, "");
482 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
483 ndr->data+ndr->offset,
487 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
488 "Bad character conversion");
490 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
492 /* this is a way of detecting if a string is sent with the wrong
494 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
495 if (strlen(as) < len1) {
496 DEBUG(6,("short string '%s'\n", as));
499 if (strlen(as) == len1) {
500 DEBUG(6,("long string '%s'\n", as));
506 case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE:
507 NDR_CHECK(ndr_pull_uint16(ndr, &len3));
508 NDR_PULL_NEED_BYTES(ndr, len3);
510 *s = talloc_strdup(ndr->mem_ctx, "");
513 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
514 ndr->data+ndr->offset,
518 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
519 "Bad character conversion");
521 NDR_CHECK(ndr_pull_advance(ndr, len3));
525 case LIBNDR_FLAG_STR_NULLTERM:
526 len1 = strnlen_w(ndr->data+ndr->offset,
527 (ndr->data_size - ndr->offset)/2);
528 if (len1*2+2 <= ndr->data_size - ndr->offset) {
531 ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX,
532 ndr->data+ndr->offset,
536 return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
537 "Bad character conversion");
539 NDR_CHECK(ndr_pull_advance(ndr, len1*2));
543 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
544 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
545 NDR_CHECK(ndr_pull_uint32(ndr, &len1));
546 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
547 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
549 return ndr_pull_error(ndr, NDR_ERR_STRING,
550 "Bad ascii string lengths len1=%u ofs=%u len2=%u\n",
553 NDR_ALLOC_N(ndr, as, (len2+1));
554 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
559 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
560 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
561 NDR_CHECK(ndr_pull_uint32(ndr, &len2));
562 NDR_ALLOC_N(ndr, as, (len2+1));
563 NDR_CHECK(ndr_pull_bytes(ndr, as, len2));
568 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
569 NDR_CHECK(ndr_pull_uint16(ndr, &len3));
570 NDR_ALLOC_N(ndr, as, (len3+1));
571 NDR_CHECK(ndr_pull_bytes(ndr, as, len3));
576 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM:
577 len1 = strnlen(ndr->data+ndr->offset, (ndr->data_size - ndr->offset));
578 if (len1+1 <= ndr->data_size - ndr->offset) {
581 NDR_ALLOC_N(ndr, as, (len1+1));
582 NDR_CHECK(ndr_pull_bytes(ndr, as, len1));
588 return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
589 ndr->flags & LIBNDR_STRING_FLAGS);
597 push a general string onto the wire
599 NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
601 ssize_t s_len, c_len;
605 if (!(ndr_flags & NDR_SCALARS)) {
613 s_len = s?strlen(s):0;
614 c_len = s?strlen_m(s):0;
616 switch (ndr->flags & LIBNDR_STRING_FLAGS) {
617 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
618 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
619 NDR_CHECK(ndr_push_uint32(ndr, 0));
620 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
621 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
622 ret = convert_string(CH_UNIX, chset,
624 ndr->data+ndr->offset, c_len*2 + 2);
626 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
627 "Bad character conversion");
629 ndr->offset += c_len*2 + 2;
632 case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
633 NDR_CHECK(ndr_push_uint32(ndr, c_len));
634 NDR_CHECK(ndr_push_uint32(ndr, 0));
635 NDR_CHECK(ndr_push_uint32(ndr, c_len));
636 NDR_PUSH_NEED_BYTES(ndr, c_len*2);
637 ret = convert_string(CH_UNIX, chset,
639 ndr->data+ndr->offset, c_len*2);
641 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
642 "Bad character conversion");
644 ndr->offset += c_len*2;
647 case LIBNDR_FLAG_STR_SIZE4:
648 NDR_CHECK(ndr_push_uint32(ndr, c_len + 1));
649 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
650 ret = convert_string(CH_UNIX, chset,
652 ndr->data+ndr->offset, c_len*2 + 2);
654 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
655 "Bad character conversion");
657 ndr->offset += c_len*2 + 2;
660 case LIBNDR_FLAG_STR_NULLTERM:
661 NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2);
662 ret = convert_string(CH_UNIX, chset,
664 ndr->data+ndr->offset, c_len*2 + 2);
666 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
667 "Bad character conversion");
669 ndr->offset += c_len*2 + 2;
672 case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE:
673 NDR_CHECK(ndr_push_uint16(ndr, c_len*2));
674 NDR_PUSH_NEED_BYTES(ndr, c_len*2);
675 ret = convert_string(CH_UNIX, chset,
677 ndr->data+ndr->offset, c_len*2);
679 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
680 "Bad character conversion");
682 ndr->offset += c_len*2;
685 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
686 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
687 NDR_CHECK(ndr_push_uint32(ndr, 0));
688 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
689 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
690 ret = convert_string(CH_UNIX, CH_DOS,
692 ndr->data+ndr->offset, c_len + 1);
694 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
695 "Bad character conversion");
697 ndr->offset += c_len + 1;
700 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
701 NDR_CHECK(ndr_push_uint32(ndr, c_len));
702 NDR_CHECK(ndr_push_uint32(ndr, 0));
703 NDR_CHECK(ndr_push_uint32(ndr, c_len));
704 NDR_PUSH_NEED_BYTES(ndr, c_len);
705 ret = convert_string(CH_UNIX, CH_DOS,
707 ndr->data+ndr->offset, c_len);
709 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
710 "Bad character conversion");
712 ndr->offset += c_len;
715 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_LEN4:
716 NDR_CHECK(ndr_push_uint32(ndr, 0));
717 NDR_CHECK(ndr_push_uint32(ndr, c_len+1));
718 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
719 ret = convert_string(CH_UNIX, CH_DOS,
721 ndr->data+ndr->offset, c_len + 1);
723 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
724 "Bad character conversion");
726 ndr->offset += c_len + 1;
729 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2:
730 NDR_CHECK(ndr_push_uint16(ndr, c_len+1));
731 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
732 ret = convert_string(CH_UNIX, CH_DOS,
734 ndr->data+ndr->offset, c_len + 1);
736 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
737 "Bad character conversion");
739 ndr->offset += c_len + 1;
742 case LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM:
743 NDR_PUSH_NEED_BYTES(ndr, c_len + 1);
744 ret = convert_string(CH_UNIX, CH_DOS,
746 ndr->data+ndr->offset, c_len + 1);
748 return ndr_push_error(ndr, NDR_ERR_CHARCNV,
749 "Bad character conversion");
751 ndr->offset += c_len + 1;
755 return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
756 ndr->flags & LIBNDR_STRING_FLAGS);
765 NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, NTTIME t)
767 NDR_CHECK(ndr_push_uint64(ndr, t));
774 NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, NTTIME *t)
776 NDR_CHECK(ndr_pull_uint64(ndr, t));
783 NTSTATUS ndr_push_time_t(struct ndr_push *ndr, time_t t)
785 return ndr_push_uint32(ndr, t);
791 NTSTATUS ndr_pull_time_t(struct ndr_pull *ndr, time_t *t)
794 NDR_CHECK(ndr_pull_uint32(ndr, &tt));
800 void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
802 ndr->print(ndr, "%s: struct %s", name, type);
805 void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
807 ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
810 void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
812 ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
815 void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
817 ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
820 void ndr_print_uint64(struct ndr_print *ndr, const char *name, uint64_t v)
822 ndr->print(ndr, "%-25s: 0x%08x%08x", name, (uint32_t)(v >> 32), (uint32_t)(v & 0xFFFFFFFF));
825 void ndr_print_int64(struct ndr_print *ndr, const char *name, int64_t v)
827 ndr->print(ndr, "%-25s: 0x%08x%08x (%lld)", name,
829 (uint32_t)(v & 0xFFFFFFFF),
833 void ndr_print_HYPER_T(struct ndr_print *ndr, const char *name, HYPER_T v)
835 ndr->print(ndr, "%-25s: 0x%08x%08x", name, (uint32_t)(v >> 32), (uint32_t)(v & 0xFFFFFFFF));
838 void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
841 ndr->print(ndr, "%-25s: *", name);
843 ndr->print(ndr, "%-25s: NULL", name);
847 void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
850 ndr->print(ndr, "%-25s: '%s'", name, s);
852 ndr->print(ndr, "%-25s: NULL", name);
856 void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
858 ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr->mem_ctx, t));
861 void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
863 if (t == (time_t)-1 || t == 0) {
864 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
866 ndr->print(ndr, "%-25s: %s", name, timestring(ndr->mem_ctx, t));
870 void ndr_print_union(struct ndr_print *ndr, const char *name, uint16_t level, const char *type)
872 ndr->print(ndr, "%-25s: union %s(case %u)", name, type, level);
875 void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
877 ndr->print(ndr, "UNKNOWN LEVEL %u", level);
880 void ndr_print_array_HYPER_T(struct ndr_print *ndr, const char *name,
881 const HYPER_T *data, uint32_t count)
885 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
887 for (i=0;i<count;i++) {
889 asprintf(&idx, "[%d]", i);
891 ndr_print_HYPER_T(ndr, idx, data[i]);
898 void ndr_print_array_uint32(struct ndr_print *ndr, const char *name,
899 const uint32_t *data, uint32_t count)
903 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
905 for (i=0;i<count;i++) {
907 asprintf(&idx, "[%d]", i);
909 ndr_print_uint32(ndr, idx, data[i]);
916 void ndr_print_array_uint16(struct ndr_print *ndr, const char *name,
917 const uint16_t *data, uint32_t count)
921 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
923 for (i=0;i<count;i++) {
925 asprintf(&idx, "[%d]", i);
927 ndr_print_uint16(ndr, idx, data[i]);
934 void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
935 const uint8_t *data, uint32_t count)
939 if (count <= 600 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
941 for (i=0;i<count;i++) {
942 snprintf(&s[i*2], 3, "%02x", data[i]);
945 ndr->print(ndr, "%-25s: %s", name, s);
949 ndr->print(ndr, "%s: ARRAY(%d)", name, count);
951 for (i=0;i<count;i++) {
953 asprintf(&idx, "[%d]", i);
955 ndr_print_uint8(ndr, idx, data[i]);
963 build a GUID from a string
965 NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
968 uint32_t time_mid, time_hi_and_version;
969 uint32_t clock_seq[2];
973 if (11 != sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
974 &time_low, &time_mid, &time_hi_and_version,
975 &clock_seq[0], &clock_seq[1],
976 &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
977 return NT_STATUS_INVALID_PARAMETER;
980 guid->time_low = time_low;
981 guid->time_mid = time_mid;
982 guid->time_hi_and_version = time_hi_and_version;
983 guid->clock_seq[0] = clock_seq[0];
984 guid->clock_seq[1] = clock_seq[1];
986 guid->node[i] = node[i];
993 its useful to be able to display these in debugging messages
995 const char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
997 return talloc_asprintf(mem_ctx,
998 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
999 guid->time_low, guid->time_mid,
1000 guid->time_hi_and_version,
1003 guid->node[0], guid->node[1],
1004 guid->node[2], guid->node[3],
1005 guid->node[4], guid->node[5]);
1008 void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
1010 ndr->print(ndr, "%-25s: %s", name, GUID_string(ndr->mem_ctx, guid));
1013 void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
1015 ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, r.length);
1017 dump_data(10, r.data, r.length);
1023 push a DATA_BLOB onto the wire.
1025 NTSTATUS ndr_push_DATA_BLOB(struct ndr_push *ndr, DATA_BLOB blob)
1027 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
1028 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1029 blob.length = NDR_ALIGN(ndr, 2);
1030 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1031 blob.length = NDR_ALIGN(ndr, 4);
1032 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1033 blob.length = NDR_ALIGN(ndr, 8);
1035 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
1036 data_blob_clear(&blob);
1037 } else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
1038 NDR_CHECK(ndr_push_uint32(ndr, blob.length));
1040 NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
1041 return NT_STATUS_OK;
1045 pull a DATA_BLOB from the wire.
1047 NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, DATA_BLOB *blob)
1051 if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
1052 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
1053 length = NDR_ALIGN(ndr, 2);
1054 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
1055 length = NDR_ALIGN(ndr, 4);
1056 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
1057 length = NDR_ALIGN(ndr, 8);
1059 if (ndr->data_size - ndr->offset < length) {
1060 length = ndr->data_size - ndr->offset;
1062 } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
1063 length = ndr->data_size - ndr->offset;
1065 NDR_CHECK(ndr_pull_uint32(ndr, &length));
1067 NDR_PULL_NEED_BYTES(ndr, length);
1068 *blob = data_blob_talloc(ndr->mem_ctx, ndr->data+ndr->offset, length);
1069 ndr->offset += length;
1070 return NT_STATUS_OK;