l2tpns/ll.c
fred_nerk b43583c01d * Fri Mar 5 2004 David Parrish <david@dparrish.com> 1.1.0
- Change all strcpy() calls to strncpy() to avoid buffer overflow potential
- Add ICMP host unreachable support
- Logging to syslog if log_file = "syslog:facility"
- Now requires libcli 1.5
- All configuration moves to a config structure
- Ability to modify and write config on the fly through command-line interface
- Config file support is removed, and now handled by the cli
- Show hostname in cli prompt
- Keep current state type for tunnels
- Add uptime command do CLI, which also shows real-time bandwidth utilisation
- Add goodbye command to cluster master, which forces droppping a slave
- Cache IP address allocation, so that reconnecting users get the same address
- Fix tunnel resend timeouts, so that dead tunnels will be cleaned up
- Allocate tunnels and radius without using a linked list which had issues
- Fix some off-by-one errors in tunnel and session and radius arrays
- Save and reload ip address pool when dieing
- Check version and size of reloaded data when restarting
- Remove plugin_config support
- Remove old support for TBF which didn't work anyway. HTB is required to do throttling now.
- Add COPYING and Changes files
2004-03-05 00:09:03 +00:00

141 lines
2.1 KiB
C

// L2TPNS Linked List Stuff
// $Id: ll.c,v 1.2 2004/03/05 00:09:03 fred_nerk Exp $
#include <stdio.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include "ll.h"
linked_list *ll_init()
{
return (linked_list *)calloc(sizeof(linked_list), 1);
}
void ll_done(linked_list *l)
{
li *i = l->head, *n;
while (i)
{
n = i->next;
free(i);
i = n;
}
free(l);
}
li *ll_push(linked_list *l, void *data)
{
li *i;
if (!l) return NULL;
if (!(i = (li *)calloc(sizeof(li), 1))) return NULL;
i->data = data;
i->next = NULL;
if (l->end)
l->end->next = i;
else
l->head = i;
l->end = i;
return i;
}
void *ll_pop(linked_list *l)
{
li *i;
void *data;
if (!l) return NULL;
if (!l->head)
return NULL;
data = l->head->data;
i = l->head->next;
free(l->head);
l->head = i;
return data;
}
void ll_iterate(linked_list *l, int(*func)(void *))
{
li *i;
if (!l || !func) return;
for (i = l->head; i; i = i->next)
{
if (i->data)
if (!func(i))
break;
}
}
void ll_reset(linked_list *l)
{
if (!l) return;
l->current = NULL;
}
void *ll_next(linked_list *l)
{
if (!l) return NULL;
if (!l->current)
l->current = l->head;
else
l->current = l->current->next;
if (!l->current)
return NULL;
return l->current->data;
}
void ll_delete(linked_list *l, void *data)
{
li *i = l->head, *p = NULL;
while (i)
{
if (i->data == data)
{
if (l->head == i) l->head = i->next;
if (l->end == i) l->end = i->next;
if (p) p->next = i->next;
free(i);
l->current = NULL;
return;
}
p = i;
i = i->next;
}
}
int ll_size(linked_list *l)
{
int count = 0;
li *i;
if (!l) return 0;
for (i = l->head; i; i = i->next)
if (i->data) count++;
return count;
}
int ll_contains(linked_list *l, void *search)
{
li *i;
for (i = l->head; i; i = i->next)
if (i->data == search)
return 1;
return 0;
}