26RCSID(
"$Id: f3b58faa30befebf3f9fbb5d56834cfd6c9c07ab $")
28#include <freeradius-devel/util/net.h>
29#include <freeradius-devel/util/struct.h>
30#include <freeradius-devel/util/syserror.h>
31#include <freeradius-devel/io/test_point.h>
34#ifdef HAVE_LINUX_IF_PACKET_H
35# include <linux/if_packet.h>
36# include <linux/if_ether.h>
39#include <net/if_arp.h>
66 [3] =
"Reverse-Request",
67 [4] =
"Reverse-Reply",
69 [5] =
"DRARP-Request",
72 [8] =
"InARP-Request",
75 [11] =
"MARS-Request",
84 [20] =
"MARS-Grouplist-Request",
85 [21] =
"MARS-Grouplist-Reply",
86 [22] =
"MARS-Redirect-MAP",
108 struct sockaddr_in *sin;
116 memset(&req, 0,
sizeof(req));
117 sin = (
struct sockaddr_in *) &req.arp_pa;
118 sin->sin_family = AF_INET;
119 memcpy(&sin->sin_addr.s_addr, ipaddr, 4);
121 strlcpy(req.arp_dev, interface,
sizeof(req.arp_dev));
123 memcpy(&req.arp_ha.sa_data, macaddr, 6);
125 req.arp_flags = ATF_COM;
126 if (ioctl(fd, SIOCSARP, &req) < 0) {
181 if (slen <= 0)
return slen;
190 if ((arp->
htype[0] == 0) && (arp->
htype[1] == 0)) arp->
htype[1] = FR_HARDWARE_FORMAT_VALUE_ETHERNET;
191 if ((arp->
ptype[0] == 0) && (arp->
ptype[1] == 0)) arp->
ptype[0] = (FR_PROTOCOL_FORMAT_VALUE_IPV4 >> 8);
204#define COPY(_a, _b) do { \
205 if (memcmp(arp->_a, zeros, sizeof(arp->_a)) == 0) { \
206 memcpy(arp->_a, our_original->_b, sizeof(arp->_a)); \
234 if ((arp->
htype[0] != 0) || (arp->
htype[1] != 1)) {
239 if ((arp->
ptype[0] != 8) || (arp->
ptype[1] != 0)) {
244 if (arp->
hlen != 6) {
249 if (arp->
plen != 4) {
296 .default_type_size = 4,
297 .default_type_length = 0,
315 if (!test_ctx)
return -1;
uint8_t hlen
Length of hardware address.
uint8_t plen
Length of protocol address.
uint8_t htype[2]
Format of hardware address.
uint8_t ptype[2]
Format of protocol address.
#define FR_ARP_PACKET_SIZE
char const * fr_arp_packet_codes[FR_ARP_CODE_MAX]
#define fr_dbuff_set(_dst, _src)
Set the 'current' position in a dbuff or marker using another dbuff or marker, a char pointer,...
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
#define fr_dict_autofree(_to_free)
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
#define fr_dict_autoload(_to_load)
char const * name
name of this protocol
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
Protocol-specific callbacks in libfreeradius-PROTOCOL.
static uint32_t instance_count
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
static fr_dict_t const * dict_arp
void fr_proto_da_stack_build(fr_da_stack_t *stack, fr_dict_attr_t const *da)
Build a complete DA stack from the da back to the root.
static ssize_t fr_arp_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, UNUSED void *proto_ctx)
void fr_arp_global_free(void)
int fr_arp_global_init(void)
int fr_arp_entry_add(UNUSED int fd, UNUSED char const *interface, UNUSED uint8_t ipaddr[static 4], UNUSED uint8_t macaddr[static 6])
fr_dict_attr_t const * attr_arp_packet
static uint8_t const zeros[6]
fr_dict_protocol_t libfreeradius_arp_dict_protocol
static int encode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict)
ssize_t fr_arp_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len)
Decode a raw ARP packet into VPs.
fr_dict_autoload_t libfreeradius_arp_dict[]
fr_dict_attr_autoload_t libfreeradius_arp_dict_attr[]
static ssize_t fr_arp_decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, UNUSED void *proto_ctx)
fr_test_point_proto_encode_t arp_tp_encode_proto
fr_test_point_proto_decode_t arp_tp_decode_proto
ssize_t fr_arp_encode(fr_dbuff_t *dbuff, uint8_t const *original, fr_pair_list_t *vps)
Encode VPS into a raw ARP packet.
size_t strlcpy(char *dst, char const *src, size_t siz)
ssize_t fr_struct_to_network(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *parent_cursor, void *encode_ctx, fr_encode_dbuff_t encode_value, fr_encode_dbuff_t encode_pair)
ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_value_t decode_value, fr_pair_decode_value_t decode_tlv)
Convert a STRUCT to one or more VPs.
Stores an attribute, a value and various bits of other data.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
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.
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
#define fr_pair_dcursor_by_ancestor_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes descended from the specified fr_dict_attr_t.
#define FR_PROTO_STACK_PRINT(_stack, _depth)
Structure for holding the stack of dictionary attributes being encoded.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
static size_t char ** out