26 RCSID(
"$Id: 72236c487e6ee6b37baa4ed4ae406b247199f516 $")
28 #include <freeradius-devel/io/test_point.h>
29 #include <freeradius-devel/protocol/vmps/vmps.h>
30 #include <freeradius-devel/util/dbuff.h>
31 #include <freeradius-devel/util/proto.h>
32 #include <freeradius-devel/util/udp.h>
76 [FR_PACKET_TYPE_VALUE_JOIN_REQUEST] =
"Join-Request",
77 [FR_PACKET_TYPE_VALUE_JOIN_RESPONSE] =
"Join-Response",
78 [FR_PACKET_TYPE_VALUE_RECONFIRM_REQUEST] =
"Reconfirm-Request",
79 [FR_PACKET_TYPE_VALUE_RECONFIRM_RESPONSE] =
"Reconfirm-Response",
97 while (data_len > 0) {
107 if ((ptr[0] != 0) || (ptr[1] != 0) ||
108 (ptr[2] != 0x0c) || (ptr[3] < 1) || (ptr[3] > 8)) {
122 if (attrlen > data_len) {
124 "plus header length to exceed packet length %lx",
136 if ((ptr[3] != 5) && (attrlen > 250)) {
137 fr_strerror_printf(
"Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);
142 data_len -= (6 + attrlen);
148 *packet_len = ptr - packet;
170 if (code) *code =
data[1];
171 vp->vp_tainted =
true;
177 vp->vp_tainted =
true;
184 vp->vp_tainted =
true;
188 end =
data + data_len;
196 if ((end - ptr) < 6) {
209 if (attr_len > (
size_t) (end - ptr)) {
235 vp->vp_tainted =
true;
258 static int contents[5][VQP_MAX_ATTRIBUTES] = {
259 { 0, 0, 0, 0, 0, 0 },
260 { 0x0c01, 0x0c02, 0x0c03, 0x0c04, 0x0c07, 0x0c05 },
261 { 0x0c03, 0x0c08, 0, 0, 0, 0 },
262 { 0x0c01, 0x0c02, 0x0c03, 0x0c04, 0x0c07, 0x0c08 },
263 { 0x0c03, 0x0c08, 0, 0, 0, 0 }
287 FR_ERROR_CODE_VALUE_NO_ERROR,
340 if (slen < 0)
return slen;
386 if (
data[3] > 30)
return -3;
392 attributes =
data[3];
394 end =
data + data_len;
396 while (attributes > 0) {
403 if ((end - ptr) < 6) {
404 return 6 * attributes;
420 if ((ptr -
data) > 4096) {
421 return -(ptr -
data);
435 if (ptr > end)
return (6 * attributes) + ptr -
data;
447 static char const tabs[] =
"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
449 for (i = 0; i < attrlen; i++) {
450 if ((i > 0) && ((i & 0x0f) == 0x00))
453 if ((i & 0x0f) == 0x0f) fprintf(
fr_log_fp,
"\n");
455 if ((i & 0x0f) != 0) fprintf(
fr_log_fp,
"\n");
468 if (packet_len < 8)
return;
470 fprintf(fp,
" Version:\t\t%u\n", packet[0]);
475 fprintf(fp,
" OpCode:\t\t%u\n", packet[1]);
481 fprintf(fp,
" OpCode:\t\t%u\n", packet[2]);
484 fprintf(fp,
" Data Count:\t\t%u\n", packet[3]);
486 memcpy(&
id, packet + 4, 4);
489 fprintf(fp,
" ID:\t%08x\n",
id);
491 if (packet_len == 8)
return;
493 for (attr = packet + 8, end = packet + packet_len;
496 memcpy(&
id, attr, 4);
500 if (length > (end - attr))
break;
502 fprintf(fp,
"\t\t%08x %04x ",
id, length);
512 uint8_t const *
data,
size_t data_len,
void *proto_ctx)
531 if (!test_ctx)
return -1;
572 if (!test_ctx)
return -1;
struct fr_dbuff_marker_s fr_dbuff_marker_t
A position marker associated with a dbuff.
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
#define FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, _in, _inlen)
Copy exactly _inlen bytes into dbuff or marker returning if there's insufficient space.
#define FR_DBUFF_IN_RETURN(_dbuff_or_marker, _in)
Copy data from a fixed sized C type into a dbuff returning if there is insufficient space.
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
static uint8_t * fr_dbuff_marker(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
Initialises a new marker pointing to the 'current' position of the dbuff.
#define FR_DBUFF_IN_BYTES_RETURN(_dbuff_or_marker,...)
Copy a byte sequence into a dbuff or marker returning if there's insufficient space.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
static fr_dict_attr_t const * attr_packet_type
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
static uint8_t depth(fr_minmax_heap_index_t i)
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
static uint32_t fr_nbo_to_uint32(uint8_t const data[static sizeof(uint32_t)])
Read an unsigned 32bit integer from wire format (big endian)
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
fr_pair_t * fr_pair_afrom_child_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
Create a new valuepair.
void * fr_proto_next_encodable(fr_dlist_head_t *list, void *current, void *uctx)
Implements the default iterator to encode pairs belonging to a specific dictionary that are not inter...
static fr_dict_t const * dict_vmps
HIDDEN fr_dict_attr_t const * attr_error_code
HIDDEN fr_dict_attr_t const * attr_sequence_number
int fr_vmps_global_init(void)
void fr_vmps_global_free(void)
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Entry point for protocol decoders.
Entry point for protocol encoders.
#define fr_pair_dcursor_iter_init(_cursor, _list, _iter, _uctx)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
#define fr_type_is_leaf(_x)
ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
return fr_dbuff_set(dbuff, &our_dbuff)
ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value)
Encode a single value box, serializing its contents in generic network format.
static size_t char ** out
static ssize_t fr_vmps_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
static void print_hex_data(uint8_t const *ptr, int attrlen, int depth)
int fr_vmps_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, unsigned int *code)
static int decode_test_ctx(void **out, TALLOC_CTX *ctx)
ssize_t fr_vmps_encode(fr_dbuff_t *dbuff, uint8_t const *original, int code, uint32_t seq_no, fr_dcursor_t *cursor)
static int _encode_test_ctx(UNUSED fr_vmps_ctx_t *proto_ctx)
char const * fr_vmps_packet_names[FR_VMPS_CODE_MAX]
static int _decode_test_ctx(UNUSED fr_vmps_ctx_t *proto_ctx)
static int encode_test_ctx(void **out, TALLOC_CTX *ctx)
static ssize_t fr_vmps_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, UNUSED void *proto_ctx)
bool fr_vmps_ok(uint8_t const *packet, size_t *packet_len)
ssize_t fr_vmps_packet_size(uint8_t const *data, size_t data_len)
See how big of a packet is in the buffer.
fr_test_point_proto_decode_t vmps_tp_decode_proto
void fr_vmps_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len)
Print a raw VMPS packet as hex.
fr_test_point_proto_encode_t vmps_tp_encode_proto
Structures and prototypes for Cisco's VLAN Query Protocol.