1/*	$OpenBSD: logmsg.c,v 1.6 2017/03/04 00:15:35 renato Exp $ */
2
3/*
4 * Copyright (c) 2003, 2004 Henning Brauer <henning@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 <sys/socket.h>
21#include <arpa/inet.h>
22#include <netinet/in.h>
23#include <netmpls/mpls.h>
24#include <stdio.h>
25#include <string.h>
26#include <netdb.h>
27
28#include "ldp.h"
29#include "ldpd.h"
30#include "ldpe.h"
31#include "lde.h"
32
33#define NUM_LOGS	4
34const char *
35log_sockaddr(void *vp)
36{
37	static char	 buf[NUM_LOGS][NI_MAXHOST];
38	static int	 round = 0;
39	struct sockaddr	*sa = vp;
40
41	round = (round + 1) % NUM_LOGS;
42
43	if (getnameinfo(sa, sa->sa_len, buf[round], NI_MAXHOST, NULL, 0,
44	    NI_NUMERICHOST))
45		return ("(unknown)");
46	else
47		return (buf[round]);
48}
49
50const char *
51log_in6addr(const struct in6_addr *addr)
52{
53	struct sockaddr_in6	sa_in6;
54
55	memset(&sa_in6, 0, sizeof(sa_in6));
56	sa_in6.sin6_len = sizeof(sa_in6);
57	sa_in6.sin6_family = AF_INET6;
58	sa_in6.sin6_addr = *addr;
59
60	recoverscope(&sa_in6);
61
62	return (log_sockaddr(&sa_in6));
63}
64
65const char *
66log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
67{
68	struct sockaddr_in6	sa_in6;
69
70	memset(&sa_in6, 0, sizeof(sa_in6));
71	sa_in6.sin6_len = sizeof(sa_in6);
72	sa_in6.sin6_family = AF_INET6;
73	sa_in6.sin6_addr = *addr;
74
75	addscope(&sa_in6, ifindex);
76
77	return (log_sockaddr(&sa_in6));
78}
79
80const char *
81log_addr(int af, const union ldpd_addr *addr)
82{
83	static char	 buf[NUM_LOGS][INET6_ADDRSTRLEN];
84	static int	 round = 0;
85
86	switch (af) {
87	case AF_INET:
88		round = (round + 1) % NUM_LOGS;
89		if (inet_ntop(AF_INET, &addr->v4, buf[round],
90		    sizeof(buf[round])) == NULL)
91			return ("???");
92		return (buf[round]);
93	case AF_INET6:
94		return (log_in6addr(&addr->v6));
95	default:
96		break;
97	}
98
99	return ("???");
100}
101
102#define	TF_BUFS	4
103#define	TF_LEN	32
104
105char *
106log_label(uint32_t label)
107{
108	char		*buf;
109	static char	 tfbuf[TF_BUFS][TF_LEN];	/* ring buffer */
110	static int	 idx = 0;
111
112	buf = tfbuf[idx++];
113	if (idx == TF_BUFS)
114		idx = 0;
115
116	switch (label) {
117	case NO_LABEL:
118		snprintf(buf, TF_LEN, "-");
119		break;
120	case MPLS_LABEL_IMPLNULL:
121		snprintf(buf, TF_LEN, "imp-null");
122		break;
123	case MPLS_LABEL_IPV4NULL:
124	case MPLS_LABEL_IPV6NULL:
125		snprintf(buf, TF_LEN, "exp-null");
126		break;
127	default:
128		snprintf(buf, TF_LEN, "%u", label);
129		break;
130	}
131
132	return (buf);
133}
134
135char *
136log_hello_src(const struct hello_source *src)
137{
138	static char buf[64];
139
140	switch (src->type) {
141	case HELLO_LINK:
142		snprintf(buf, sizeof(buf), "iface %s",
143		    src->link.ia->iface->name);
144		break;
145	case HELLO_TARGETED:
146		snprintf(buf, sizeof(buf), "source %s",
147		    log_addr(src->target->af, &src->target->addr));
148		break;
149	}
150
151	return (buf);
152}
153
154const char *
155log_map(const struct map *map)
156{
157	static char	buf[128];
158
159	switch (map->type) {
160	case MAP_TYPE_WILDCARD:
161		if (snprintf(buf, sizeof(buf), "wildcard") < 0)
162			return ("???");
163		break;
164	case MAP_TYPE_PREFIX:
165		if (snprintf(buf, sizeof(buf), "%s/%u",
166		    log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
167		    map->fec.prefix.prefixlen) == -1)
168			return ("???");
169		break;
170	case MAP_TYPE_PWID:
171		if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
172		    map->fec.pwid.pwid, map->fec.pwid.group_id,
173		    pw_type_name(map->fec.pwid.type)) == -1)
174			return ("???");
175		break;
176	case MAP_TYPE_TYPED_WCARD:
177		if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
178			return ("???");
179		switch (map->fec.twcard.type) {
180		case MAP_TYPE_PREFIX:
181			if (snprintf(buf + strlen(buf), sizeof(buf) -
182			    strlen(buf), " (prefix, address-family %s)",
183			    af_name(map->fec.twcard.u.prefix_af)) < 0)
184				return ("???");
185			break;
186		case MAP_TYPE_PWID:
187			if (snprintf(buf + strlen(buf), sizeof(buf) -
188			    strlen(buf), " (pwid, type %s)",
189			    pw_type_name(map->fec.twcard.u.pw_type)) < 0)
190				return ("???");
191			break;
192		default:
193			if (snprintf(buf + strlen(buf), sizeof(buf) -
194			    strlen(buf), " (unknown type)") < 0)
195				return ("???");
196			break;
197		}
198		break;
199	default:
200		return ("???");
201	}
202
203	return (buf);
204}
205
206const char *
207log_fec(const struct fec *fec)
208{
209	static char	buf[64];
210	union ldpd_addr	addr;
211
212	switch (fec->type) {
213	case FEC_TYPE_IPV4:
214		addr.v4 = fec->u.ipv4.prefix;
215		if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
216		    log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
217			return ("???");
218		break;
219	case FEC_TYPE_IPV6:
220		addr.v6 = fec->u.ipv6.prefix;
221		if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
222		    log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
223			return ("???");
224		break;
225	case FEC_TYPE_PWID:
226		if (snprintf(buf, sizeof(buf),
227		    "pwid %u (%s) - %s",
228		    fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
229		    inet_ntoa(fec->u.pwid.lsr_id)) == -1)
230			return ("???");
231		break;
232	default:
233		return ("???");
234	}
235
236	return (buf);
237}
238
239/* names */
240const char *
241af_name(int af)
242{
243	switch (af) {
244	case AF_INET:
245		return ("ipv4");
246	case AF_INET6:
247		return ("ipv6");
248	case AF_MPLS:
249		return ("mpls");
250	default:
251		return ("UNKNOWN");
252	}
253}
254
255const char *
256socket_name(int type)
257{
258	switch (type) {
259	case LDP_SOCKET_DISC:
260		return ("discovery");
261	case LDP_SOCKET_EDISC:
262		return ("extended discovery");
263	case LDP_SOCKET_SESSION:
264		return ("session");
265	default:
266		return ("UNKNOWN");
267	}
268}
269
270const char *
271nbr_state_name(int state)
272{
273	switch (state) {
274	case NBR_STA_PRESENT:
275		return ("PRESENT");
276	case NBR_STA_INITIAL:
277		return ("INITIALIZED");
278	case NBR_STA_OPENREC:
279		return ("OPENREC");
280	case NBR_STA_OPENSENT:
281		return ("OPENSENT");
282	case NBR_STA_OPER:
283		return ("OPERATIONAL");
284	default:
285		return ("UNKNOWN");
286	}
287}
288
289const char *
290if_state_name(int state)
291{
292	switch (state) {
293	case IF_STA_DOWN:
294		return ("DOWN");
295	case IF_STA_ACTIVE:
296		return ("ACTIVE");
297	default:
298		return ("UNKNOWN");
299	}
300}
301
302const char *
303if_type_name(enum iface_type type)
304{
305	switch (type) {
306	case IF_TYPE_POINTOPOINT:
307		return ("POINTOPOINT");
308	case IF_TYPE_BROADCAST:
309		return ("BROADCAST");
310	}
311	/* NOTREACHED */
312	return ("UNKNOWN");
313}
314
315const char *
316msg_name(uint16_t msg)
317{
318	static char buf[16];
319
320	switch (msg) {
321	case MSG_TYPE_NOTIFICATION:
322		return ("notification");
323	case MSG_TYPE_HELLO:
324		return ("hello");
325	case MSG_TYPE_INIT:
326		return ("initialization");
327	case MSG_TYPE_KEEPALIVE:
328		return ("keepalive");
329	case MSG_TYPE_CAPABILITY:
330		return ("capability");
331	case MSG_TYPE_ADDR:
332		return ("address");
333	case MSG_TYPE_ADDRWITHDRAW:
334		return ("address withdraw");
335	case MSG_TYPE_LABELMAPPING:
336		return ("label mapping");
337	case MSG_TYPE_LABELREQUEST:
338		return ("label request");
339	case MSG_TYPE_LABELWITHDRAW:
340		return ("label withdraw");
341	case MSG_TYPE_LABELRELEASE:
342		return ("label release");
343	case MSG_TYPE_LABELABORTREQ:
344	default:
345		snprintf(buf, sizeof(buf), "[%08x]", msg);
346		return (buf);
347	}
348}
349
350const char *
351status_code_name(uint32_t status)
352{
353	static char buf[16];
354
355	switch (status) {
356	case S_SUCCESS:
357		return ("Success");
358	case S_BAD_LDP_ID:
359		return ("Bad LDP Identifier");
360	case S_BAD_PROTO_VER:
361		return ("Bad Protocol Version");
362	case S_BAD_PDU_LEN:
363		return ("Bad PDU Length");
364	case S_UNKNOWN_MSG:
365		return ("Unknown Message Type");
366	case S_BAD_MSG_LEN:
367		return ("Bad Message Length");
368	case S_UNKNOWN_TLV:
369		return ("Unknown TLV");
370	case S_BAD_TLV_LEN:
371		return ("Bad TLV Length");
372	case S_BAD_TLV_VAL:
373		return ("Malformed TLV Value");
374	case S_HOLDTIME_EXP:
375		return ("Hold Timer Expired");
376	case S_SHUTDOWN:
377		return ("Shutdown");
378	case S_LOOP_DETECTED:
379		return ("Loop Detected");
380	case S_UNKNOWN_FEC:
381		return ("Unknown FEC");
382	case S_NO_ROUTE:
383		return ("No Route");
384	case S_NO_LABEL_RES:
385		return ("No Label Resources");
386	case S_AVAILABLE:
387		return ("Label Resources Available");
388	case S_NO_HELLO:
389		return ("Session Rejected, No Hello");
390	case S_PARM_ADV_MODE:
391		return ("Rejected Advertisement Mode Parameter");
392	case S_MAX_PDU_LEN:
393		return ("Rejected Max PDU Length Parameter");
394	case S_PARM_L_RANGE:
395		return ("Rejected Label Range Parameter");
396	case S_KEEPALIVE_TMR:
397		return ("KeepAlive Timer Expired");
398	case S_LAB_REQ_ABRT:
399		return ("Label Request Aborted");
400	case S_MISS_MSG:
401		return ("Missing Message Parameters");
402	case S_UNSUP_ADDR:
403		return ("Unsupported Address Family");
404	case S_KEEPALIVE_BAD:
405		return ("Bad KeepAlive Time");
406	case S_INTERN_ERR:
407		return ("Internal Error");
408	case S_ILLEGAL_CBIT:
409		return ("Illegal C-Bit");
410	case S_WRONG_CBIT:
411		return ("Wrong C-Bit");
412	case S_INCPT_BITRATE:
413		return ("Incompatible bit-rate");
414	case S_CEP_MISCONF:
415		return ("CEP-TDM mis-configuration");
416	case S_PW_STATUS:
417		return ("PW Status");
418	case S_UNASSIGN_TAI:
419		return ("Unassigned/Unrecognized TAI");
420	case S_MISCONF_ERR:
421		return ("Generic Misconfiguration Error");
422	case S_WITHDRAW_MTHD:
423		return ("Label Withdraw PW Status Method");
424	case S_UNSSUPORTDCAP:
425		return ("Unsupported Capability");
426	case S_ENDOFLIB:
427		return ("End-of-LIB");
428	case S_TRANS_MISMTCH:
429		return ("Transport Connection Mismatch");
430	case S_DS_NONCMPLNCE:
431		return ("Dual-Stack Noncompliance");
432	default:
433		snprintf(buf, sizeof(buf), "[%08x]", status);
434		return (buf);
435	}
436}
437
438const char *
439pw_type_name(uint16_t pw_type)
440{
441	static char buf[64];
442
443	switch (pw_type) {
444	case PW_TYPE_ETHERNET_TAGGED:
445		return ("Eth Tagged");
446	case PW_TYPE_ETHERNET:
447		return ("Ethernet");
448	case PW_TYPE_WILDCARD:
449		return ("Wildcard");
450	default:
451		snprintf(buf, sizeof(buf), "[%0x]", pw_type);
452		return (buf);
453	}
454}
455