Coverage Report

Created: 2026-09-14 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/pimd/pim_main.c
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 */