Bug Summary

File:src/usr.sbin/ldpd/address.c
Warning:line 161, column 2
Value stored to 'size' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name address.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/ldpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/ldpd -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/ldpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/ldpd/address.c
1/* $OpenBSD: address.c,v 1.35 2017/03/04 00:21:48 renato Exp $ */
2
3/*
4 * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <arpa/inet.h>
21#include <stdlib.h>
22#include <string.h>
23
24#include "ldpd.h"
25#include "ldpe.h"
26#include "lde.h"
27#include "log.h"
28
29static void send_address(struct nbr *, int, struct if_addr_head *,
30 unsigned int, int);
31static int gen_address_list_tlv(struct ibuf *, int, struct if_addr_head *,
32 unsigned int);
33static int gen_mac_list_tlv(struct ibuf *, uint8_t *);
34static void address_list_add(struct if_addr_head *, struct if_addr *);
35static void address_list_clr(struct if_addr_head *);
36static void log_msg_address(int, uint16_t, struct nbr *, int,
37 union ldpd_addr *);
38static void log_msg_mac_withdrawal(int, struct nbr *, uint8_t *);
39
40static void
41send_address(struct nbr *nbr, int af, struct if_addr_head *addr_list,
42 unsigned int addr_count, int withdraw)
43{
44 struct ibuf *buf;
45 uint16_t msg_type;
46 uint8_t addr_size;
47 struct if_addr *if_addr;
48 uint16_t size;
49 unsigned int tlv_addr_count = 0;
50 int err = 0;
51
52 /* nothing to send */
53 if (LIST_EMPTY(addr_list)(((addr_list)->lh_first) == ((void *)0)))
54 return;
55
56 if (!withdraw)
57 msg_type = MSG_TYPE_ADDR0x0300;
58 else
59 msg_type = MSG_TYPE_ADDRWITHDRAW0x0301;
60
61 switch (af) {
62 case AF_INET2:
63 addr_size = sizeof(struct in_addr);
64 break;
65 case AF_INET624:
66 addr_size = sizeof(struct in6_addr);
67 break;
68 default:
69 fatalx("send_address: unknown af");
70 }
71
72 while ((if_addr = LIST_FIRST(addr_list)((addr_list)->lh_first)) != NULL((void *)0)) {
73 /*
74 * Send as many addresses as possible - respect the session's
75 * negotiated maximum pdu length.
76 */
77 size = LDP_HDR_SIZE10 + LDP_MSG_SIZE8 + ADDR_LIST_SIZE6;
78 if (size + addr_count * addr_size <= nbr->max_pdu_len)
79 tlv_addr_count = addr_count;
80 else
81 tlv_addr_count = (nbr->max_pdu_len - size) / addr_size;
82 size += tlv_addr_count * addr_size;
83 addr_count -= tlv_addr_count;
84
85 if ((buf = ibuf_open(size)) == NULL((void *)0))
86 fatal(__func__);
87
88 err |= gen_ldp_hdr(buf, size);
89 size -= LDP_HDR_SIZE10;
90 err |= gen_msg_hdr(buf, msg_type, size);
91 size -= LDP_MSG_SIZE8;
92 err |= gen_address_list_tlv(buf, af, addr_list, tlv_addr_count);
93 if (err) {
94 address_list_clr(addr_list);
95 ibuf_free(buf);
96 return;
97 }
98
99 while ((if_addr = LIST_FIRST(addr_list)((addr_list)->lh_first)) != NULL((void *)0)) {
100 log_msg_address(1, msg_type, nbr, af, &if_addr->addr);
101
102 LIST_REMOVE(if_addr, entry)do { if ((if_addr)->entry.le_next != ((void *)0)) (if_addr
)->entry.le_next->entry.le_prev = (if_addr)->entry.le_prev
; *(if_addr)->entry.le_prev = (if_addr)->entry.le_next;
; ; } while (0)
;
103 free(if_addr);
104 if (--tlv_addr_count == 0)
105 break;
106 }
107
108 evbuf_enqueue(&nbr->tcp->wbuf, buf);
109 }
110
111 nbr_fsm(nbr, NBR_EVT_PDU_SENT);
112}
113
114void
115send_address_single(struct nbr *nbr, struct if_addr *if_addr, int withdraw)
116{
117 struct if_addr_head addr_list;
118
119 LIST_INIT(&addr_list)do { ((&addr_list)->lh_first) = ((void *)0); } while (
0)
;
120 address_list_add(&addr_list, if_addr);
121 send_address(nbr, if_addr->af, &addr_list, 1, withdraw);
122}
123
124void
125send_address_all(struct nbr *nbr, int af)
126{
127 struct if_addr_head addr_list;
128 struct if_addr *if_addr;
129 unsigned int addr_count = 0;
130
131 LIST_INIT(&addr_list)do { ((&addr_list)->lh_first) = ((void *)0); } while (
0)
;
132 LIST_FOREACH(if_addr, &global.addr_list, entry)for((if_addr) = ((&global.addr_list)->lh_first); (if_addr
)!= ((void *)0); (if_addr) = ((if_addr)->entry.le_next))
{
133 if (if_addr->af != af)
134 continue;
135
136 address_list_add(&addr_list, if_addr);
137 addr_count++;
138 }
139
140 send_address(nbr, af, &addr_list, addr_count, 0);
141}
142
143void
144send_mac_withdrawal(struct nbr *nbr, struct map *fec, uint8_t *mac)
145{
146 struct ibuf *buf;
147 uint16_t size;
148 int err;
149
150 size = LDP_HDR_SIZE10 + LDP_MSG_SIZE8 + ADDR_LIST_SIZE6 + len_fec_tlv(fec) +
151 TLV_HDR_SIZE4;
152 if (mac)
153 size += ETHER_ADDR_LEN6;
154
155 if ((buf = ibuf_open(size)) == NULL((void *)0))
156 fatal(__func__);
157
158 err = gen_ldp_hdr(buf, size);
159 size -= LDP_HDR_SIZE10;
160 err |= gen_msg_hdr(buf, MSG_TYPE_ADDRWITHDRAW0x0301, size);
161 size -= LDP_MSG_SIZE8;
Value stored to 'size' is never read
162 err |= gen_address_list_tlv(buf, AF_INET2, NULL((void *)0), 0);
163 err |= gen_fec_tlv(buf, fec);
164 err |= gen_mac_list_tlv(buf, mac);
165 if (err) {
166 ibuf_free(buf);
167 return;
168 }
169
170 log_msg_mac_withdrawal(1, nbr, mac);
171
172 evbuf_enqueue(&nbr->tcp->wbuf, buf);
173
174 nbr_fsm(nbr, NBR_EVT_PDU_SENT);
175}
176
177int
178recv_address(struct nbr *nbr, char *buf, uint16_t len)
179{
180 struct ldp_msg msg;
181 uint16_t msg_type;
182 enum imsg_type type;
183 struct address_list_tlv alt;
184 uint16_t alt_len;
185 uint16_t alt_family;
186 struct lde_addr lde_addr;
187
188 memcpy(&msg, buf, sizeof(msg));
189 msg_type = ntohs(msg.type)(__uint16_t)(__builtin_constant_p(msg.type) ? (__uint16_t)(((
__uint16_t)(msg.type) & 0xffU) << 8 | ((__uint16_t)
(msg.type) & 0xff00U) >> 8) : __swap16md(msg.type))
;
190 switch (msg_type) {
191 case MSG_TYPE_ADDR0x0300:
192 type = IMSG_ADDRESS_ADD;
193 break;
194 case MSG_TYPE_ADDRWITHDRAW0x0301:
195 type = IMSG_ADDRESS_DEL;
196 break;
197 default:
198 fatalx("recv_address: unexpected msg type");
199 }
200 buf += LDP_MSG_SIZE8;
201 len -= LDP_MSG_SIZE8;
202
203 /* Address List TLV */
204 if (len < ADDR_LIST_SIZE6) {
205 session_shutdown(nbr, S_BAD_MSG_LEN0x80000005, msg.id, msg.type);
206 return (-1);
207 }
208 memcpy(&alt, buf, sizeof(alt));
209 alt_len = ntohs(alt.length)(__uint16_t)(__builtin_constant_p(alt.length) ? (__uint16_t)(
((__uint16_t)(alt.length) & 0xffU) << 8 | ((__uint16_t
)(alt.length) & 0xff00U) >> 8) : __swap16md(alt.length
))
;
210 alt_family = ntohs(alt.family)(__uint16_t)(__builtin_constant_p(alt.family) ? (__uint16_t)(
((__uint16_t)(alt.family) & 0xffU) << 8 | ((__uint16_t
)(alt.family) & 0xff00U) >> 8) : __swap16md(alt.family
))
;
211 if (alt_len > len - TLV_HDR_SIZE4) {
212 session_shutdown(nbr, S_BAD_TLV_LEN0x80000007, msg.id, msg.type);
213 return (-1);
214 }
215 if (ntohs(alt.type)(__uint16_t)(__builtin_constant_p(alt.type) ? (__uint16_t)(((
__uint16_t)(alt.type) & 0xffU) << 8 | ((__uint16_t)
(alt.type) & 0xff00U) >> 8) : __swap16md(alt.type))
!= TLV_TYPE_ADDRLIST0x0101) {
216 send_notification(nbr->tcp, S_MISS_MSG0x00000016, msg.id, msg.type);
217 return (-1);
218 }
219 switch (alt_family) {
220 case AF_IPV40x1:
221 if (!nbr->v4_enabled)
222 /* just ignore the message */
223 return (0);
224 break;
225 case AF_IPV60x2:
226 if (!nbr->v6_enabled)
227 /* just ignore the message */
228 return (0);
229 break;
230 default:
231 send_notification(nbr->tcp, S_UNSUP_ADDR0x00000017, msg.id, msg.type);
232 return (-1);
233 }
234 alt_len -= sizeof(alt.family);
235 buf += sizeof(alt);
236 len -= sizeof(alt);
237
238 /* Process all received addresses */
239 while (alt_len > 0) {
240 switch (alt_family) {
241 case AF_IPV40x1:
242 if (alt_len < sizeof(struct in_addr)) {
243 session_shutdown(nbr, S_BAD_TLV_LEN0x80000007, msg.id,
244 msg.type);
245 return (-1);
246 }
247
248 memset(&lde_addr, 0, sizeof(lde_addr));
249 lde_addr.af = AF_INET2;
250 memcpy(&lde_addr.addr, buf, sizeof(struct in_addr));
251
252 buf += sizeof(struct in_addr);
253 len -= sizeof(struct in_addr);
254 alt_len -= sizeof(struct in_addr);
255 break;
256 case AF_IPV60x2:
257 if (alt_len < sizeof(struct in6_addr)) {
258 session_shutdown(nbr, S_BAD_TLV_LEN0x80000007, msg.id,
259 msg.type);
260 return (-1);
261 }
262
263 memset(&lde_addr, 0, sizeof(lde_addr));
264 lde_addr.af = AF_INET624;
265 memcpy(&lde_addr.addr, buf, sizeof(struct in6_addr));
266
267 buf += sizeof(struct in6_addr);
268 len -= sizeof(struct in6_addr);
269 alt_len -= sizeof(struct in6_addr);
270 break;
271 default:
272 fatalx("recv_address: unknown af");
273 }
274
275 log_msg_address(0, msg_type, nbr, lde_addr.af, &lde_addr.addr);
276
277 ldpe_imsg_compose_lde(type, nbr->peerid, 0, &lde_addr,
278 sizeof(lde_addr));
279 }
280
281 /* Optional Parameters */
282 while (len > 0) {
283 struct tlv tlv;
284 uint16_t tlv_type;
285 uint16_t tlv_len;
286
287 if (len < sizeof(tlv)) {
288 session_shutdown(nbr, S_BAD_TLV_LEN0x80000007, msg.id, msg.type);
289 return (-1);
290 }
291
292 memcpy(&tlv, buf, TLV_HDR_SIZE4);
293 tlv_type = ntohs(tlv.type)(__uint16_t)(__builtin_constant_p(tlv.type) ? (__uint16_t)(((
__uint16_t)(tlv.type) & 0xffU) << 8 | ((__uint16_t)
(tlv.type) & 0xff00U) >> 8) : __swap16md(tlv.type))
;
294 tlv_len = ntohs(tlv.length)(__uint16_t)(__builtin_constant_p(tlv.length) ? (__uint16_t)(
((__uint16_t)(tlv.length) & 0xffU) << 8 | ((__uint16_t
)(tlv.length) & 0xff00U) >> 8) : __swap16md(tlv.length
))
;
295 if (tlv_len + TLV_HDR_SIZE4 > len) {
296 session_shutdown(nbr, S_BAD_TLV_LEN0x80000007, msg.id, msg.type);
297 return (-1);
298 }
299 buf += TLV_HDR_SIZE4;
300 len -= TLV_HDR_SIZE4;
301
302 switch (tlv_type) {
303 default:
304 if (!(ntohs(tlv.type)(__uint16_t)(__builtin_constant_p(tlv.type) ? (__uint16_t)(((
__uint16_t)(tlv.type) & 0xffU) << 8 | ((__uint16_t)
(tlv.type) & 0xff00U) >> 8) : __swap16md(tlv.type))
& UNKNOWN_FLAG0x8000))
305 send_notification_rtlvs(nbr, S_UNKNOWN_TLV0x00000006,
306 msg.id, msg.type, tlv_type, tlv_len, buf);
307 /* ignore unknown tlv */
308 break;
309 }
310 buf += tlv_len;
311 len -= tlv_len;
312 }
313
314 return (0);
315}
316
317static int
318gen_address_list_tlv(struct ibuf *buf, int af, struct if_addr_head *addr_list,
319 unsigned int tlv_addr_count)
320{
321 struct address_list_tlv alt;
322 uint16_t addr_size;
323 struct if_addr *if_addr;
324 int err = 0;
325
326 memset(&alt, 0, sizeof(alt));
327 alt.type = htons(TLV_TYPE_ADDRLIST)(__uint16_t)(__builtin_constant_p(0x0101) ? (__uint16_t)(((__uint16_t
)(0x0101) & 0xffU) << 8 | ((__uint16_t)(0x0101) &
0xff00U) >> 8) : __swap16md(0x0101))
;
328
329 switch (af) {
330 case AF_INET2:
331 alt.family = htons(AF_IPV4)(__uint16_t)(__builtin_constant_p(0x1) ? (__uint16_t)(((__uint16_t
)(0x1) & 0xffU) << 8 | ((__uint16_t)(0x1) & 0xff00U
) >> 8) : __swap16md(0x1))
;
332 addr_size = sizeof(struct in_addr);
333 break;
334 case AF_INET624:
335 alt.family = htons(AF_IPV6)(__uint16_t)(__builtin_constant_p(0x2) ? (__uint16_t)(((__uint16_t
)(0x2) & 0xffU) << 8 | ((__uint16_t)(0x2) & 0xff00U
) >> 8) : __swap16md(0x2))
;
336 addr_size = sizeof(struct in6_addr);
337 break;
338 default:
339 fatalx("gen_address_list_tlv: unknown af");
340 }
341 alt.length = htons(sizeof(alt.family) + addr_size * tlv_addr_count)(__uint16_t)(__builtin_constant_p(sizeof(alt.family) + addr_size
* tlv_addr_count) ? (__uint16_t)(((__uint16_t)(sizeof(alt.family
) + addr_size * tlv_addr_count) & 0xffU) << 8 | ((__uint16_t
)(sizeof(alt.family) + addr_size * tlv_addr_count) & 0xff00U
) >> 8) : __swap16md(sizeof(alt.family) + addr_size * tlv_addr_count
))
;
342
343 err |= ibuf_add(buf, &alt, sizeof(alt));
344 if (addr_list == NULL((void *)0))
345 return (err);
346
347 LIST_FOREACH(if_addr, addr_list, entry)for((if_addr) = ((addr_list)->lh_first); (if_addr)!= ((void
*)0); (if_addr) = ((if_addr)->entry.le_next))
{
348 err |= ibuf_add(buf, &if_addr->addr, addr_size);
349 if (--tlv_addr_count == 0)
350 break;
351 }
352
353 return (err);
354}
355
356static int
357gen_mac_list_tlv(struct ibuf *buf, uint8_t *mac)
358{
359 struct tlv tlv;
360 int err;
361
362 memset(&tlv, 0, sizeof(tlv));
363 tlv.type = htons(TLV_TYPE_MAC_LIST)(__uint16_t)(__builtin_constant_p(0x8404) ? (__uint16_t)(((__uint16_t
)(0x8404) & 0xffU) << 8 | ((__uint16_t)(0x8404) &
0xff00U) >> 8) : __swap16md(0x8404))
;
364 if (mac)
365 tlv.length = htons(ETHER_ADDR_LEN)(__uint16_t)(__builtin_constant_p(6) ? (__uint16_t)(((__uint16_t
)(6) & 0xffU) << 8 | ((__uint16_t)(6) & 0xff00U
) >> 8) : __swap16md(6))
;
366 err = ibuf_add(buf, &tlv, sizeof(tlv));
367 if (mac)
368 err |= ibuf_add(buf, mac, ETHER_ADDR_LEN6);
369
370 return (err);
371}
372
373static void
374address_list_add(struct if_addr_head *addr_list, struct if_addr *if_addr)
375{
376 struct if_addr *new;
377
378 new = malloc(sizeof(*new));
379 if (new == NULL((void *)0))
380 fatal(__func__);
381 *new = *if_addr;
382
383 LIST_INSERT_HEAD(addr_list, new, entry)do { if (((new)->entry.le_next = (addr_list)->lh_first)
!= ((void *)0)) (addr_list)->lh_first->entry.le_prev =
&(new)->entry.le_next; (addr_list)->lh_first = (new
); (new)->entry.le_prev = &(addr_list)->lh_first; }
while (0)
;
384}
385
386static void
387address_list_clr(struct if_addr_head *addr_list)
388{
389 struct if_addr *if_addr;
390
391 while ((if_addr = LIST_FIRST(addr_list)((addr_list)->lh_first)) != NULL((void *)0)) {
392 LIST_REMOVE(if_addr, entry)do { if ((if_addr)->entry.le_next != ((void *)0)) (if_addr
)->entry.le_next->entry.le_prev = (if_addr)->entry.le_prev
; *(if_addr)->entry.le_prev = (if_addr)->entry.le_next;
; ; } while (0)
;
393 free(if_addr);
394 }
395}
396
397static void
398log_msg_address(int out, uint16_t msg_type, struct nbr *nbr, int af,
399 union ldpd_addr *addr)
400{
401 log_debug("msg-%s: %s: lsr-id %s, address %s", (out) ? "out" : "in",
402 msg_name(msg_type), inet_ntoa(nbr->id), log_addr(af, addr));
403}
404
405static void
406log_msg_mac_withdrawal(int out, struct nbr *nbr, uint8_t *mac)
407{
408 log_debug("msg-%s: mac withdrawal: lsr-id %s, mac %s",
409 (out) ? "out" : "in", inet_ntoa(nbr->id),
410 (mac) ? ether_ntoa((struct ether_addr *)mac) : "wildcard");
411}