root/librpc/ndr/ndr_basic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ndr_check_padding
  2. ndr_pull_int8
  3. ndr_pull_uint8
  4. ndr_pull_int16
  5. ndr_pull_uint16
  6. ndr_pull_int32
  7. ndr_pull_uint32
  8. ndr_pull_generic_ptr
  9. ndr_pull_ref_ptr
  10. ndr_pull_udlong
  11. ndr_pull_udlongr
  12. ndr_pull_dlong
  13. ndr_pull_hyper
  14. ndr_pull_pointer
  15. ndr_pull_NTSTATUS
  16. ndr_push_NTSTATUS
  17. ndr_print_NTSTATUS
  18. ndr_pull_WERROR
  19. ndr_push_WERROR
  20. ndr_print_WERROR
  21. ndr_pull_bytes
  22. ndr_pull_array_uint8
  23. ndr_push_int8
  24. ndr_push_uint8
  25. ndr_push_int16
  26. ndr_push_uint16
  27. ndr_push_int32
  28. ndr_push_uint32
  29. ndr_push_udlong
  30. ndr_push_udlongr
  31. ndr_push_dlong
  32. ndr_push_hyper
  33. ndr_push_pointer
  34. ndr_push_align
  35. ndr_pull_align
  36. ndr_push_bytes
  37. ndr_push_zero
  38. ndr_push_array_uint8
  39. ndr_push_unique_ptr
  40. ndr_push_full_ptr
  41. ndr_push_ref_ptr
  42. ndr_push_NTTIME
  43. ndr_pull_NTTIME
  44. ndr_push_NTTIME_1sec
  45. ndr_pull_NTTIME_1sec
  46. ndr_pull_NTTIME_hyper
  47. ndr_push_NTTIME_hyper
  48. ndr_push_time_t
  49. ndr_pull_time_t
  50. ndr_pull_ipv4address
  51. ndr_push_ipv4address
  52. ndr_print_ipv4address
  53. ndr_print_struct
  54. ndr_print_enum
  55. ndr_print_bitmap_flag
  56. ndr_print_int8
  57. ndr_print_uint8
  58. ndr_print_int16
  59. ndr_print_uint16
  60. ndr_print_int32
  61. ndr_print_uint32
  62. ndr_print_udlong
  63. ndr_print_udlongr
  64. ndr_print_dlong
  65. ndr_print_hyper
  66. ndr_print_pointer
  67. ndr_print_ptr
  68. ndr_print_NTTIME
  69. ndr_print_NTTIME_1sec
  70. ndr_print_NTTIME_hyper
  71. ndr_print_time_t
  72. ndr_print_union
  73. ndr_print_bad_level
  74. ndr_print_array_uint8
  75. ndr_print_DATA_BLOB
  76. ndr_push_DATA_BLOB
  77. ndr_pull_DATA_BLOB
  78. ndr_size_DATA_BLOB

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    routines for marshalling/unmarshalling basic types
   5 
   6    Copyright (C) Andrew Tridgell 2003
   7    
   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 3 of the License, or
  11    (at your option) any later version.
  12    
  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.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "system/network.h"
  24 #include "librpc/ndr/libndr.h"
  25 
  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_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(ndr->data,ofs))
  29 #define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
  30 #define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
  31 #define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr))  { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)
  32 
  33 
  34 /*
  35   check for data leaks from the server by looking for non-zero pad bytes
  36   these could also indicate that real structure elements have been
  37   mistaken for padding in the IDL
  38 */
  39 _PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n)
     /* [<][>][^][v][top][bottom][index][help] */
  40 {
  41         size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1);
  42         int i;
  43         for (i=ndr->offset;i<ofs2;i++) {
  44                 if (ndr->data[i] != 0) {
  45                         break;
  46                 }
  47         }
  48         if (i<ofs2) {
  49                 DEBUG(0,("WARNING: Non-zero padding to %d: ", (int)n));
  50                 for (i=ndr->offset;i<ofs2;i++) {
  51                         DEBUG(0,("%02x ", ndr->data[i]));
  52                 }
  53                 DEBUG(0,("\n"));
  54         }
  55 
  56 }
  57 
  58 /*
  59   parse a int8_t
  60 */
  61 _PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
  62 {
  63         NDR_PULL_NEED_BYTES(ndr, 1);
  64         *v = (int8_t)CVAL(ndr->data, ndr->offset);
  65         ndr->offset += 1;
  66         return NDR_ERR_SUCCESS;
  67 }
  68 
  69 /*
  70   parse a uint8_t
  71 */
  72 _PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
  73 {
  74         NDR_PULL_NEED_BYTES(ndr, 1);
  75         *v = CVAL(ndr->data, ndr->offset);
  76         ndr->offset += 1;
  77         return NDR_ERR_SUCCESS;
  78 }
  79 
  80 /*
  81   parse a int16_t
  82 */
  83 _PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
  84 {
  85         NDR_PULL_ALIGN(ndr, 2);
  86         NDR_PULL_NEED_BYTES(ndr, 2);
  87         *v = (uint16_t)NDR_SVAL(ndr, ndr->offset);
  88         ndr->offset += 2;
  89         return NDR_ERR_SUCCESS;
  90 }
  91 
  92 /*
  93   parse a uint16_t
  94 */
  95 _PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97         NDR_PULL_ALIGN(ndr, 2);
  98         NDR_PULL_NEED_BYTES(ndr, 2);
  99         *v = NDR_SVAL(ndr, ndr->offset);
 100         ndr->offset += 2;
 101         return NDR_ERR_SUCCESS;
 102 }
 103 
 104 /*
 105   parse a int32_t
 106 */
 107 _PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 108 {
 109         NDR_PULL_ALIGN(ndr, 4);
 110         NDR_PULL_NEED_BYTES(ndr, 4);
 111         *v = NDR_IVALS(ndr, ndr->offset);
 112         ndr->offset += 4;
 113         return NDR_ERR_SUCCESS;
 114 }
 115 
 116 /*
 117   parse a uint32_t
 118 */
 119 _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 120 {
 121         NDR_PULL_ALIGN(ndr, 4);
 122         NDR_PULL_NEED_BYTES(ndr, 4);
 123         *v = NDR_IVAL(ndr, ndr->offset);
 124         ndr->offset += 4;
 125         return NDR_ERR_SUCCESS;
 126 }
 127 
 128 /*
 129   parse a pointer referent identifier
 130 */
 131 _PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 132 {
 133         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v));
 134         if (*v != 0) {
 135                 ndr->ptr_count++;
 136         }
 137         return NDR_ERR_SUCCESS;
 138 }
 139 
 140 /*
 141   parse a ref pointer referent identifier
 142 */
 143 _PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 144 {
 145         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v));
 146         /* ref pointers always point to data */
 147         *v = 1;
 148         return NDR_ERR_SUCCESS;
 149 }
 150 
 151 /*
 152   parse a udlong
 153 */
 154 _PUBLIC_ enum ndr_err_code ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 155 {
 156         NDR_PULL_ALIGN(ndr, 4);
 157         NDR_PULL_NEED_BYTES(ndr, 8);
 158         *v = NDR_IVAL(ndr, ndr->offset);
 159         *v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32;
 160         ndr->offset += 8;
 161         return NDR_ERR_SUCCESS;
 162 }
 163 
 164 /*
 165   parse a udlongr
 166 */
 167 _PUBLIC_ enum ndr_err_code ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 168 {
 169         NDR_PULL_ALIGN(ndr, 4);
 170         NDR_PULL_NEED_BYTES(ndr, 8);
 171         *v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32;
 172         *v |= NDR_IVAL(ndr, ndr->offset+4);
 173         ndr->offset += 8;
 174         return NDR_ERR_SUCCESS;
 175 }
 176 
 177 /*
 178   parse a dlong
 179 */
 180 _PUBLIC_ enum ndr_err_code ndr_pull_dlong(struct ndr_pull *ndr, int ndr_flags, int64_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 181 {
 182         return ndr_pull_udlong(ndr, ndr_flags, (uint64_t *)v);
 183 }
 184 
 185 /*
 186   parse a hyper
 187 */
 188 _PUBLIC_ enum ndr_err_code ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
     /* [<][>][^][v][top][bottom][index][help] */
 189 {
 190         NDR_PULL_ALIGN(ndr, 8);
 191         return ndr_pull_udlong(ndr, ndr_flags, v);
 192 }
 193 
 194 /*
 195   parse a pointer
 196 */
 197 _PUBLIC_ enum ndr_err_code ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v)
     /* [<][>][^][v][top][bottom][index][help] */
 198 {
 199         uintptr_t h;
 200         NDR_PULL_ALIGN(ndr, sizeof(h));
 201         NDR_PULL_NEED_BYTES(ndr, sizeof(h));
 202         memcpy(&h, ndr->data+ndr->offset, sizeof(h));
 203         ndr->offset += sizeof(h);
 204         *v = (void *)h;
 205         return NDR_ERR_SUCCESS;
 206 }
 207 
 208 /*
 209   pull a NTSTATUS
 210 */
 211 _PUBLIC_ enum ndr_err_code ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status)
     /* [<][>][^][v][top][bottom][index][help] */
 212 {
 213         uint32_t v;
 214         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
 215         *status = NT_STATUS(v);
 216         return NDR_ERR_SUCCESS;
 217 }
 218 
 219 /*
 220   push a NTSTATUS
 221 */
 222 _PUBLIC_ enum ndr_err_code ndr_push_NTSTATUS(struct ndr_push *ndr, int ndr_flags, NTSTATUS status)
     /* [<][>][^][v][top][bottom][index][help] */
 223 {
 224         return ndr_push_uint32(ndr, ndr_flags, NT_STATUS_V(status));
 225 }
 226 
 227 _PUBLIC_ void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS r)
     /* [<][>][^][v][top][bottom][index][help] */
 228 {
 229         ndr->print(ndr, "%-25s: %s", name, nt_errstr(r));
 230 }
 231 
 232 /*
 233   pull a WERROR
 234 */
 235 _PUBLIC_ enum ndr_err_code ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status)
     /* [<][>][^][v][top][bottom][index][help] */
 236 {
 237         uint32_t v;
 238         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
 239         *status = W_ERROR(v);
 240         return NDR_ERR_SUCCESS;
 241 }
 242 
 243 /*
 244   push a WERROR
 245 */
 246 _PUBLIC_ enum ndr_err_code ndr_push_WERROR(struct ndr_push *ndr, int ndr_flags, WERROR status)
     /* [<][>][^][v][top][bottom][index][help] */
 247 {
 248         return ndr_push_uint32(ndr, NDR_SCALARS, W_ERROR_V(status));
 249 }
 250 
 251 _PUBLIC_ void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR r)
     /* [<][>][^][v][top][bottom][index][help] */
 252 {
 253         ndr->print(ndr, "%-25s: %s", name, win_errstr(r));
 254 }
 255 
 256 /*
 257   parse a set of bytes
 258 */
 259 _PUBLIC_ enum ndr_err_code ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n)
     /* [<][>][^][v][top][bottom][index][help] */
 260 {
 261         NDR_PULL_NEED_BYTES(ndr, n);
 262         memcpy(data, ndr->data + ndr->offset, n);
 263         ndr->offset += n;
 264         return NDR_ERR_SUCCESS;
 265 }
 266 
 267 /*
 268   pull an array of uint8
 269 */
 270 _PUBLIC_ enum ndr_err_code ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n)
     /* [<][>][^][v][top][bottom][index][help] */
 271 {
 272         if (!(ndr_flags & NDR_SCALARS)) {
 273                 return NDR_ERR_SUCCESS;
 274         }
 275         return ndr_pull_bytes(ndr, data, n);
 276 }
 277 
 278 /*
 279   push a int8_t
 280 */
 281 _PUBLIC_ enum ndr_err_code ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 282 {
 283         NDR_PUSH_NEED_BYTES(ndr, 1);
 284         SCVAL(ndr->data, ndr->offset, (uint8_t)v);
 285         ndr->offset += 1;
 286         return NDR_ERR_SUCCESS;
 287 }
 288 
 289 /*
 290   push a uint8_t
 291 */
 292 _PUBLIC_ enum ndr_err_code ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 293 {
 294         NDR_PUSH_NEED_BYTES(ndr, 1);
 295         SCVAL(ndr->data, ndr->offset, v);
 296         ndr->offset += 1;
 297         return NDR_ERR_SUCCESS;
 298 }
 299 
 300 /*
 301   push a int16_t
 302 */
 303 _PUBLIC_ enum ndr_err_code ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 304 {
 305         NDR_PUSH_ALIGN(ndr, 2);
 306         NDR_PUSH_NEED_BYTES(ndr, 2);
 307         NDR_SSVAL(ndr, ndr->offset, (uint16_t)v);
 308         ndr->offset += 2;
 309         return NDR_ERR_SUCCESS;
 310 }
 311 
 312 /*
 313   push a uint16_t
 314 */
 315 _PUBLIC_ enum ndr_err_code ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 316 {
 317         NDR_PUSH_ALIGN(ndr, 2);
 318         NDR_PUSH_NEED_BYTES(ndr, 2);
 319         NDR_SSVAL(ndr, ndr->offset, v);
 320         ndr->offset += 2;
 321         return NDR_ERR_SUCCESS;
 322 }
 323 
 324 /*
 325   push a int32_t
 326 */
 327 _PUBLIC_ enum ndr_err_code ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 328 {
 329         NDR_PUSH_ALIGN(ndr, 4);
 330         NDR_PUSH_NEED_BYTES(ndr, 4);
 331         NDR_SIVALS(ndr, ndr->offset, v);
 332         ndr->offset += 4;
 333         return NDR_ERR_SUCCESS;
 334 }
 335 
 336 /*
 337   push a uint32_t
 338 */
 339 _PUBLIC_ enum ndr_err_code ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 340 {
 341         NDR_PUSH_ALIGN(ndr, 4);
 342         NDR_PUSH_NEED_BYTES(ndr, 4);
 343         NDR_SIVAL(ndr, ndr->offset, v);
 344         ndr->offset += 4;
 345         return NDR_ERR_SUCCESS;
 346 }
 347 
 348 /*
 349   push a udlong
 350 */
 351 _PUBLIC_ enum ndr_err_code ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 352 {
 353         NDR_PUSH_ALIGN(ndr, 4);
 354         NDR_PUSH_NEED_BYTES(ndr, 8);
 355         NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
 356         NDR_SIVAL(ndr, ndr->offset+4, (v>>32));
 357         ndr->offset += 8;
 358         return NDR_ERR_SUCCESS;
 359 }
 360 
 361 /*
 362   push a udlongr
 363 */
 364 _PUBLIC_ enum ndr_err_code ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 365 {
 366         NDR_PUSH_ALIGN(ndr, 4);
 367         NDR_PUSH_NEED_BYTES(ndr, 8);
 368         NDR_SIVAL(ndr, ndr->offset, (v>>32));
 369         NDR_SIVAL(ndr, ndr->offset+4, (v & 0xFFFFFFFF));
 370         ndr->offset += 8;
 371         return NDR_ERR_SUCCESS;
 372 }
 373 
 374 /*
 375   push a dlong
 376 */
 377 _PUBLIC_ enum ndr_err_code ndr_push_dlong(struct ndr_push *ndr, int ndr_flags, int64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 378 {
 379         return ndr_push_udlong(ndr, NDR_SCALARS, (uint64_t)v);
 380 }
 381 
 382 /*
 383   push a hyper
 384 */
 385 _PUBLIC_ enum ndr_err_code ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 386 {
 387         NDR_PUSH_ALIGN(ndr, 8);
 388         return ndr_push_udlong(ndr, NDR_SCALARS, v);
 389 }
 390 
 391 /*
 392   push a pointer
 393 */
 394 _PUBLIC_ enum ndr_err_code ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v)
     /* [<][>][^][v][top][bottom][index][help] */
 395 {
 396         uintptr_t h = (intptr_t)v;
 397         NDR_PUSH_ALIGN(ndr, sizeof(h));
 398         NDR_PUSH_NEED_BYTES(ndr, sizeof(h));
 399         memcpy(ndr->data+ndr->offset, &h, sizeof(h));
 400         ndr->offset += sizeof(h);
 401         return NDR_ERR_SUCCESS;
 402 }
 403 
 404 _PUBLIC_ enum ndr_err_code ndr_push_align(struct ndr_push *ndr, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 405 {
 406         NDR_PUSH_ALIGN(ndr, size);
 407         return NDR_ERR_SUCCESS;
 408 }
 409 
 410 _PUBLIC_ enum ndr_err_code ndr_pull_align(struct ndr_pull *ndr, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 411 {
 412         NDR_PULL_ALIGN(ndr, size);
 413         return NDR_ERR_SUCCESS;
 414 }
 415 
 416 /*
 417   push some bytes
 418 */
 419 _PUBLIC_ enum ndr_err_code ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n)
     /* [<][>][^][v][top][bottom][index][help] */
 420 {
 421         NDR_PUSH_NEED_BYTES(ndr, n);
 422         memcpy(ndr->data + ndr->offset, data, n);
 423         ndr->offset += n;
 424         return NDR_ERR_SUCCESS;
 425 }
 426 
 427 /*
 428   push some zero bytes
 429 */
 430 _PUBLIC_ enum ndr_err_code ndr_push_zero(struct ndr_push *ndr, uint32_t n)
     /* [<][>][^][v][top][bottom][index][help] */
 431 {
 432         NDR_PUSH_NEED_BYTES(ndr, n);
 433         memset(ndr->data + ndr->offset, 0, n);
 434         ndr->offset += n;
 435         return NDR_ERR_SUCCESS;
 436 }
 437 
 438 /*
 439   push an array of uint8
 440 */
 441 _PUBLIC_ enum ndr_err_code ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
     /* [<][>][^][v][top][bottom][index][help] */
 442 {
 443         if (!(ndr_flags & NDR_SCALARS)) {
 444                 return NDR_ERR_SUCCESS;
 445         }
 446         return ndr_push_bytes(ndr, data, n);
 447 }
 448 
 449 /*
 450   push a unique non-zero value if a pointer is non-NULL, otherwise 0
 451 */
 452 _PUBLIC_ enum ndr_err_code ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
     /* [<][>][^][v][top][bottom][index][help] */
 453 {
 454         uint32_t ptr = 0;
 455         if (p) {
 456                 ptr = ndr->ptr_count * 4;
 457                 ptr |= 0x00020000;
 458                 ndr->ptr_count++;
 459         }
 460         return ndr_push_uint32(ndr, NDR_SCALARS, ptr);
 461 }
 462 
 463 /*
 464   push a 'simple' full non-zero value if a pointer is non-NULL, otherwise 0
 465 */
 466 _PUBLIC_ enum ndr_err_code ndr_push_full_ptr(struct ndr_push *ndr, const void *p)
     /* [<][>][^][v][top][bottom][index][help] */
 467 {
 468         uint32_t ptr = 0;
 469         if (p) {
 470                 /* Check if the pointer already exists and has an id */
 471                 ptr = ndr_token_peek(&ndr->full_ptr_list, p);
 472                 if (ptr == 0) {
 473                         ndr->ptr_count++;
 474                         ptr = ndr->ptr_count;
 475                         ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
 476                 }
 477         }
 478         return ndr_push_uint32(ndr, NDR_SCALARS, ptr);
 479 }
 480 
 481 /*
 482   push always a 0, if a pointer is NULL it's a fatal error
 483 */
 484 _PUBLIC_ enum ndr_err_code ndr_push_ref_ptr(struct ndr_push *ndr)
     /* [<][>][^][v][top][bottom][index][help] */
 485 {
 486         return ndr_push_uint32(ndr, NDR_SCALARS, 0xAEF1AEF1);
 487 }
 488 
 489 
 490 /*
 491   push a NTTIME
 492 */
 493 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
     /* [<][>][^][v][top][bottom][index][help] */
 494 {
 495         NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
 496         return NDR_ERR_SUCCESS;
 497 }
 498 
 499 /*
 500   pull a NTTIME
 501 */
 502 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
     /* [<][>][^][v][top][bottom][index][help] */
 503 {
 504         NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
 505         return NDR_ERR_SUCCESS;
 506 }
 507 
 508 /*
 509   push a NTTIME
 510 */
 511 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
     /* [<][>][^][v][top][bottom][index][help] */
 512 {
 513         t /= 10000000;
 514         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
 515         return NDR_ERR_SUCCESS;
 516 }
 517 
 518 /*
 519   pull a NTTIME_1sec
 520 */
 521 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
     /* [<][>][^][v][top][bottom][index][help] */
 522 {
 523         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
 524         (*t) *= 10000000;
 525         return NDR_ERR_SUCCESS;
 526 }
 527 
 528 /*
 529   pull a NTTIME_hyper
 530 */
 531 _PUBLIC_ enum ndr_err_code ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
     /* [<][>][^][v][top][bottom][index][help] */
 532 {
 533         NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
 534         return NDR_ERR_SUCCESS;
 535 }
 536 
 537 /*
 538   push a NTTIME_hyper
 539 */
 540 _PUBLIC_ enum ndr_err_code ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
     /* [<][>][^][v][top][bottom][index][help] */
 541 {
 542         NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
 543         return NDR_ERR_SUCCESS;
 544 }
 545 
 546 /*
 547   push a time_t
 548 */
 549 _PUBLIC_ enum ndr_err_code ndr_push_time_t(struct ndr_push *ndr, int ndr_flags, time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
 550 {
 551         return ndr_push_uint32(ndr, ndr_flags, t);
 552 }
 553 
 554 /*
 555   pull a time_t
 556 */
 557 _PUBLIC_ enum ndr_err_code ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags, time_t *t)
     /* [<][>][^][v][top][bottom][index][help] */
 558 {
 559         uint32_t tt;
 560         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &tt));
 561         *t = tt;
 562         return NDR_ERR_SUCCESS;
 563 }
 564 
 565 
 566 /*
 567   pull a ipv4address
 568 */
 569 _PUBLIC_ enum ndr_err_code ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **address)
     /* [<][>][^][v][top][bottom][index][help] */
 570 {
 571         struct in_addr in;
 572         NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &in.s_addr));
 573         in.s_addr = htonl(in.s_addr);
 574         *address = talloc_strdup(ndr->current_mem_ctx, inet_ntoa(in));
 575         NDR_ERR_HAVE_NO_MEMORY(*address);
 576         return NDR_ERR_SUCCESS;
 577 }
 578 
 579 /*
 580   push a ipv4address
 581 */
 582 _PUBLIC_ enum ndr_err_code ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
     /* [<][>][^][v][top][bottom][index][help] */
 583 {
 584         uint32_t addr;
 585         if (!is_ipaddress(address)) {
 586                 return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
 587                                       "Invalid IPv4 address: '%s'", 
 588                                       address);
 589         }
 590         addr = inet_addr(address);
 591         NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr)));
 592         return NDR_ERR_SUCCESS;
 593 }
 594 
 595 /*
 596   print a ipv4address
 597 */
 598 _PUBLIC_ void ndr_print_ipv4address(struct ndr_print *ndr, const char *name, 
     /* [<][>][^][v][top][bottom][index][help] */
 599                            const char *address)
 600 {
 601         ndr->print(ndr, "%-25s: %s", name, address);
 602 }
 603 
 604 
 605 _PUBLIC_ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
     /* [<][>][^][v][top][bottom][index][help] */
 606 {
 607         ndr->print(ndr, "%s: struct %s", name, type);
 608 }
 609 
 610 _PUBLIC_ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type, 
     /* [<][>][^][v][top][bottom][index][help] */
 611                     const char *val, uint32_t value)
 612 {
 613         if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
 614                 ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
 615         } else {
 616                 ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
 617         }
 618 }
 619 
 620 _PUBLIC_ void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value)
     /* [<][>][^][v][top][bottom][index][help] */
 621 {
 622         /* this is an attempt to support multi-bit bitmap masks */
 623         value &= flag;
 624 
 625         while (!(flag & 1)) {
 626                 flag >>= 1;
 627                 value >>= 1;
 628         }       
 629         if (flag == 1) {
 630                 ndr->print(ndr, "   %d: %-25s", value, flag_name);
 631         } else {
 632                 ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value);
 633         }
 634 }
 635 
 636 _PUBLIC_ void ndr_print_int8(struct ndr_print *ndr, const char *name, int8_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 637 {
 638         ndr->print(ndr, "%-25s: %d", name, v);
 639 }
 640 
 641 _PUBLIC_ void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 642 {
 643         ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
 644 }
 645 
 646 _PUBLIC_ void ndr_print_int16(struct ndr_print *ndr, const char *name, int16_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 647 {
 648         ndr->print(ndr, "%-25s: %d", name, v);
 649 }
 650 
 651 _PUBLIC_ void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 652 {
 653         ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
 654 }
 655 
 656 _PUBLIC_ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 657 {
 658         ndr->print(ndr, "%-25s: %d", name, v);
 659 }
 660 
 661 _PUBLIC_ void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 662 {
 663         ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
 664 }
 665 
 666 _PUBLIC_ void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 667 {
 668         ndr->print(ndr, "%-25s: 0x%016llx (%llu)", name, (unsigned long long)v, (unsigned long long)v);
 669 }
 670 
 671 _PUBLIC_ void ndr_print_udlongr(struct ndr_print *ndr, const char *name, uint64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 672 {
 673         ndr_print_udlong(ndr, name, v);
 674 }
 675 
 676 _PUBLIC_ void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 677 {
 678         ndr->print(ndr, "%-25s: 0x%016llx (%lld)", name, (unsigned long long)v, (long long)v);
 679 }
 680 
 681 _PUBLIC_ void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v)
     /* [<][>][^][v][top][bottom][index][help] */
 682 {
 683         ndr_print_dlong(ndr, name, v);
 684 }
 685 
 686 _PUBLIC_ void ndr_print_pointer(struct ndr_print *ndr, const char *name, void *v)
     /* [<][>][^][v][top][bottom][index][help] */
 687 {
 688         ndr->print(ndr, "%-25s: %p", name, v);
 689 }
 690 
 691 _PUBLIC_ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
     /* [<][>][^][v][top][bottom][index][help] */
 692 {
 693         if (p) {
 694                 ndr->print(ndr, "%-25s: *", name);
 695         } else {
 696                 ndr->print(ndr, "%-25s: NULL", name);
 697         }
 698 }
 699 
 700 _PUBLIC_ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
     /* [<][>][^][v][top][bottom][index][help] */
 701 {
 702         ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t));
 703 }
 704 
 705 _PUBLIC_ void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
     /* [<][>][^][v][top][bottom][index][help] */
 706 {
 707         /* this is a standard NTTIME here
 708          * as it's already converted in the pull/push code
 709          */
 710         ndr_print_NTTIME(ndr, name, t);
 711 }
 712 
 713 _PUBLIC_ void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t)
     /* [<][>][^][v][top][bottom][index][help] */
 714 {
 715         ndr_print_NTTIME(ndr, name, t);
 716 }
 717 
 718 _PUBLIC_ void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
 719 {
 720         if (t == (time_t)-1 || t == 0) {
 721                 ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
 722         } else {
 723                 ndr->print(ndr, "%-25s: %s", name, timestring(ndr, t));
 724         }
 725 }
 726 
 727 _PUBLIC_ void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type)
     /* [<][>][^][v][top][bottom][index][help] */
 728 {
 729         if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
 730                 ndr->print(ndr, "%-25s: union %s(case 0x%X)", name, type, level);
 731         } else {
 732                 ndr->print(ndr, "%-25s: union %s(case %d)", name, type, level);
 733         }
 734 }
 735 
 736 _PUBLIC_ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
     /* [<][>][^][v][top][bottom][index][help] */
 737 {
 738         ndr->print(ndr, "UNKNOWN LEVEL %u", level);
 739 }
 740 
 741 _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, 
     /* [<][>][^][v][top][bottom][index][help] */
 742                            const uint8_t *data, uint32_t count)
 743 {
 744         int i;
 745 
 746         if (count <= 600 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
 747                 char s[1202];
 748                 for (i=0;i<count;i++) {
 749                         snprintf(&s[i*2], 3, "%02x", data[i]);
 750                 }
 751                 s[i*2] = 0;
 752                 ndr->print(ndr, "%-25s: %s", name, s);
 753                 return;
 754         }
 755 
 756         ndr->print(ndr, "%s: ARRAY(%d)", name, count);
 757         ndr->depth++;
 758         for (i=0;i<count;i++) {
 759                 char *idx=NULL;
 760                 if (asprintf(&idx, "[%d]", i) != -1) {
 761                         ndr_print_uint8(ndr, idx, data[i]);
 762                         free(idx);
 763                 }
 764         }
 765         ndr->depth--;   
 766 }
 767 
 768 _PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
     /* [<][>][^][v][top][bottom][index][help] */
 769 {
 770         ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, (unsigned)r.length);
 771         if (r.length) {
 772                 dump_data(10, r.data, r.length);
 773         }
 774 }
 775 
 776 
 777 /*
 778   push a DATA_BLOB onto the wire. 
 779 */
 780 _PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, DATA_BLOB blob)
     /* [<][>][^][v][top][bottom][index][help] */
 781 {
 782         if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
 783                 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
 784                         blob.length = NDR_ALIGN(ndr, 2);
 785                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
 786                         blob.length = NDR_ALIGN(ndr, 4);
 787                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
 788                         blob.length = NDR_ALIGN(ndr, 8);
 789                 }
 790                 NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
 791                 data_blob_clear(&blob);
 792         } else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
 793                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, blob.length));
 794         }
 795         NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
 796         return NDR_ERR_SUCCESS;
 797 }
 798 
 799 /*
 800   pull a DATA_BLOB from the wire. 
 801 */
 802 _PUBLIC_ enum ndr_err_code ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
     /* [<][>][^][v][top][bottom][index][help] */
 803 {
 804         uint32_t length = 0;
 805 
 806         if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
 807                 if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
 808                         length = NDR_ALIGN(ndr, 2);
 809                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
 810                         length = NDR_ALIGN(ndr, 4);
 811                 } else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
 812                         length = NDR_ALIGN(ndr, 8);
 813                 }
 814                 if (ndr->data_size - ndr->offset < length) {
 815                         length = ndr->data_size - ndr->offset;
 816                 }
 817         } else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
 818                 length = ndr->data_size - ndr->offset;
 819         } else {
 820                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length));
 821         }
 822         NDR_PULL_NEED_BYTES(ndr, length);
 823         *blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
 824         ndr->offset += length;
 825         return NDR_ERR_SUCCESS;
 826 }
 827 
 828 _PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
     /* [<][>][^][v][top][bottom][index][help] */
 829 {
 830         if (!data) return ret;
 831         return ret + data->length;
 832 }

/* [<][>][^][v][top][bottom][index][help] */