Coverage Report

Created: 2023-09-25 06:52

/src/lldpd/src/lldpd-structs.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- mode: c; c-file-style: "openbsd" -*- */
2
/*
3
 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
4
 *
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <stdlib.h>
19
#include <unistd.h>
20
#include <time.h>
21
#include "lldpd-structs.h"
22
#include "log.h"
23
24
void
25
lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *chassis)
26
2.27k
{
27
2.27k
  struct lldpd_mgmt *mgmt, *mgmt_next;
28
29
2.27k
  log_debug("alloc", "cleanup management addresses for chassis %s",
30
2.27k
      chassis->c_name ? chassis->c_name : "(unknown)");
31
32
3.28k
  for (mgmt = TAILQ_FIRST(&chassis->c_mgmt); mgmt != NULL; mgmt = mgmt_next) {
33
1.01k
    mgmt_next = TAILQ_NEXT(mgmt, m_entries);
34
1.01k
    free(mgmt);
35
1.01k
  }
36
2.27k
  TAILQ_INIT(&chassis->c_mgmt);
37
2.27k
}
38
39
void
40
lldpd_chassis_cleanup(struct lldpd_chassis *chassis, int all)
41
2.27k
{
42
2.27k
  lldpd_chassis_mgmt_cleanup(chassis);
43
2.27k
  log_debug("alloc", "cleanup chassis %s",
44
2.27k
      chassis->c_name ? chassis->c_name : "(unknown)");
45
2.27k
#ifdef ENABLE_LLDPMED
46
2.27k
  free(chassis->c_med_hw);
47
2.27k
  free(chassis->c_med_sw);
48
2.27k
  free(chassis->c_med_fw);
49
2.27k
  free(chassis->c_med_sn);
50
2.27k
  free(chassis->c_med_manuf);
51
2.27k
  free(chassis->c_med_model);
52
2.27k
  free(chassis->c_med_asset);
53
2.27k
#endif
54
2.27k
  free(chassis->c_id);
55
2.27k
  free(chassis->c_name);
56
2.27k
  free(chassis->c_descr);
57
2.27k
  if (all) free(chassis);
58
2.27k
}
59
60
#ifdef ENABLE_DOT1
61
void
62
lldpd_vlan_cleanup(struct lldpd_port *port)
63
2.27k
{
64
2.27k
  struct lldpd_vlan *vlan, *vlan_next;
65
3.25k
  for (vlan = TAILQ_FIRST(&port->p_vlans); vlan != NULL; vlan = vlan_next) {
66
984
    free(vlan->v_name);
67
984
    vlan_next = TAILQ_NEXT(vlan, v_entries);
68
984
    free(vlan);
69
984
  }
70
2.27k
  TAILQ_INIT(&port->p_vlans);
71
2.27k
  port->p_pvid = 0;
72
2.27k
}
73
74
void
75
lldpd_ppvid_cleanup(struct lldpd_port *port)
76
2.27k
{
77
2.27k
  struct lldpd_ppvid *ppvid, *ppvid_next;
78
2.66k
  for (ppvid = TAILQ_FIRST(&port->p_ppvids); ppvid != NULL; ppvid = ppvid_next) {
79
394
    ppvid_next = TAILQ_NEXT(ppvid, p_entries);
80
394
    free(ppvid);
81
394
  }
82
2.27k
  TAILQ_INIT(&port->p_ppvids);
83
2.27k
}
84
85
void
86
lldpd_pi_cleanup(struct lldpd_port *port)
87
2.27k
{
88
2.27k
  struct lldpd_pi *pi, *pi_next;
89
2.67k
  for (pi = TAILQ_FIRST(&port->p_pids); pi != NULL; pi = pi_next) {
90
405
    free(pi->p_pi);
91
405
    pi_next = TAILQ_NEXT(pi, p_entries);
92
405
    free(pi);
93
405
  }
94
2.27k
  TAILQ_INIT(&port->p_pids);
95
2.27k
}
96
#endif
97
98
#ifdef ENABLE_CUSTOM
99
void
100
lldpd_custom_tlv_add(struct lldpd_port *port, struct lldpd_custom *curr)
101
0
{
102
0
  struct lldpd_custom *custom;
103
104
0
  if ((custom = malloc(sizeof(struct lldpd_custom)))) {
105
0
    memcpy(custom, curr, sizeof(struct lldpd_custom));
106
0
    if ((custom->oui_info = malloc(custom->oui_info_len))) {
107
0
      memcpy(custom->oui_info, curr->oui_info, custom->oui_info_len);
108
0
      TAILQ_INSERT_TAIL(&port->p_custom_list, custom, next);
109
0
    } else {
110
0
      free(custom);
111
0
      log_warn("rpc",
112
0
          "could not allocate memory for custom TLV info");
113
0
    }
114
0
  }
115
0
}
116
117
void
118
lldpd_custom_tlv_cleanup(struct lldpd_port *port, struct lldpd_custom *curr)
119
0
{
120
0
  struct lldpd_custom *custom, *custom_next;
121
0
  for (custom = TAILQ_FIRST(&port->p_custom_list); custom != NULL;
122
0
       custom = custom_next) {
123
0
    custom_next = TAILQ_NEXT(custom, next);
124
0
    if (!memcmp(curr->oui, custom->oui, sizeof(curr->oui)) &&
125
0
        curr->subtype == custom->subtype) {
126
0
      TAILQ_REMOVE(&port->p_custom_list, custom, next);
127
0
      free(custom->oui_info);
128
0
      free(custom);
129
0
    }
130
0
  }
131
0
}
132
133
void
134
lldpd_custom_list_cleanup(struct lldpd_port *port)
135
2.27k
{
136
2.27k
  struct lldpd_custom *custom, *custom_next;
137
3.60k
  for (custom = TAILQ_FIRST(&port->p_custom_list); custom != NULL;
138
2.27k
       custom = custom_next) {
139
1.32k
    custom_next = TAILQ_NEXT(custom, next);
140
1.32k
    free(custom->oui_info);
141
1.32k
    free(custom);
142
1.32k
  }
143
2.27k
  TAILQ_INIT(&port->p_custom_list);
144
2.27k
}
145
#endif
146
147
/* Cleanup a remote port. The before last argument, `expire` is a function that
148
 * should be called when a remote port is removed. If the last argument is 1,
149
 * all remote ports are removed.
150
 */
