The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
base.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program 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
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /**
18  * $Id: 059e4a5e26b4cc5f6fd451444507cbd58e072470 $
19  * @file src/process/arp/base.c
20  * @brief ARP processing.
21  *
22  * @copyright 2020 Network RADIUS SAS (legal@networkradius.com)
23  */
24 #include <freeradius-devel/server/protocol.h>
25 #include <freeradius-devel/util/debug.h>
26 #include <freeradius-devel/arp/arp.h>
27 
28 static fr_dict_t const *dict_arp;
29 
32  { .out = &dict_arp, .proto = "arp" },
33  { NULL }
34 };
35 
37 
40  { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_arp},
41  { NULL }
42 };
43 
44 typedef struct {
45  uint64_t nothing; // so that the next field isn't at offset 0
46 
54 
55 typedef struct {
56  bool test;
57 
60 
61 #define PROCESS_PACKET_TYPE fr_arp_packet_code_t
62 #define PROCESS_CODE_MAX FR_ARP_CODE_MAX
63 #define PROCESS_CODE_DO_NOT_RESPOND FR_ARP_DO_NOT_RESPOND
64 #define PROCESS_PACKET_CODE_VALID FR_ARP_PACKET_CODE_VALID
65 #define PROCESS_INST process_arp_t
66 #include <freeradius-devel/server/process.h>
67 
68 static fr_process_state_t const process_state[] = {
69  [ FR_ARP_REQUEST ] = {
70  .packet_type = {
74 
80  },
81  .rcode = RLM_MODULE_NOOP,
82  .recv = recv_generic,
83  .resume = resume_recv_generic,
84  .section_offset = PROCESS_CONF_OFFSET(request),
85  },
86  [ FR_ARP_REPLY ] = {
87  .packet_type = {
91 
97  },
98  .rcode = RLM_MODULE_NOOP,
99  .send = send_generic,
100  .resume = resume_send_generic,
101  .section_offset = PROCESS_CONF_OFFSET(reply),
102  },
103 
104  [ FR_ARP_REVERSE_REQUEST ] = {
105  .packet_type = {
109 
115  },
116  .rcode = RLM_MODULE_NOOP,
117  .recv = recv_generic,
118  .resume = resume_recv_generic,
119  .section_offset = PROCESS_CONF_OFFSET(reverse_request),
120  },
121  [ FR_ARP_REVERSE_REPLY ] = {
122  .packet_type = {
126 
132  },
133  .rcode = RLM_MODULE_NOOP,
134  .send = send_generic,
135  .resume = resume_send_generic,
136  .section_offset = PROCESS_CONF_OFFSET(reverse_reply),
137  },
138 
139  // @todo - recv reply, to look at other replies.
140 
141  [ FR_ARP_DO_NOT_RESPOND ] = {
142  .packet_type = {
146 
152  },
153  .rcode = RLM_MODULE_NOOP,
154  .send = send_generic,
155  .resume = resume_send_generic,
156  .section_offset = PROCESS_CONF_OFFSET(do_not_respond),
157  },
158 };
159 
160 /*
161  * Debug the packet if requested.
162  */
163 static void arp_packet_debug(request_t *request, fr_packet_t const *packet, fr_pair_list_t const *list, bool received)
164 {
165  if (!packet) return;
166  if (!RDEBUG_ENABLED) return;
167 
168  log_request(L_DBG, L_DBG_LVL_1, request, __FILE__, __LINE__, "%s %s",
169  received ? "Received" : "Sending",
170  fr_arp_packet_codes[packet->code]);
171 
172  if (received || request->parent) {
173  log_request_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
174  } else {
175  log_request_proto_pair_list(L_DBG_LVL_1, request, NULL, list, NULL);
176  }
177 }
178 
179 static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
180 {
181  fr_process_state_t const *state;
182 
184 
186  fr_assert(PROCESS_PACKET_CODE_VALID(request->packet->code));
187 
188  request->component = "arp";
189  request->module = NULL;
190  fr_assert(request->dict == dict_arp);
191 
192  UPDATE_STATE(packet);
193 
194  if (!state->recv) {
195  REDEBUG("Invalid packet type (%u)", request->packet->code);
197  }
198 
199  arp_packet_debug(request, request->packet, &request->request_pairs, true);
200 
201  return state->recv(p_result, mctx, request);
202 }
203 
204 
206  {
207  .name = "recv",
208  .name2 = "Request",
209  .component = MOD_POST_AUTH,
210  .offset = PROCESS_CONF_OFFSET(request),
211  },
212  {
213  .name = "send",
214  .name2 = "Reply",
215  .component = MOD_POST_AUTH,
216  .offset = PROCESS_CONF_OFFSET(reply),
217  },
218  { /* we can listen for others ARP replies, too */
219  .name = "recv",
220  .name2 = "Reply",
221  .component = MOD_POST_AUTH,
222  .offset = PROCESS_CONF_OFFSET(recv_reply),
223  },
224  {
225  .name = "recv",
226  .name2 = "Reverse-Request",
227  .component = MOD_POST_AUTH,
228  .offset = PROCESS_CONF_OFFSET(reverse_request),
229  },
230 
231  {
232  .name = "send",
233  .name2 = "Reverse-Reply",
234  .component = MOD_POST_AUTH,
235  .offset = PROCESS_CONF_OFFSET(reverse_reply),
236  },
237  {
238  .name = "send",
239  .name2 = "Do-Not-Respond",
240  .component = MOD_POST_AUTH,
241  .offset = PROCESS_CONF_OFFSET(do_not_respond),
242  },
243 
245 };
246 
247 
250  .common = {
251  .magic = MODULE_MAGIC_INIT,
252  .name = "arp",
253  .inst_size = sizeof(process_arp_t)
254  },
255  .process = mod_process,
256  .compile_list = compile_list,
257  .dict = &dict_arp,
258 };
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition: action.h:35
@ FR_ARP_REVERSE_REQUEST
Definition: arp.h:67
@ FR_ARP_REQUEST
Definition: arp.h:65
@ FR_ARP_DO_NOT_RESPOND
Definition: arp.h:70
@ FR_ARP_REVERSE_REPLY
Definition: arp.h:68
@ FR_ARP_REPLY
Definition: arp.h:66
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
@ MOD_POST_AUTH
7 methods index for postauth section.
Definition: components.h:37
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition: dict.h:250
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition: dict.h:263
Specifies an attribute which must be present for the module to function.
Definition: dict.h:249
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition: dict.h:262
void *_CONST data
Module instance's parsed configuration.
Definition: dl_module.h:165
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition: dl_module.h:65
void log_request_proto_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a list of protocol fr_pair_ts.
Definition: log.c:845
void log_request(fr_log_type_t type, fr_log_lvl_t lvl, request_t *request, char const *file, int line, char const *fmt,...)
Marshal variadic log arguments into a va_list and pass to normal logging functions.
Definition: log.c:603
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
Definition: log.c:821
@ L_DBG_LVL_1
Highest priority debug messages (-x).
Definition: log.h:70
@ L_DBG
Only displayed when debugging is enabled.
Definition: log.h:59
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Definition: module_ctx.h:42
Temporary structure to hold arguments for module calls.
Definition: module_ctx.h:41
bool test
Definition: base.c:56
static fr_dict_attr_t const * attr_packet_type
Definition: base.c:36
static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition: base.c:179
uint64_t nothing
Definition: base.c:45
process_arp_sections_t sections
Definition: base.c:58
CONF_SECTION * request
Definition: base.c:47
CONF_SECTION * reverse_reply
Definition: base.c:51
static void arp_packet_debug(request_t *request, fr_packet_t const *packet, fr_pair_list_t const *list, bool received)
Definition: base.c:163
fr_dict_autoload_t process_arp_dict[]
Definition: base.c:31
fr_dict_attr_autoload_t process_arp_dict_attr[]
Definition: base.c:39
static const virtual_server_compile_t compile_list[]
Definition: base.c:205
CONF_SECTION * reply
Definition: base.c:48
static fr_process_state_t const process_state[]
Definition: base.c:68
CONF_SECTION * recv_reply
Definition: base.c:49
static fr_dict_t const * dict_arp
Definition: base.c:28
CONF_SECTION * reverse_request
Definition: base.c:50
fr_process_module_t process_arp
Definition: base.c:249
#define PROCESS_PACKET_CODE_VALID
Definition: base.c:64
CONF_SECTION * do_not_respond
Definition: base.c:52
#define PROCESS_TRACE
Trace each state function as it's entered.
Definition: process.h:65
module_t common
Common fields for all loadable modules.
Definition: process.h:55
Common public symbol definition for all process modules.
Definition: process.h:54
char const * fr_arp_packet_codes[FR_ARP_CODE_MAX]
Definition: base.c:63
#define REDEBUG(fmt,...)
Definition: radclient.h:52
#define RDEBUG_ENABLED()
Definition: radclient.h:49
rlm_rcode_t
Return codes indicating the result of the module call.
Definition: rcode.h:40
@ RLM_MODULE_INVALID
The module considers the request invalid.
Definition: rcode.h:45
@ RLM_MODULE_OK
The module is OK, continue.
Definition: rcode.h:43
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition: rcode.h:42
@ RLM_MODULE_DISALLOW
Reject the request (user is locked out).
Definition: rcode.h:46
@ RLM_MODULE_REJECT
Immediately reject the request.
Definition: rcode.h:41
@ RLM_MODULE_NOTFOUND
User not found.
Definition: rcode.h:47
@ RLM_MODULE_UPDATED
OK (pairs modified).
Definition: rcode.h:49
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition: rcode.h:48
RETURN_MODULE_FAIL
fr_assert(0)
#define talloc_get_type_abort_const
Definition: talloc.h:270
unsigned int code
Packet code (type).
Definition: packet.h:61
#define COMPILE_TERMINATOR
char const * name
Name of the processing section, such as "recv" or "send".
Processing sections which are allowed in this virtual server.