[BACK]Return to name2id.c CVS log [TXT][DIR] Up to [local] / src / usr.sbin / ospf6d

File: [local] / src / usr.sbin / ospf6d / name2id.c (download)

Revision 1.1, Mon Oct 8 10:44:50 2007 UTC (16 years, 7 months ago) by norby
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5, OPENBSD_7_4_BASE, OPENBSD_7_4, OPENBSD_7_3_BASE, OPENBSD_7_3, OPENBSD_7_2_BASE, OPENBSD_7_2, OPENBSD_7_1_BASE, OPENBSD_7_1, OPENBSD_7_0_BASE, OPENBSD_7_0, OPENBSD_6_9_BASE, OPENBSD_6_9, OPENBSD_6_8_BASE, OPENBSD_6_8, OPENBSD_6_7_BASE, OPENBSD_6_7, OPENBSD_6_6_BASE, OPENBSD_6_6, OPENBSD_6_5_BASE, OPENBSD_6_5, OPENBSD_6_4_BASE, OPENBSD_6_4, OPENBSD_6_3_BASE, OPENBSD_6_3, OPENBSD_6_2_BASE, OPENBSD_6_2, OPENBSD_6_1_BASE, OPENBSD_6_1, OPENBSD_6_0_BASE, OPENBSD_6_0, OPENBSD_5_9_BASE, OPENBSD_5_9, OPENBSD_5_8_BASE, OPENBSD_5_8, OPENBSD_5_7_BASE, OPENBSD_5_7, OPENBSD_5_6_BASE, OPENBSD_5_6, OPENBSD_5_5_BASE, OPENBSD_5_5, OPENBSD_5_4_BASE, OPENBSD_5_4, OPENBSD_5_3_BASE, OPENBSD_5_3, OPENBSD_5_2_BASE, OPENBSD_5_2, OPENBSD_5_1_BASE, OPENBSD_5_1, OPENBSD_5_0_BASE, OPENBSD_5_0, OPENBSD_4_9_BASE, OPENBSD_4_9, OPENBSD_4_8_BASE, OPENBSD_4_8, OPENBSD_4_7_BASE, OPENBSD_4_7, OPENBSD_4_6_BASE, OPENBSD_4_6, OPENBSD_4_5_BASE, OPENBSD_4_5, OPENBSD_4_4_BASE, OPENBSD_4_4, OPENBSD_4_3_BASE, OPENBSD_4_3, HEAD

Welcome ospf6d

The new ospf6d daemon will support OSPFv3, basically OSPF for IPv6 networks.

It is heavily based on ospfd(8), it is more or less a copy and paste of it.
Currently some unneeded stuff has been removed and the trasition from
IPv4 to IPv6 has begun.

ospf6d is not very usefull at the moment, it is being imported to allow more
people to work on it concurrently.

Not yet connected to the builds.

ok claudio@ dlg@

/*	$OpenBSD: name2id.c,v 1.1 2007/10/08 10:44:50 norby Exp $ */

/*
 * Copyright (c) 2004, 2005 Henning Brauer <henning@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/types.h>
#include <sys/socket.h>

#include <net/route.h>

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "ospf6d.h"

#define	IDVAL_MAX	50000

u_int16_t	 _name2id(struct n2id_labels *, const char *);
const char	*_id2name(struct n2id_labels *, u_int16_t);
u_int32_t	 _id2tag(struct n2id_labels *, u_int16_t);
u_int16_t	 _tag2id(struct n2id_labels *, u_int32_t);
void		 _tag(struct n2id_labels *, u_int16_t, u_int32_t);
void		 _unref(struct n2id_labels *, u_int16_t);
void		 _ref(struct n2id_labels *, u_int16_t);

struct n2id_labels	rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);

u_int16_t
rtlabel_name2id(const char *name)
{
	return (_name2id(&rt_labels, name));
}

const char *
rtlabel_id2name(u_int16_t id)
{
	return (_id2name(&rt_labels, id));
}

u_int32_t
rtlabel_id2tag(u_int16_t id)
{
	return (_id2tag(&rt_labels, id));
}

u_int16_t
rtlabel_tag2id(u_int32_t tag)
{
	return (_tag2id(&rt_labels, tag));
}

void
rtlabel_tag(u_int16_t id, u_int32_t tag)
{
	_tag(&rt_labels, id, tag);
}

void
rtlabel_unref(u_int16_t id)
{
	_unref(&rt_labels, id);
}

/*
void
rtlabel_ref(u_int16_t id)
{
	_ref(&rt_labels, id);
}
*/

