/*
Unix SMB/CIFS implementation.
routines for marshalling/unmarshalling basic types
Copyright (C) Andrew Tridgell 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "replace.h"
#include "system/network.h"
#include "librpc/ndr/libndr.h"
#include "lib/util/util_net.h"
#include "lib/util/debug.h"
#include "lib/util/util.h"
#include "lib/util/bytearray.h"
#define NDR_PULL_U16(ndr, ofs) \
(NDR_BE(ndr) ? PULL_BE_U16(ndr->data,ofs) : PULL_LE_U16(ndr->data,ofs))
#define NDR_PULL_U32(ndr, ofs) \
(NDR_BE(ndr) ? PULL_BE_U32(ndr->data,ofs) : PULL_LE_U32(ndr->data,ofs))
#define NDR_PULL_I32(ndr, ofs) \
(int32_t)(NDR_BE(ndr) ? PULL_BE_U32(ndr->data,ofs) : PULL_LE_U32(ndr->data,ofs))
#define NDR_PULL_I64(ndr, ofs) \
(NDR_BE(ndr) ? PULL_BE_I64((ndr)->data, ofs) : PULL_LE_I64((ndr)->data, ofs))
#define NDR_PUSH_U16(ndr, ofs, v) \
do { \
if (NDR_BE(ndr)) { \
PUSH_BE_U16(ndr->data, ofs, v); \
} else { \
PUSH_LE_U16(ndr->data, ofs, v); \
} \
} while (0)
#define NDR_PUSH_U32(ndr, ofs, v) \
do { \
if (NDR_BE(ndr)) { \
PUSH_BE_U32(ndr->data, ofs, v); \
} else { \
PUSH_LE_U32(ndr->data, ofs, v); \
} \
} while (0)
#define NDR_PUSH_I32(ndr, ofs, v) \
do { \
if (NDR_BE(ndr)) { \
PUSH_BE_U32(ndr->data, ofs, v); \
} else { \
PUSH_LE_U32(ndr->data, ofs, v); \
} \
} while (0)
#define NDR_PUSH_I64(ndr, ofs, v) \
do { \
if (NDR_BE(ndr)) { \
PUSH_BE_I64((ndr)->data, ofs, v); \
} else { \
PUSH_LE_I64((ndr)->data, ofs, v); \
} \
} while (0)
static void ndr_dump_data(struct ndr_print *ndr, const uint8_t *buf, int len);
/*
check for data leaks from the server by looking for non-zero pad bytes
these could also indicate that real structure elements have been
mistaken for padding in the IDL
*/
_PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n)
{
size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1);
size_t i;
for (i=ndr->offset;i<ofs2;i++) {
if (ndr->data[i] != 0) {
break;
}
}
if (i<ofs2) {
DEBUG(0,("WARNING: Non-zero padding to %zu: ", n));
for (i=ndr->offset;i<ofs2;i++) {
DEBUG(0,("%02x ", ndr->data[i]));
}
DEBUG(0,("\n"));
}
}
/*
parse a int8_t
*/
_PUBLIC_ enum ndr_err_code ndr_pull_int8(struct ndr_pull *ndr, ndr_flags_type ndr_flags, int8_t *v)
{
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
NDR_PULL_NEED_BYTES(ndr, 1);
*v = (int8_t)PULL_BE_U8(ndr->data, ndr->offset);
ndr->offset += 1;
return NDR_ERR_SUCCESS;
}
/*
parse a uint8_t
*/
_PUBLIC_ enum ndr_err_code ndr_pull_uint8(struct ndr_pull *ndr, ndr_flags_type ndr_flags, uint8_t *v)
{
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
NDR_PULL_NEED_BYTES(ndr, 1);
*v = PULL_BE_U8(ndr->data, ndr->offset);
ndr->offset += 1;
return NDR_ERR_SUCCESS;
}
/*
parse a int16_t
*/
_PUBLIC_ enum ndr_err_code ndr_pull_int16(struct ndr_pull *ndr, ndr_flags_type ndr_flags, int16_t *v)
{
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
NDR_PULL_ALIGN(ndr, 2);
NDR_PULL_NEED_BYTES(ndr, 2);
*v = (uint16_t)NDR_PULL_U16(ndr, ndr->offset);
ndr->offset += 2;
return NDR_ERR_SUCCESS;
}
/*
parse a uint16_t
*/
_PUBLIC_ enum ndr_err_code ndr_pull_uint16(struct ndr_pull *ndr, ndr_flags_type ndr_flags, uint16_t *v)
{
NDR_PULL_CHECK_F
|