Annotation of embedaddon/mpd/src/ippool.c, revision 1.1
1.1 ! misho 1:
! 2: /*
! 3: * ippool.c
! 4: *
! 5: * Written by Alexander Motin <mav@FreeBSD.org>
! 6: */
! 7:
! 8: #include "ppp.h"
! 9: #include "ip.h"
! 10: #include "ippool.h"
! 11: #include "util.h"
! 12:
! 13: enum {
! 14: SET_ADD
! 15: };
! 16:
! 17: struct ippool_rec {
! 18: struct in_addr ip;
! 19: int used;
! 20: };
! 21:
! 22: struct ippool {
! 23: char name[LINK_MAX_NAME];
! 24: struct ippool_rec *pool;
! 25: int size;
! 26: SLIST_ENTRY(ippool) next;
! 27: };
! 28:
! 29: typedef struct ippool *IPPool;
! 30:
! 31: SLIST_HEAD(, ippool) gIPPools;
! 32: pthread_mutex_t gIPPoolMutex;
! 33:
! 34: static void IPPoolAdd(char *pool, struct in_addr begin, struct in_addr end);
! 35: static int IPPoolSetCommand(Context ctx, int ac, char *av[], void *arg);
! 36:
! 37: const struct cmdtab IPPoolSetCmds[] = {
! 38: { "add {pool} {start} {end}", "Add IP range to the pool",
! 39: IPPoolSetCommand, NULL, 2, (void *) SET_ADD },
! 40: { NULL },
! 41: };
! 42:
! 43: void
! 44: IPPoolInit(void)
! 45: {
! 46: int ret = pthread_mutex_init (&gIPPoolMutex, NULL);
! 47: if (ret != 0) {
! 48: Log(LG_ERR, ("Could not create IP pool mutex: %d", ret));
! 49: exit(EX_UNAVAILABLE);
! 50: }
! 51: SLIST_INIT(&gIPPools);
! 52: }
! 53:
! 54: int IPPoolGet(char *pool, struct u_addr *ip)
! 55: {
! 56: IPPool p;
! 57: int i;
! 58:
! 59: MUTEX_LOCK(gIPPoolMutex);
! 60: SLIST_FOREACH(p, &gIPPools, next) {
! 61: if (strcmp(p->name, pool) == 0)
! 62: break;
! 63: }
! 64: if (!p) {
! 65: MUTEX_UNLOCK(gIPPoolMutex);
! 66: return (-1);
! 67: }
! 68: i = 0;
! 69: while (i < p->size) {
! 70: if (!p->pool[i].used) {
! 71: p->pool[i].used = 1;
! 72: in_addrtou_addr(&p->pool[i].ip, ip);
! 73: MUTEX_UNLOCK(gIPPoolMutex);
! 74: return (0);
! 75: }
! 76: i++;
! 77: }
! 78: MUTEX_UNLOCK(gIPPoolMutex);
! 79: return (-1);
! 80: }
! 81:
! 82: void IPPoolFree(char *pool, struct u_addr *ip) {
! 83: IPPool p;
! 84: int i;
! 85:
! 86: MUTEX_LOCK(gIPPoolMutex);
! 87: SLIST_FOREACH(p, &gIPPools, next) {
! 88: if (strcmp(p->name, pool) == 0)
! 89: break;
! 90: }
! 91: if (!p) {
! 92: MUTEX_UNLOCK(gIPPoolMutex);
! 93: return;
! 94: }
! 95: i = 0;
! 96: while (i < p->size) {
! 97: if (p->pool[i].ip.s_addr == ip->u.ip4.s_addr) {
! 98: p->pool[i].used = 0;
! 99: MUTEX_UNLOCK(gIPPoolMutex);
! 100: return;
! 101: }
! 102: i++;
! 103: }
! 104: MUTEX_UNLOCK(gIPPoolMutex);
! 105: }
! 106:
! 107: static void
! 108: IPPoolAdd(char *pool, struct in_addr begin, struct in_addr end)
! 109: {
! 110:
! 111: IPPool p;
! 112: struct ippool_rec *r;
! 113: int i, j, k;
! 114: int total;
! 115: u_int c = ntohl(end.s_addr) - ntohl(begin.s_addr) + 1;
! 116:
! 117: if (c > 65536) {
! 118: Log(LG_ERR, ("Too big IP range: %d", c));
! 119: return;
! 120: }
! 121:
! 122: MUTEX_LOCK(gIPPoolMutex);
! 123: SLIST_FOREACH(p, &gIPPools, next) {
! 124: if (strcmp(p->name, pool) == 0)
! 125: break;
! 126: }
! 127:
! 128: if (!p) {
! 129: p = Malloc(MB_IPPOOL, sizeof(struct ippool));
! 130: strlcpy(p->name, pool, sizeof(p->name));
! 131: SLIST_INSERT_HEAD(&gIPPools, p, next);
! 132: }
! 133: total = 0;
! 134: for (i = 0; i < p->size; i++) {
! 135: if (p->pool[i].ip.s_addr)
! 136: total++;
! 137: }
! 138: r = Malloc(MB_IPPOOL, (total + c) * sizeof(struct ippool_rec));
! 139: if (p->pool != NULL) {
! 140: memcpy(r, p->pool, p->size * sizeof(struct ippool_rec));
! 141: Freee(p->pool);
! 142: }
! 143: p->pool = r;
! 144: k = p->size;
! 145: for (i = 0; i < c; i++) {
! 146: struct in_addr ip;
! 147: ip.s_addr = htonl(ntohl(begin.s_addr) + i);
! 148: for (j = 0; j < p->size; j++) {
! 149: if (p->pool[j].ip.s_addr == ip.s_addr)
! 150: break;
! 151: }
! 152: if (j != p->size)
! 153: continue;
! 154: p->pool[k++].ip = ip;
! 155: }
! 156: p->size = k;
! 157: MUTEX_UNLOCK(gIPPoolMutex);
! 158: }
! 159:
! 160: /*
! 161: * IPPoolStat()
! 162: */
! 163:
! 164: int
! 165: IPPoolStat(Context ctx, int ac, char *av[], void *arg)
! 166: {
! 167: IPPool p;
! 168:
! 169: Printf("Available IP pools:\r\n");
! 170: MUTEX_LOCK(gIPPoolMutex);
! 171: SLIST_FOREACH(p, &gIPPools, next) {
! 172: int i;
! 173: int total = 0;
! 174: int used = 0;
! 175: for (i = 0; i < p->size; i++) {
! 176: if (p->pool[i].ip.s_addr) {
! 177: total++;
! 178: if (p->pool[i].used)
! 179: used++;
! 180: }
! 181: }
! 182: Printf("\t%s:\tused %4d of %4d\r\n", p->name, used, total);
! 183: }
! 184: MUTEX_UNLOCK(gIPPoolMutex);
! 185: return(0);
! 186: }
! 187:
! 188: /*
! 189: * IPPoolSetCommand()
! 190: */
! 191:
! 192: static int
! 193: IPPoolSetCommand(Context ctx, int ac, char *av[], void *arg)
! 194: {
! 195: switch ((intptr_t)arg) {
! 196: case SET_ADD:
! 197: {
! 198: struct u_addr begin;
! 199: struct u_addr end;
! 200:
! 201: /* Parse args */
! 202: if (ac != 3
! 203: || !ParseAddr(av[1], &begin, ALLOW_IPV4)
! 204: || !ParseAddr(av[2], &end, ALLOW_IPV4))
! 205: return(-1);
! 206:
! 207: IPPoolAdd(av[0], begin.u.ip4, end.u.ip4);
! 208: }
! 209: break;
! 210: default:
! 211: assert(0);
! 212: }
! 213: return(0);
! 214: }
! 215:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>