GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ospf6d/name2id.c Lines: 0 69 0.0 %
Date: 2017-11-13 Branches: 0 60 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: name2id.c,v 1.1 2007/10/08 10:44:50 norby Exp $ */
2
3
/*
4
 * Copyright (c) 2004, 2005 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 MIND, USE, DATA OR PROFITS, WHETHER IN
15
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/socket.h>
21
22
#include <net/route.h>
23
24
#include <errno.h>
25
#include <stdlib.h>
26
#include <string.h>
27
28
#include "ospf6d.h"
29
30
#define	IDVAL_MAX	50000
31
32
u_int16_t	 _name2id(struct n2id_labels *, const char *);
33
const char	*_id2name(struct n2id_labels *, u_int16_t);
34
u_int32_t	 _id2tag(struct n2id_labels *, u_int16_t);
35
u_int16_t	 _tag2id(struct n2id_labels *, u_int32_t);
36
void		 _tag(struct n2id_labels *, u_int16_t, u_int32_t);
37
void		 _unref(struct n2id_labels *, u_int16_t);
38
void		 _ref(struct n2id_labels *, u_int16_t);
39
40
struct n2id_labels	rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
41
42
u_int16_t
43
rtlabel_name2id(const char *name)
44
{
45
	return (_name2id(&rt_labels, name));
46
}
47
48
const char *
49
rtlabel_id2name(u_int16_t id)
50
{
51
	return (_id2name(&rt_labels, id));
52
}
53
54
u_int32_t
55
rtlabel_id2tag(u_int16_t id)
56
{
57
	return (_id2tag(&rt_labels, id));
58
}
59
60
u_int16_t
61
rtlabel_tag2id(u_int32_t tag)
62
{
63
	return (_tag2id(&rt_labels, tag));
64
}
65
66
void
67
rtlabel_tag(u_int16_t id, u_int32_t tag)
68
{
69
	_tag(&rt_labels, id, tag);
70
}
71
72
void
73
rtlabel_unref(u_int16_t id)
74
{
75
	_unref(&rt_labels, id);
76
}
77
78
/*
79
void
80
rtlabel_ref(u_int16_t id)
81
{
82
	_ref(&rt_labels, id);
83
}
84
*/
85
86
u_int16_t
87
_name2id(struct n2id_labels *head, const char *name)
88
{
89
	struct n2id_label	*label, *p = NULL;
90
	u_int16_t		 new_id = 1;
91
92
	if (!name[0]) {
93
		errno = EINVAL;
94
		return (0);
95
	}
96
97
	TAILQ_FOREACH(label, head, entry)
98
		if (strcmp(name, label->name) == 0) {
99
			label->ref++;
100
			return (label->id);
101
		}
102
103
	/*
104
	 * to avoid fragmentation, we do a linear search from the beginning
105
	 * and take the first free slot we find. if there is none or the list
106
	 * is empty, append a new entry at the end.
107
	 */
108
109
	if (!TAILQ_EMPTY(head))
110
		for (p = TAILQ_FIRST(head); p != NULL &&
111
		    p->id == new_id; p = TAILQ_NEXT(p, entry))
112
			new_id = p->id + 1;
113
114
	if (new_id > IDVAL_MAX) {
115
		errno = ERANGE;
116
		return (0);
117
	}
118
119
	if ((label = calloc(1, sizeof(struct n2id_label))) == NULL)
120
		return (0);
121
	if ((label->name = strdup(name)) == NULL) {
122
		free(label);
123
		return (0);
124
	}
125
	label->id = new_id;
126
	label->ref++;
127
128
	if (p != NULL)	/* insert new entry before p */
129
		TAILQ_INSERT_BEFORE(p, label, entry);
130
	else		/* either list empty or no free slot in between */
131
		TAILQ_INSERT_TAIL(head, label, entry);
132
133
	return (label->id);
134
}
135
136
const char *
137
_id2name(struct n2id_labels *head, u_int16_t id)
138
{
139
	struct n2id_label	*label;
140
141
	if (id == 0)
142
		return ("");
143
144
	TAILQ_FOREACH(label, head, entry)
145
		if (label->id == id)
146
			return (label->name);
147
148
	return ("");
149
}
150
151
u_int32_t
152
_id2tag(struct n2id_labels *head, u_int16_t id)
153
{
154
	struct n2id_label	*label;
155
156
	if (id == 0)
157
		return (0);
158
159
	TAILQ_FOREACH(label, head, entry)
160
		if (label->id == id)
161
			return (label->ext_tag);
162
163
	return (0);
164
}
165
166
u_int16_t
167
_tag2id(struct n2id_labels *head, u_int32_t tag)
168
{
169
	struct n2id_label	*label;
170
171
	if (tag == 0)
172
		return (0);
173
174
	TAILQ_FOREACH(label, head, entry)
175
		if (label->ext_tag == tag)
176
			return (label->id);
177
178
	return (0);
179
}
180
181
void
182
_tag(struct n2id_labels *head, u_int16_t id, u_int32_t tag)
183
{
184
	struct n2id_label	*label;
185
186
	if (id == 0)
187
		return;
188
189
	TAILQ_FOREACH(label, head, entry)
190
		if (label->id == id)
191
			label->ext_tag = tag;
192
}
193
194
void
195
_unref(struct n2id_labels *head, u_int16_t id)
196
{
197
	struct n2id_label	*p, *next;
198
199
	if (id == 0)
200
		return;
201
202
	for (p = TAILQ_FIRST(head); p != NULL; p = next) {
203
		next = TAILQ_NEXT(p, entry);
204
		if (id == p->id) {
205
			if (--p->ref == 0) {
206
				TAILQ_REMOVE(head, p, entry);
207
				free(p->name);
208
				free(p);
209
			}
210
			break;
211
		}
212
	}
213
}
214
215
void
216
_ref(struct n2id_labels *head, u_int16_t id)
217
{
218
	struct n2id_label	*label;
219
220
	if (id == 0)
221
		return;
222
223
	TAILQ_FOREACH(label, head, entry)
224
		if (label->id == id) {
225
			++label->ref;
226
			break;
227
		}
228
}