File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / ippool.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 08:44:29 2013 UTC (10 years, 11 months ago) by misho
Branches: mpd, MAIN
CVS tags: v5_8p7, v5_8p1_cross, v5_8p1, v5_8, v5_7p0, v5_7, v5_6, HEAD
5.7

    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>