From 0fceb64d25ff3d9586549bb43d971c5eef904330 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 7 Jun 1999 10:23:42 +0200 Subject: Import ax25-apps 0.0.1 from tarball --- ax25rtd/cache_ctl.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 ax25rtd/cache_ctl.c (limited to 'ax25rtd/cache_ctl.c') diff --git a/ax25rtd/cache_ctl.c b/ax25rtd/cache_ctl.c new file mode 100644 index 0000000..0d892ad --- /dev/null +++ b/ax25rtd/cache_ctl.c @@ -0,0 +1,330 @@ +/* $Id: cache_ctl.c,v 1.4 1996/10/23 18:27:43 jreuter Exp jreuter $ + * + * Copyright (c) 1996 Jörg Reuter (jreuter@poboxes.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include + +#include "ax25rtd.h" + +/* Hmm, we really should implement this in C++ */ +/* But I HATE it. */ + +/* (later: haven't I seen this statement elsewere? hmm...) */ + +int update_ip_route(config *config, unsigned long ip, int ipmode, ax25_address *call, time_t timestamp) +{ + ip_rt_entry *bp = ip_routes; + ip_rt_entry *bp_prev = ip_routes; + char *iface = config->dev; + int action = 0; + + if (((ip ^ config->ip) & config->netmask) != 0) + return 0; + + iface = config->dev; + + while (bp) + { + if (bp->ip == ip) + { + if (bp->timestamp == 0 && timestamp != 0) + return 0; + + if (strcmp(bp->iface, iface)) + { + action |= NEW_ROUTE; + strcpy(bp->iface, iface); + } + + if (memcmp(&bp->call, call, AXLEN)) + { + action |= NEW_ARP; + memcpy(&bp->call, call, AXLEN); + } + + if (ipmode && ipmode != bp->ipmode) + { + action |= NEW_IPMODE; + bp->ipmode = ipmode; + } + + bp->timestamp = timestamp; + + if (bp != ip_routes) + { + if (bp->next) + bp->next->prev = bp->prev; + if (bp->prev) + bp->prev->next = bp->next; + + bp->next = ip_routes; + bp->prev = NULL; + ip_routes->prev = bp; + ip_routes = bp; + } + + return action; + } + + bp_prev = bp; + bp = bp->next; + } + + if (ip_routes_cnt >= ip_maxroutes) + { + if (bp_prev == NULL) /* error */ + return 0; + + bp_prev->prev->next = NULL; + free(bp_prev); + ip_routes_cnt--; + } + + bp = (ip_rt_entry *) malloc(sizeof(ip_rt_entry)); + if (bp == NULL) + return 0; + + ip_routes_cnt++; + action = NEW_ROUTE | NEW_ARP | NEW_IPMODE; + bp->ipmode = ipmode; + bp->ip = ip; + bp->invalid = 0; + + bp->timestamp = timestamp; + strcpy(bp->iface, iface); + memcpy(&bp->call, call, AXLEN); + + if (ip_routes == NULL) + { + ip_routes = bp; + bp->next = bp->prev = NULL; + return action; + } + + bp->next = ip_routes; + bp->prev = NULL; + ip_routes->prev = bp; + ip_routes = bp; + + return action; +} + + +ax25_rt_entry *update_ax25_route(config *config, ax25_address *call, int ndigi, ax25_address *digi, time_t timestamp) +{ + ax25_rt_entry *bp = ax25_routes; + ax25_rt_entry *bp_prev = ax25_routes; + unsigned char *iface = config->dev; + int action = 0; + + while (bp) + { + if (!memcmp(call, &bp->call, AXLEN) && !strcmp(bp->iface, iface)) + { + if (bp->timestamp == 0 && timestamp != 0) + return NULL; + + if (ndigi != bp->ndigi || memcmp(bp->digipeater, digi, bp->ndigi*AXLEN)) + { + action |= NEW_ROUTE; + memcpy(bp->digipeater, digi, ndigi*AXLEN); + bp->ndigi = ndigi; + } + + bp->timestamp = timestamp; + + if (bp != ax25_routes) + { + if (bp->next) + bp->next->prev = bp->prev; + if (bp->prev) + bp->prev->next = bp->next; + + bp->next = ax25_routes; + bp->prev = NULL; + ax25_routes->prev = bp; + ax25_routes = bp; + } + + if (action) + return bp; + else + return NULL; + } + + bp_prev = bp; + bp = bp->next; + } + + if (ax25_routes_cnt >= ax25_maxroutes) + { + if (bp_prev == NULL) /* error */ + return NULL; + + bp_prev->prev->next = NULL; + free(bp_prev); + ax25_routes_cnt--; + } + + bp = (ax25_rt_entry *) malloc(sizeof(ax25_rt_entry)); + if (bp == NULL) + return NULL; + + ax25_routes_cnt++; + + bp->timestamp = timestamp; + strcpy(bp->iface, iface); + bp->call = *call; + + if (ndigi) + memcpy(bp->digipeater, digi, ndigi*AXLEN); + + bp->ndigi = ndigi; + + if (ax25_routes == NULL) + { + ax25_routes = bp; + bp->next = bp->prev = NULL; + return bp; + } + + bp->next = ax25_routes; + bp->prev = NULL; + ax25_routes->prev = bp; + ax25_routes = bp; + + return bp; +} + +ip_rt_entry * remove_ip_route(ip_rt_entry *bp) +{ + ip_rt_entry *bp2; + + bp2 = bp->next; + if (bp2) + bp2->prev = bp->prev; + if (bp->prev) + bp->prev->next = bp2; + if (bp == ip_routes) + ip_routes = bp2; + + del_kernel_ip_route(bp->iface, bp->ip); + + free(bp); + ip_routes_cnt--; + return bp2; +} + +ax25_rt_entry * remove_ax25_route(ax25_rt_entry *bp) +{ + ax25_rt_entry *bp2; + ip_rt_entry *iprt; + + bp2 = bp->next; + if (bp2) + bp2->prev = bp->prev; + if (bp->prev) + bp->prev->next = bp2; + if (bp == ax25_routes) + ax25_routes = bp2; + + for (iprt = ip_routes; iprt; iprt = iprt->next) + if (!memcmp(&iprt->call, &bp->call, AXLEN)) + remove_ip_route(iprt); + + del_kernel_ax25_route(bp->iface, &bp->call); + + free(bp); + ax25_routes_cnt--; + return bp2; +} + +int del_ip_route(unsigned long ip) +{ + ip_rt_entry *bp; + + if (ip == 0) + return 1; + + for (bp=ip_routes; bp; bp = bp->next) + if (bp->ip == ip) + { + remove_ip_route(bp); + return 0; + } + + return 1; +} + +int invalidate_ip_route(unsigned long ip) +{ + ip_rt_entry *bp; + + for (bp=ip_routes; bp; bp = bp->next) + if (bp->ip == ip) + { + bp->invalid = 1; + return 1; + } + + return 0; +} + +int del_ax25_route(config * config, ax25_address *call) +{ + ax25_rt_entry *bp; + + for (bp=ax25_routes; bp; bp = bp->next) + if (!memcmp(call, &bp->call, AXLEN) && !strcmp(config->dev, bp->iface)) + { + remove_ax25_route(bp); + return 0; + } + + return 1; +} + + +void expire_ax25_route(time_t when) +{ + ax25_rt_entry *bp; + time_t now = time(NULL); + + for (bp = ax25_routes; bp; ) + if (bp->timestamp != 0 && bp->timestamp+when <= now) + bp = remove_ax25_route(bp); + else + bp = bp->next; +} + +void expire_ip_route(time_t when) +{ + ip_rt_entry *bp; + time_t now = time(NULL); + + for (bp = ip_routes; bp; ) + if (bp->timestamp != 0 && bp->timestamp+when <= now) + bp = remove_ip_route(bp); + else + bp = bp->next; +} -- cgit v1.2.3