1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
2024-07-22 01:58:46 -03:00

141 lines
2.8 KiB
C
Executable File

/* itf.c - IP interface registry */
/* Written 1995-1999 by Werner Almesberger, EPFL-LRC/ICA */
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <linux/atmclip.h>
#include <sys/socket.h>
#define _LINUX_NETDEVICE_H /* glibc2 */
#include <linux/if_arp.h>
#include "atmd.h"
#include "table.h"
#include "io.h"
#include "itf.h"
#include "arp.h"
#define COMPONENT "ITF"
ITF *lookup_itf(int number)
{
ITF *itf;
for (itf = itfs; itf; itf = itf->next)
if (itf->number == number) break;
return itf;
}
ITF *lookup_itf_by_ip(uint32_t ip)
{
ITF *itf;
for (itf = itfs; itf; itf = itf->next)
if (!((itf->local_ip ^ ip) & itf->netmask)) break;
return itf;
}
void itf_create(int number)
{
diag(COMPONENT,DIAG_DEBUG,"ITF CREATE %d",number);
}
void itf_up(int number)
{
ITF *itf;
diag(COMPONENT,DIAG_DEBUG,"ITF UP %d",number);
if (lookup_itf(number)) {
diag(COMPONENT,DIAG_ERROR,"interface is already active");
return;
}
itf = alloc_t(ITF);
if (ip_itf_info(number,&itf->local_ip,&itf->netmask,&itf->mtu) < 0) {
free(itf);
return;
}
itf->number = number;
memset(&itf->qos,0,sizeof(struct atm_qos));
itf->qos.aal = ATM_AAL5;
itf->qos.txtp.traffic_class = ATM_UBR;
itf->qos.txtp.max_sdu = RFC1483LLC_LEN+RFC1626_MTU;
itf->qos.rxtp = itf->qos.txtp;
itf->sndbuf = 0; /* use system default */
itf->table = itf->arp_srv = NULL;
Q_INSERT_HEAD(itfs,itf);
}
static void itf_bring_down(ITF *itf)
{
ENTRY *entry,*next;
for (entry = itf->table; entry; entry = next) {
next = entry->next;
discard_entry(entry);
}
Q_REMOVE(itfs,itf);
free(itf);
}
void itf_down(int number)
{
ITF *itf;
diag(COMPONENT,DIAG_DEBUG,"ITF DOWN %d",number);
itf = lookup_itf(number);
if (!itf) {
diag(COMPONENT,DIAG_ERROR,"no such interface (%d)",number);
return;
}
itf_bring_down(itf);
}
void itf_change(int number)
{
ITF *itf;
ENTRY *entry,*next,*disconnected;
uint32_t local_ip,netmask;
int mtu;
diag(COMPONENT,DIAG_DEBUG,"ITF CHANGE %d",number);
itf = lookup_itf(number);
if (!itf) {
diag(COMPONENT,DIAG_DEBUG,"no interface to change (%d)",number);
return;
}
if (ip_itf_info(number,&local_ip,&netmask,&mtu) < 0) {
itf_bring_down(itf);
return;
}
disconnected = NULL;
for (entry = itf->table; entry; entry = next) {
next = entry->next;
if ((entry->flags & ATF_PERM) &&
!((entry->ip ^ local_ip) & (netmask | itf->netmask))) continue;
if ((entry->flags & ATF_ARPSRV) && !((entry->ip ^ local_ip) & netmask))
{
disconnected = entry;
discard_vccs(entry);
/* @@@ should adjust max_sdu if mtu changed */
continue;
}
discard_entry(entry);
}
itf->local_ip = local_ip;
itf->netmask = netmask;
itf->mtu = mtu;
if (disconnected) vcc_detach(disconnected);
}