The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
packet.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/** fr_packet_t alloc/free functions
18 *
19 * @file src/lib/server/packet.c
20 *
21 * @copyright 2023 Network RADIUS SAS (legal@networkradius.com)
22 */
23
24RCSID("$Id: 5a66a58568a06cafc2c901b7d63e3d193bfb76b4 $")
25
26#include <freeradius-devel/util/atexit.h>
27#include <freeradius-devel/util/pair_legacy.h>
28
29#include <freeradius-devel/server/packet.h>
30
32
35 { .out = &dict_freeradius, .proto = "freeradius" },
36 { NULL }
37};
38
47
50 { .out = &attr_net, .name = "Net", .type = FR_TYPE_TLV, .dict = &dict_freeradius },
51 { .out = &attr_net_src, .name = "Net.Src", .type = FR_TYPE_TLV, .dict = &dict_freeradius },
52 { .out = &attr_net_dst, .name = "Net.Dst", .type = FR_TYPE_TLV, .dict = &dict_freeradius },
53 { .out = &attr_net_src_ip, .name = "Net.Src.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
54 { .out = &attr_net_src_port, .name = "Net.Src.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
55 { .out = &attr_net_dst_ip, .name = "Net.Dst.IP", .type = FR_TYPE_COMBO_IP_ADDR, .dict = &dict_freeradius },
56 { .out = &attr_net_dst_port, .name = "Net.Dst.Port", .type = FR_TYPE_UINT16, .dict = &dict_freeradius },
57 { .out = &attr_net_timestamp, .name = "Net.Timestamp", .type = FR_TYPE_DATE, .dict = &dict_freeradius },
58
59 { NULL }
60};
61
62static int inet2pairs(TALLOC_CTX *ctx, fr_pair_list_t *list,
63 fr_dict_attr_t const *attr_ip, fr_dict_attr_t const *attr_port,
64 fr_ipaddr_t const *ipaddr, uint16_t port)
65{
67
68 if (fr_pair_find_or_append_by_da(ctx, &vp, list, attr_ip) < 0) return -1;
69 fr_value_box_ipaddr(&vp->data, attr_ip, ipaddr, false);
71
72 if (fr_pair_find_or_append_by_da(ctx, &vp, list, attr_port) < 0) return -1;
73 vp->vp_uint16 = port;
75
76 return 0;
77}
78
79/** Allocate a "Net." struct with src/dst host and port.
80 *
81 * @param ctx The context in which the packet is allocated.
82 * @param[in] list #fr_pair_list_t value to resolve to #fr_packet_t.
83 * @param[out] packet The request packet.
84 *
85 * @return
86 * - 0 on success
87 * - <0 on error.
88 */
89int fr_packet_pairs_from_packet(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_packet_t const *packet)
90{
91 fr_pair_t *vp, *net, *tlv;
92
93 /*
94 * Net
95 */
96 if (fr_pair_find_or_append_by_da(ctx, &net, list, attr_net) < 0) return -1;
97
98 /*
99 * Net.Src
100 */
101 if (fr_pair_find_or_append_by_da(net, &tlv, &net->vp_group, attr_net_src) < 0) return -1;
102
103 if (inet2pairs(tlv, &tlv->vp_group, attr_net_src_ip, attr_net_src_port, &packet->socket.inet.src_ipaddr, packet->socket.inet.src_port) < 0) return -1;
104
105 /*
106 * Net.Dst
107 */
108 if (fr_pair_find_or_append_by_da(net, &tlv, &net->vp_group, attr_net_dst) < 0) return -1;
109
110 if (inet2pairs(tlv, &tlv->vp_group, attr_net_dst_ip, attr_net_dst_port, &packet->socket.inet.dst_ipaddr, packet->socket.inet.dst_port) < 0) return -1;
111
112 /*
113 * Timestamp
114 */
115 if (fr_pair_find_or_append_by_da(net, &vp, &net->vp_group, attr_net_timestamp) < 0) return -1;
116 vp->vp_date = fr_time_to_unix_time(packet->timestamp);
118
119 return 0;
120}
121
122static void pairs2inet(fr_ipaddr_t *ipaddr, uint16_t *port, fr_pair_list_t const *list,
123 fr_dict_attr_t const *attr_ip, fr_dict_attr_t const *attr_port)
124{
125 fr_pair_t *vp;
126
127 vp = fr_pair_find_by_da(list, NULL, attr_ip);
128 if (vp) *ipaddr = vp->vp_ip;
129
130 vp = fr_pair_find_by_da(list, NULL, attr_port);
131 if (vp) *port = vp->vp_uint16;
132}
133
134/** Convert pairs to information in a packet.
135 *
136 * @param packet the packet to send
137 * @param list the list to check for Net.*
138 */
140{
141 fr_pair_t *net, *tlv;
142
143 net = fr_pair_find_by_da(list, NULL, attr_net);
144 if (!net) return;
145
146 tlv = fr_pair_find_by_da(&net->vp_group, NULL, attr_net_src);
147 if (tlv) {
148 pairs2inet(&packet->socket.inet.src_ipaddr, &packet->socket.inet.src_port, &tlv->vp_group,
150 }
151
152 tlv = fr_pair_find_by_da(&net->vp_group, NULL, attr_net_dst);
153 if (tlv) {
154 pairs2inet(&packet->socket.inet.dst_ipaddr, &packet->socket.inet.dst_port, &tlv->vp_group,
156 }
157}
158
159static int _packet_global_free(UNUSED void *uctx)
160{
162
163 return 0;
164}
165
166static int _packet_global_init(UNUSED void *uctx)
167{
169 error:
170 fr_perror("packet_global_init");
171 return -1;
172 }
173
174 if (fr_dict_attr_autoload(util_packet_dict_attr) < 0) goto error;
175
176 return 0;
177}
178
179/** Initialises the Net. packet attributes.
180 *
181 * @return
182 * - 0 on success.
183 * - -1 on failure.
184 */
186{
187 int ret;
188
189 fr_atexit_global_once_ret(&ret, _packet_global_init, _packet_global_free, NULL);
190
191 return ret;
192}
#define RCSID(id)
Definition build.h:483
#define UNUSED
Definition build.h:315
#define fr_dict_autofree(_to_free)
Definition dict.h:853
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:268
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:281
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.
Definition dict_util.c:4090
#define fr_dict_autoload(_to_load)
Definition dict.h:850
Specifies an attribute which must be present for the module to function.
Definition dict.h:267
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:280
IPv4/6 prefix.
int packet_global_init(void)
Initialises the Net.
Definition packet.c:185
static fr_dict_attr_t const * attr_net_src
Definition packet.c:40
static void pairs2inet(fr_ipaddr_t *ipaddr, uint16_t *port, fr_pair_list_t const *list, fr_dict_attr_t const *attr_ip, fr_dict_attr_t const *attr_port)
Definition packet.c:122
static int inet2pairs(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *attr_ip, fr_dict_attr_t const *attr_port, fr_ipaddr_t const *ipaddr, uint16_t port)
Definition packet.c:62
static fr_dict_attr_t const * attr_net_dst_port
Definition packet.c:45
static fr_dict_t const * dict_freeradius
Definition packet.c:31
static fr_dict_attr_t const * attr_net_timestamp
Definition packet.c:46
fr_dict_autoload_t util_packet_dict[]
Definition packet.c:34
static fr_dict_attr_t const * attr_net
Definition packet.c:39
int fr_packet_pairs_from_packet(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_packet_t const *packet)
Allocate a "Net." struct with src/dst host and port.
Definition packet.c:89
void fr_packet_net_from_pairs(fr_packet_t *packet, fr_pair_list_t const *list)
Convert pairs to information in a packet.
Definition packet.c:139
static fr_dict_attr_t const * attr_net_dst
Definition packet.c:43
fr_dict_attr_autoload_t util_packet_dict_attr[]
Definition packet.c:49
static int _packet_global_init(UNUSED void *uctx)
Definition packet.c:166
static fr_dict_attr_t const * attr_net_src_ip
Definition packet.c:41
static fr_dict_attr_t const * attr_net_dst_ip
Definition packet.c:44
static int _packet_global_free(UNUSED void *uctx)
Definition packet.c:159
static fr_dict_attr_t const * attr_net_src_port
Definition packet.c:42
unsigned short uint16_t
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:693
fr_pair_t * vp
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
Definition time.h:688
fr_socket_t socket
This packet was received on.
Definition packet.h:57
fr_time_t timestamp
When we received the packet.
Definition packet.h:58
static int fr_pair_find_or_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Definition pair.h:523
static void fr_pair_set_immutable(fr_pair_t *vp)
Definition pair.h:688
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition strerror.c:733
int fr_value_box_ipaddr(fr_value_box_t *dst, fr_dict_attr_t const *enumv, fr_ipaddr_t const *ipaddr, bool tainted)
Assign a fr_value_box_t value from an fr_ipaddr_t.
Definition value.c:3630