151
void
152
lldpd_remote_cleanup(struct lldpd_hardware *hardware,
153
    void (*expire)(struct lldpd_hardware *, struct lldpd_port *), int all)
154
0
{
155
0
  struct lldpd_port *port, *port_next;
156
0
  int del;
157
0
  time_t now = time(NULL);
158
159
0
  log_debug("alloc", "cleanup remote port on %s", hardware->h_ifname);
160
0
  for (port = TAILQ_FIRST(&hardware->h_rports); port != NULL; port = port_next) {
161
0
    port_next = TAILQ_NEXT(port, p_entries);
162
0
    del = all;
163
0
    if (!all && expire && (now >= port->p_lastupdate + port->p_ttl)) {
164
0
      if (port->p_ttl > 0) hardware->h_ageout_cnt++;
165
0
      del = 1;
166
0
    }
167
0
    if (del) {
168
0
      if (expire) expire(hardware, port);
169
      /* This TAILQ_REMOVE is dangerous. It should not be
170
       * called while in liblldpctl because we don't have a
171
       * real list. It is only needed to be called when we
172
       * don't delete the entire list. */
173
0
      if (!all) TAILQ_REMOVE(&hardware->h_rports, port, p_entries);
174
175
0
      hardware->h_delete_cnt++;
176
      /* Register last removal to be able to report
177
       * lldpStatsRemTablesLastChangeTime */
178
0
      hardware->h_lport.p_lastremove = time(NULL);
179
0
      lldpd_port_cleanup(port, 1);
180
0
      free(port);
181
0
    }
182
0
  }
183
0
  if (all) TAILQ_INIT(&hardware->h_rports);
184
0
}
185
186
/* If `all' is true, clear all information, including information that
187
   are not refreshed periodically. Port should be freed manually. */
188
void
189
lldpd_port_cleanup(struct lldpd_port *port, int all)
190
2.27k
{
191
2.27k
#ifdef ENABLE_LLDPMED
192
2.27k
  int i;
193
2.27k
  if (all)
194
9.09k
    for (i = 0; i < LLDP_MED_LOCFORMAT_LAST; i++)
195
6.82k
      free(port->p_med_location[i].data);
196
2.27k
#endif
197
2.27k
#ifdef ENABLE_DOT1
198
2.27k
  lldpd_vlan_cleanup(port);
199
2.27k
  lldpd_ppvid_cleanup(port);
200
2.27k
  lldpd_pi_cleanup(port);
201
2.27k
#endif
202
  /* will set these to NULL so we don't free wrong memory */
203
204
2.27k
  if (all) {
205
2.27k
    free(port->p_id);
206
2.27k
    port->p_id = NULL;
207
2.27k
    free(port->p_descr);
208
2.27k
    port->p_descr = NULL;
209
2.27k
    free(port->p_lastframe);
210
2.27k
    if (port->p_chassis) { /* chassis may not have been attributed, yet */
211
0
      port->p_chassis->c_refcount--;
212
0
      port->p_chassis = NULL;
213
0
    }
214
2.27k
#ifdef ENABLE_CUSTOM
215
2.27k
    lldpd_custom_list_cleanup(port);
216
2.27k
#endif
217
2.27k
  }
218
2.27k
}
219
220
void
221
lldpd_config_cleanup(struct lldpd_config *config)
222
0
{
223
0
  log_debug("alloc", "general configuration cleanup");
224
0
  free(config->c_mgmt_pattern);
225
0
  free(config->c_cid_pattern);
226
0
  free(config->c_cid_string);
227
0
  free(config->c_iface_pattern);
228
0
  free(config->c_perm_ifaces);
229
0
  free(config->c_hostname);
230
0
  free(config->c_platform);
231
0
  free(config->c_description);
232
0
}