Annotation of embedaddon/mpd/src/ippool.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 31: static SLIST_HEAD(, ippool) gIPPools;
! 32: static pthread_mutex_t gIPPoolMutex;
1.1 misho 33:
1.1.1.2 ! misho 34: static void IPPoolAdd(const char *pool, struct in_addr begin, struct in_addr end);
! 35: static int IPPoolSetCommand(Context ctx, int ac, const char *const av[], const void *arg);
1.1 misho 36:
37: const struct cmdtab IPPoolSetCmds[] = {
38: { "add {pool} {start} {end}", "Add IP range to the pool",
39: IPPoolSetCommand, NULL, 2, (void *) SET_ADD },
1.1.1.2 ! misho 40: { NULL, NULL, NULL, NULL, 0, NULL },
1.1 misho 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
1.1.1.2 ! misho 108: IPPoolAdd(const char *pool, struct in_addr begin, struct in_addr end)
1.1 misho 109: {
110:
111: IPPool p;
112: struct ippool_rec *r;
113: int i, j, k;
114: int total;
1.1.1.2 ! misho 115: int c = ntohl(end.s_addr) - ntohl(begin.s_addr) + 1;
1.1 misho 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
1.1.1.2 ! misho 165: IPPoolStat(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 166: {
167: IPPool p;
168:
1.1.1.2 ! misho 169: (void)ac;
! 170: (void)av;
! 171: (void)arg;
! 172:
1.1 misho 173: Printf("Available IP pools:\r\n");
174: MUTEX_LOCK(gIPPoolMutex);
175: SLIST_FOREACH(p, &gIPPools, next) {
176: int i;
177: int total = 0;
178: int used = 0;
179: for (i = 0; i < p->size; i++) {
180: if (p->pool[i].ip.s_addr) {
181: total++;
182: if (p->pool[i].used)
183: used++;
184: }
185: }
186: Printf("\t%s:\tused %4d of %4d\r\n", p->name, used, total);
187: }
188: MUTEX_UNLOCK(gIPPoolMutex);
189: return(0);
190: }
191:
192: /*
193: * IPPoolSetCommand()
194: */
195:
196: static int
1.1.1.2 ! misho 197: IPPoolSetCommand(Context ctx, int ac, const char *const av[], const void *arg)
1.1 misho 198: {
1.1.1.2 ! misho 199: (void)ctx;
1.1 misho 200: switch ((intptr_t)arg) {
201: case SET_ADD:
202: {
203: struct u_addr begin;
204: struct u_addr end;
205:
206: /* Parse args */
207: if (ac != 3
208: || !ParseAddr(av[1], &begin, ALLOW_IPV4)
209: || !ParseAddr(av[2], &end, ALLOW_IPV4))
210: return(-1);
211:
212: IPPoolAdd(av[0], begin.u.ip4, end.u.ip4);
213: }
214: break;
215: default:
216: assert(0);
217: }
218: return(0);
219: }
220:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>