Annotation of embedaddon/mpd/src/ippool.c, revision 1.1.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>