u_int16_t
_name2id(struct n2id_labels *head, const char *name)
{
	struct n2id_label	*label, *p = NULL;
	u_int16_t		 new_id = 1;

	if (!name[0]) {
		errno = EINVAL;
		return (0);
	}

	TAILQ_FOREACH(label, head, entry)
		if (strcmp(name, label->name) == 0) {
			label->ref++;
			return (label->id);
		}

	/*
	 * to avoid fragmentation, we do a linear search from the beginning
	 * and take the first free slot we find. if there is none or the list
	 * is empty, append a new entry at the end.
	 */

	if (!TAILQ_EMPTY(head))
		for (p = TAILQ_FIRST(head); p != NULL &&
		    p->id == new_id; p = TAILQ_NEXT(p, entry))
			new_id = p->id + 1;

	if (new_id > IDVAL_MAX) {
		errno = ERANGE;
		return (0);
	}

	if ((label = calloc(1, sizeof(struct n2id_label))) == NULL)
		return (0);
	if ((label->name = strdup(name)) == NULL) {
		free(label);
		return (0);
	}
	label->id = new_id;
	label->ref++;

	if (p != NULL)	/* insert new entry before p */
		TAILQ_INSERT_BEFORE(p, label, entry);
	else		/* either list empty or no free slot in between */
		TAILQ_INSERT_TAIL(head, label, entry);

	return (label->id);
}

const char *
_id2name(struct n2id_labels *head, u_int16_t id)
{
	struct n2id_label	*label;

	if (id == 0)
		return ("");

	TAILQ_FOREACH(label, head, entry)
		if (label->id == id)
			return (label->name);

	return ("");
}

u_int32_t
_id2tag(struct n2id_labels *head, u_int16_t id)
{
	struct n2id_label	*label;

	if (id == 0)
		return (0);

	TAILQ_FOREACH(label, head, entry)
		if (label->id == id)
			return (label->ext_tag);

	return (0);
}

u_int16_t
_tag2id(struct n2id_labels *head, u_int32_t tag)
{
	struct n2id_label	*label;

	if (tag == 0)
		return (0);

	TAILQ_FOREACH(label, head, entry)
		if (label->ext_tag == tag)
			return (label->id);

	return (0);
}

void
_tag(struct n2id_labels *head, u_int16_t id, u_int32_t tag)
{
	struct n2id_label	*label;

	if (id == 0)
		return;

	TAILQ_FOREACH(label, head, entry)
		if (label->id == id)
			label->ext_tag = tag;
}

void
_unref(struct n2id_labels *head, u_int16_t id)
{
	struct n2id_label	*p, *next;

	if (id == 0)
		return;

	for (p = TAILQ_FIRST(head); p != NULL; p = next) {
		next = TAILQ_NEXT(p, entry);
		if (id == p->id) {
			if (--p->ref == 0) {
				TAILQ_REMOVE(head, p, entry);
				free(p->name);
				free(p);
			}
			break;
		}
	}
}

void
_ref(struct n2id_labels *head, u_int16_t id)
{
	struct n2id_label	*label;

	if (id == 0)
		return;

	TAILQ_FOREACH(label, head, entry)
		if (label->id == id) {
			++label->ref;
			break;
		}
}