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>