Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | /* |
3 | | * PIM for Quagga |
4 | | * Copyright (C) 2008 Everton da Silva Marques |
5 | | */ |
6 | | |
7 | | #include <zebra.h> |
8 | | |
9 | | #include "log.h" |
10 | | #include "privs.h" |
11 | | #include "lib/version.h" |
12 | | #include <getopt.h> |
13 | | #include "command.h" |
14 | | #include "frrevent.h" |
15 | | #include <signal.h> |
16 | | |
17 | | #include "memory.h" |
18 | | #include "vrf.h" |
19 | | #include "filter.h" |
20 | | #include "vty.h" |
21 | | #include "sigevent.h" |
22 | | #include "prefix.h" |
23 | | #include "plist.h" |
24 | | #include "vrf.h" |
25 | | #include "libfrr.h" |
26 | | #include "routemap.h" |
27 | | #include "routing_nb.h" |
28 | | |
29 | | #include "pimd.h" |
30 | | #include "pim_instance.h" |
31 | | #include "pim_signals.h" |
32 | | #include "pim_zebra.h" |
33 | | #include "pim_msdp.h" |
34 | | #include "pim_iface.h" |
35 | | #include "pim_bfd.h" |
36 | | #include "pim_mlag.h" |
37 | | #include "pim_errors.h" |
38 | | #include "pim_nb.h" |
39 | | |
40 | | #define FUZZING 1 |
41 | | #ifdef FUZZING |
42 | | #include "fuzz.h" |
43 | | #include "pim_pim.h" |
44 | | #include "pim_mroute.h" |
45 | | #include "pim_tlv.h" |
46 | | #include "pim_neighbor.h" |
47 | | #endif |
48 | | |
49 | | extern struct host host; |
50 | | |
51 | | struct option longopts[] = {{0}}; |
52 | | |
53 | | /* pimd privileges */ |
54 | | zebra_capabilities_t _caps_p[] = { |
55 | | ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN, ZCAP_NET_RAW, ZCAP_BIND, |
56 | | }; |
57 | | |
58 | | /* pimd privileges to run with */ |
59 | | struct zebra_privs_t pimd_privs = { |
60 | | #if defined(FRR_USER) && defined(FRR_GROUP) |
61 | | .user = FRR_USER, |
62 | | .group = FRR_GROUP, |
63 | | #endif |
64 | | #ifdef VTY_GROUP |
65 | | .vty_group = VTY_GROUP, |
66 | | #endif |
67 | | .caps_p = _caps_p, |
68 | | .cap_num_p = array_size(_caps_p), |
69 | | .cap_num_i = 0}; |
70 | | |
71 | | static const struct frr_yang_module_info *const pimd_yang_modules[] = { |
72 | | &frr_filter_info, |
73 | | &frr_interface_info, |
74 | | &frr_route_map_info, |
75 | | &frr_vrf_info, |
76 | | &frr_routing_info, |
77 | | &frr_pim_info, |
78 | | &frr_pim_rp_info, |
79 | | &frr_gmp_info, |
80 | | }; |
81 | | |
82 | 2 | FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT, |
83 | 2 | |
84 | 2 | .proghelp = "Implementation of the PIM routing protocol.", |
85 | 2 | |
86 | 2 | .signals = pimd_signals, |
87 | 2 | .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/, |
88 | 2 | |
89 | 2 | .privs = &pimd_privs, .yang_modules = pimd_yang_modules, |
90 | 2 | .n_yang_modules = array_size(pimd_yang_modules), |
91 | 2 | ); |
92 | 2 | |
93 | 2 | #ifdef FUZZING |
94 | 2 | |
95 | 2 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); |
96 | 2 | |
97 | 2 | static struct interface *FuzzingIfp; |
98 | 2 | static struct in_addr FuzzingSrc = { .s_addr = 0x0900001b }; |
99 | 2 | |
100 | 2 | static bool FuzzingInit(void) |
101 | 2 | { |
102 | 1 | vrf_configure_backend(VRF_BACKEND_VRF_LITE); |
103 | | |
104 | 1 | const char *name[] = {"pimd"}; |
105 | | |
106 | 1 | frr_preinit(&pimd_di, 1, (char **)name); |
107 | 1 | pim_router_init(); |
108 | | |
109 | | /* |
110 | | * Initializations |
111 | | */ |
112 | 1 | pim_error_init(); |
113 | 1 | pim_vrf_init(); |
114 | 1 | access_list_init(); |
115 | 1 | prefix_list_init(); |
116 | 1 | prefix_list_add_hook(pim_prefix_list_update); |
117 | 1 | prefix_list_delete_hook(pim_prefix_list_update); |
118 | | |
119 | 1 | pim_route_map_init(); |
120 | 1 | pim_init(); |
121 | | |
122 | | /* |
123 | | * Initialize zclient "update" and "lookup" sockets |
124 | | */ |
125 | 1 | if_zapi_callbacks(pim_ifp_create, pim_ifp_up, |
126 | 1 | pim_ifp_down, pim_ifp_destroy); |
127 | 1 | pim_zebra_init(); |
128 | 1 | pim_bfd_init(); |
129 | 1 | pim_mlag_init(); |
130 | | |
131 | | /* Create some fake interface */ |
132 | | |
133 | | /* Source address stuff */ |
134 | 1 | struct prefix p; |
135 | 1 | str2prefix("27.0.0.9/24", &p); |
136 | | |
137 | | /* Create system interface */ |
138 | 1 | FuzzingIfp = if_get_by_name("fuzziface", VRF_DEFAULT, "default"); |
139 | 1 | if_set_index(FuzzingIfp, 69); |
140 | | |
141 | 1 | connected_add_by_prefix(FuzzingIfp, &p, NULL); |
142 | | |
143 | 1 | return true; |
144 | 1 | } |
145 | | |
146 | | static struct pim_instance *FuzzingCreatePimInstance(void) |
147 | 1 | { |
148 | | /* Create pim stuff */ |
149 | 1 | fprintf(stderr, ">>>>>>>>> %p\n", FuzzingIfp); |
150 | 1 | struct pim_interface *pim_ifp = pim_if_new(FuzzingIfp, true, true, false, false); |
151 | 1 | pim_igmp_sock_add(pim_ifp->gm_socket_list, FuzzingSrc, FuzzingIfp, false); |
152 | | |
153 | 1 | struct pim_instance *pim = vrf_lookup_by_id(VRF_DEFAULT)->info; |
154 | 1 | pim_if_create_pimreg(pim); |
155 | 1 | pim_hello_options ho = 0; |
156 | 1 | pim_neighbor_add(FuzzingIfp, FuzzingSrc, ho, 210, 1, 1, 30, 20, NULL, 0); |
157 | | |
158 | 1 | return pim; |
159 | 1 | } |
160 | | |
161 | | static bool FuzzingInitialized; |
162 | | |
163 | | static struct pim_instance *FuzzingPim; |
164 | | |
165 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
166 | 2.44k | { |
167 | 2.44k | if (!FuzzingInitialized) { |
168 | 1 | FuzzingInit(); |
169 | 1 | FuzzingInitialized = true; |
170 | 1 | FuzzingPim = FuzzingCreatePimInstance(); |
171 | 1 | } |
172 | | |
173 | 2.44k | struct pim_instance *pim; |
174 | 2.44k | #ifdef FUZZING_LIBFUZZER |
175 | 2.44k | pim = FuzzingPim; |
176 | | #else |
177 | | pim = FuzzingPim; |
178 | | #endif |
179 | | |
180 | 2.44k | int result; |
181 | | |
182 | 2.44k | uint8_t *input = malloc(size); |
183 | 2.44k | memcpy(input, data, size); |
184 | | |
185 | | #ifdef KERNEL_IFACE |
186 | | result = pim_mroute_msg(pim, (const char *) input, size, 69); |
187 | | #else |
188 | 2.44k | int retval; |
189 | 2.44k | struct in_addr src; |
190 | 2.44k | struct in_addr grp; |
191 | | |
192 | 2.44k | memset(&src, '\0', sizeof(src)); |
193 | 2.44k | memset(&grp, '\0', sizeof(grp)); |
194 | | |
195 | 2.44k | retval = inet_aton("10.1.1.1", &src); |
196 | 2.44k | retval = inet_aton("10.1.1.2", &grp); |
197 | | |
198 | 2.44k | pim_sgaddr sg; |
199 | 2.44k | sg.src = src; |
200 | 2.44k | sg.grp = grp; |
201 | 2.44k | result = pim_pim_packet(FuzzingIfp, input, size, sg); |
202 | | |
203 | 2.44k | #endif /* KERNEL_IFACE */ |
204 | | |
205 | 2.44k | free(input); |
206 | | |
207 | 2.44k | return result; |
208 | 2.44k | } |
209 | | #endif /* FUZZING */ |
210 | | |
211 | | #ifndef FUZZING_LIBFUZZER |
212 | | int main(int argc, char **argv, char **envp) |
213 | | { |
214 | | frr_preinit(&pimd_di, argc, argv); |
215 | | |
216 | | #ifdef FUZZING |
217 | | FuzzingInit(); |
218 | | FuzzingInitialized = true; |
219 | | FuzzingPim = FuzzingCreatePimInstance(); |
220 | | |
221 | | #ifdef __AFL_HAVE_MANUAL_CONTROL |
222 | | __AFL_INIT(); |
223 | | #endif /* __AFL_HAVE_MANUAL_CONTROL */ |
224 | | |
225 | | uint8_t *input = NULL; |
226 | | int r = frrfuzz_read_input(&input); |
227 | | |
228 | | int ret = LLVMFuzzerTestOneInput(input, r); |
229 | | |
230 | | return ret; |
231 | | #endif /* FUZZING */ |
232 | | |
233 | | frr_opt_add("", longopts, ""); |
234 | | |
235 | | /* this while just reads the options */ |
236 | | while (1) { |
237 | | int opt; |
238 | | |
239 | | opt = frr_getopt(argc, argv, NULL); |
240 | | |
241 | | if (opt == EOF) |
242 | | break; |
243 | | |
244 | | switch (opt) { |
245 | | case 0: |
246 | | break; |
247 | | default: |
248 | | frr_help_exit(1); |
249 | | break; |
250 | | } |
251 | | } |
252 | | |
253 | | pim_router_init(); |
254 | | |
255 | | /* |
256 | | * Initializations |
257 | | */ |
258 | | pim_error_init(); |
259 | | pim_vrf_init(); |
260 | | access_list_init(); |
261 | | prefix_list_init(); |
262 | | prefix_list_add_hook(pim_prefix_list_update); |
263 | | prefix_list_delete_hook(pim_prefix_list_update); |
264 | | |
265 | | pim_route_map_init(); |
266 | | pim_init(); |
267 | | |
268 | | /* |
269 | | * Initialize zclient "update" and "lookup" sockets |
270 | | */ |
271 | | pim_iface_init(); |
272 | | pim_zebra_init(); |
273 | | pim_bfd_init(); |
274 | | pim_mlag_init(); |
275 | | |
276 | | hook_register(routing_conf_event, |
277 | | routing_control_plane_protocols_name_validate); |
278 | | |
279 | | routing_control_plane_protocols_register_vrf_dependency(); |
280 | | |
281 | | frr_config_fork(); |
282 | | |
283 | | #ifdef PIM_DEBUG_BYDEFAULT |
284 | | zlog_notice("PIM_DEBUG_BYDEFAULT: Enabling all debug commands"); |
285 | | PIM_DO_DEBUG_PIM_EVENTS; |
286 | | PIM_DO_DEBUG_PIM_PACKETS; |
287 | | PIM_DO_DEBUG_PIM_TRACE; |
288 | | PIM_DO_DEBUG_GM_EVENTS; |
289 | | PIM_DO_DEBUG_GM_PACKETS; |
290 | | PIM_DO_DEBUG_GM_TRACE; |
291 | | PIM_DO_DEBUG_ZEBRA; |
292 | | #endif |
293 | | |
294 | | #ifdef PIM_CHECK_RECV_IFINDEX_SANITY |
295 | | zlog_notice( |
296 | | "PIM_CHECK_RECV_IFINDEX_SANITY: will match sock/recv ifindex"); |
297 | | #ifdef PIM_REPORT_RECV_IFINDEX_MISMATCH |
298 | | zlog_notice( |
299 | | "PIM_REPORT_RECV_IFINDEX_MISMATCH: will report sock/recv ifindex mismatch"); |
300 | | #endif |
301 | | #endif |
302 | | |
303 | | #ifdef PIM_UNEXPECTED_KERNEL_UPCALL |
304 | | zlog_notice( |
305 | | "PIM_UNEXPECTED_KERNEL_UPCALL: report unexpected kernel upcall"); |
306 | | #endif |
307 | | |
308 | | frr_run(router->master); |
309 | | |
310 | | /* never reached */ |
311 | | return 0; |
312 | | } |
313 | | #endif /* FUZZING_LIBFUZZER */ |