1
0
Files
2022-09-29 17:59:04 +03:00

363 lines
7.0 KiB
C++

/*
* Copyright 1991-1992 Silicon Graphics, Inc. All rights reserved.
*
* Database classes
*
* $Revision: 1.6 $
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include "cf.h"
#include "db.h"
extern "C" {
#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
#include <macros.h>
}
/*
* Index operations for PhysAddr class
*/
static unsigned int
pahash(PhysAddr *p, int)
{
char *a = p->getAddr();
return (a[2] << 24) | (a[3] << 16) | (a[4] << 8) | a[5];
}
static int
pacmp(PhysAddr *p1, PhysAddr *p2, int)
{
return !(*p1 == *p2);
}
static indexops paops = { (unsigned int (*)()) pahash, (int (*)()) pacmp, 0 };
/*
* Index operations for IPAddr class
*/
static unsigned int
iphash(IPAddr *i, int)
{
struct in_addr *a = i->getAddr();
return a->s_addr;
}
static int
ipcmp(IPAddr *i1, IPAddr *i2, int)
{
return !(*i1 == *i2);
}
static indexops ipops = { (unsigned int (*)()) iphash, (int (*)()) ipcmp, 0 };
/*
* Index operations for DNAddr class
*/
static unsigned int
dnhash(DNAddr *d, int)
{
dn_addr *a = d->getAddr();
return (int) a;
}
static int
dncmp(DNAddr *d1, DNAddr *d2, int)
{
return !(*d1 == *d2);
}
static indexops dnops = { (unsigned int (*)()) dnhash, (int (*)()) dncmp, 0 };
/*
* InterfaceDB class
*/
InterfaceDB::InterfaceDB(void)
{
paindex = 0;
ipindex = 0;
dnindex = 0;
}
InterfaceDB::InterfaceDB(CfNode *c)
{
paindex = 0;
ipindex = 0;
dnindex = 0;
create(c);
}
InterfaceDB::~InterfaceDB(void)
{
destroy();
}
void
InterfaceDB::create(CfNode *root)
{
NetworkNode *n;
SegmentNode *s;
InterfaceNode *i;
unsigned int pa, ip, dn;
const float HashFill = 1.2;
const int MinHashSize = 1024;
// Count the types of addresses to allocate a good-sized hash table
pa = ip = dn = 0;
for (n = (NetworkNode *) root->child; n != 0; n = (NetworkNode *) n->next) {
for (s = (SegmentNode *) n->child;
s != 0; s = (SegmentNode *) s->next) {
for (i = (InterfaceNode *) s->child;
i != 0; i = (InterfaceNode *) i->next) {
if (i->physaddr.isValid())
pa++;
if (i->ipaddr.isValid())
ip++;
if (i->dnaddr.isValid())
dn++;
}
}
}
pa = (int) (pa * HashFill);
pa = MIN(pa, MinHashSize);
if (paindex != 0)
in_destroy(paindex);
paindex = index(pa, sizeof(PhysAddr), &paops);
ip = (int) (ip * HashFill);
ip = MIN(ip, MinHashSize);
if (ipindex != 0)
in_destroy(ipindex);
ipindex = index(ip, sizeof(IPAddr), &ipops);
dn = (int) (dn * HashFill);
dn = MIN(dn, MinHashSize);
if (dnindex != 0)
in_destroy(dnindex);
dnindex = index(dn, sizeof(DNAddr), &dnops);
for (n = (NetworkNode *) root->child; n != 0; n = (NetworkNode *) n->next) {
for (s = (SegmentNode *) n->child;
s != 0; s = (SegmentNode *) s->next) {
for (i = (InterfaceNode *) s->child;
i != 0; i = (InterfaceNode *) i->next)
enter(i);
}
}
}
void
InterfaceDB::destroy(void)
{
if (paindex != 0) {
in_destroy(paindex);
paindex = 0;
}
if (ipindex != 0) {
in_destroy(ipindex);
ipindex = 0;
}
if (dnindex != 0) {
in_destroy(dnindex);
dnindex = 0;
}
}
void
InterfaceDB::enter(InterfaceNode *i)
{
if (i->physaddr.isValid())
(void) in_enterqual(paindex, &i->physaddr, i, (long) i->parent->parent);
if (i->ipaddr.isValid())
(void) in_enter(ipindex, &i->ipaddr, i);
if (i->dnaddr.isValid())
(void) in_enter(dnindex, &i->dnaddr, i);
}
void
InterfaceDB::remove(InterfaceNode *i)
{
if (i->physaddr.isValid())
in_removequal(paindex, &i->physaddr, (long) i->parent->parent);
if (i->ipaddr.isValid())
in_remove(ipindex, &i->ipaddr);
if (i->dnaddr.isValid())
in_remove(dnindex, &i->dnaddr);
}
/*
* SegmentDB class
*/
SegmentDB::SegmentDB(void)
{
ipindex = 0;
dnindex = 0;
}
SegmentDB::SegmentDB(CfNode *c)
{
ipindex = 0;
dnindex = 0;
create(c);
}
SegmentDB::~SegmentDB(void)
{
destroy();
}
void
SegmentDB::create(CfNode *root)
{
NetworkNode *n;
SegmentNode *s;
unsigned int ip, dn;
const float HashFill = 1.2;
const int MinHashSize = 256;
// Count the types of segments to allocate a good-sized hash table
ip = dn = 0;
for (n = (NetworkNode *) root->child; n != 0; n = (NetworkNode *) n->next) {
for (s = (SegmentNode *) n->child;
s != 0; s = (SegmentNode *) s->next) {
if (s->ipnum.isValid())
ip++;
if (s->dnarea.isValid())
dn++;
}
}
ip = (int) (ip * HashFill);
ip = MIN(ip, MinHashSize);
if (ipindex != 0)
in_destroy(ipindex);
ipindex = index(ip, sizeof(IPNetNum), &ipops);
dn = (int) (dn * HashFill);
dn = MIN(dn, MinHashSize);
if (dnindex != 0)
in_destroy(dnindex);
dnindex = index(dn, sizeof(DNAddr), &dnops);
for (n = (NetworkNode *) root->child; n != 0; n = (NetworkNode *) n->next) {
for (s = (SegmentNode *) n->child;
s != 0; s = (SegmentNode *) s->next)
enter(s);
}
}
void
SegmentDB::destroy(void)
{
if (ipindex != 0) {
in_destroy(ipindex);
ipindex = 0;
}
if (dnindex != 0) {
in_destroy(dnindex);
dnindex = 0;
}
}
void
SegmentDB::enter(SegmentNode *s)
{
if (s->ipnum.isValid())
in_enter(ipindex, &s->ipnum, s);
if (s->dnarea.isValid())
in_enter(dnindex, &s->dnarea, s);
}
void
SegmentDB::remove(SegmentNode *s)
{
if (s->ipnum.isValid())
in_remove(ipindex, &s->ipnum);
if (s->dnarea.isValid())
in_remove(dnindex, &s->dnarea);
}
/*
* NetworkDB class
*/
NetworkDB::NetworkDB(void)
{
ipindex = 0;
}
NetworkDB::NetworkDB(CfNode *c)
{
ipindex = 0;
create(c);
}
NetworkDB::~NetworkDB(void)
{
destroy();
}
void
NetworkDB::create(CfNode *root)
{
NetworkNode *n;
unsigned int ip;
const float HashFill = 1.2;
const int MinHashSize = 128;
// Count the types of segments to allocate a good-sized hash table
ip = 0;
for (n = (NetworkNode *) root->child; n != 0; n = (NetworkNode *) n->next) {
if (n->ipnum.isValid())
ip++;
}
ip = (int) (ip * HashFill);
ip = MIN(ip, MinHashSize);
if (ipindex != 0)
in_destroy(ipindex);
ipindex = index(ip, sizeof(IPNetNum), &ipops);
for (n = (NetworkNode *) root->child; n != 0; n = (NetworkNode *) n->next)
enter(n);
}
void
NetworkDB::destroy(void)
{
if (ipindex != 0)
in_destroy(ipindex);
}
void
NetworkDB::enter(NetworkNode *n)
{
if (n->ipnum.isValid())
in_enter(ipindex, &n->ipnum, n);
}
void
NetworkDB::remove(NetworkNode *n)
{
if (n->ipnum.isValid())
in_remove(ipindex, &n->ipnum);
}