2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 #include <utils/debug.h>
26 #include <networking/host.h>
27 #include <utils/identification.h>
28 #include <attributes/attributes.h>
30 #include "pool_attributes.h"
31 #include "pool_usage.h"
34 * global database handle
39 * --start/--end addresses of various subcommands
41 host_t
*start
= NULL
, *end
= NULL
;
44 * whether --add should --replace an existing pool
46 bool replace_pool
= FALSE
;
49 * forward declarations
51 static void del(char *name
);
52 static void do_args(int argc
, char *argv
[]);
55 * nesting counter for database transaction functions
57 int nested_transaction
= 0;
60 * start a database transaction
62 static void begin_transaction()
64 if (db
->get_driver(db
) == DB_SQLITE
)
66 if (!nested_transaction
)
68 db
->execute(db
, NULL
, "BEGIN EXCLUSIVE TRANSACTION");
75 * commit a database transaction
77 static void commit_transaction()
79 if (db
->get_driver(db
) == DB_SQLITE
)
82 if (!nested_transaction
)
84 db
->execute(db
, NULL
, "END TRANSACTION");
90 * Create or replace a pool by name
92 static u_int
create_pool(char *name
, chunk_t start
, chunk_t end
, int timeout
)
97 e
= db
->query(db
, "SELECT id FROM pools WHERE name = ?",
98 DB_TEXT
, name
, DB_UINT
);
99 if (e
&& e
->enumerate(e
, &pool
))
101 if (replace_pool
== FALSE
)
103 fprintf(stderr
, "pool '%s' exists.\n", name
);
110 if (db
->execute(db
, &pool
,
111 "INSERT INTO pools (name, start, end, timeout) VALUES (?, ?, ?, ?)",
112 DB_TEXT
, name
, DB_BLOB
, start
, DB_BLOB
, end
,
113 DB_INT
, timeout
*3600) != 1)
115 fprintf(stderr
, "creating pool failed.\n");
123 * instead of a pool handle a DNS or NBNS attribute
125 static bool is_attribute(char *name
)
127 return strcaseeq(name
, "dns") || strcaseeq(name
, "nbns") ||
128 strcaseeq(name
, "wins");
132 * calculate the size of a pool using start and end address chunk
134 static u_int
get_pool_size(chunk_t start
, chunk_t end
)
136 u_int
*start_ptr
, *end_ptr
;
138 if (start
.len
< sizeof(u_int
) || end
.len
< sizeof(u_int
))
142 start_ptr
= (u_int
*)(start
.ptr
+ start
.len
- sizeof(u_int
));
143 end_ptr
= (u_int
*)(end
.ptr
+ end
.len
- sizeof(u_int
));
144 return ntohl(*end_ptr
) - ntohl(*start_ptr
) + 1;
148 * ipsec pool --status - show pool overview
150 static void status(void)
152 enumerator_t
*ns
, *pool
, *lease
;
157 /* enumerate IPv4 DNS servers */
158 ns
= db
->query(db
, "SELECT value FROM attributes WHERE type = ?",
159 DB_INT
, INTERNAL_IP4_DNS
, DB_BLOB
);
162 while (ns
->enumerate(ns
, &value
))
166 printf("dns servers:");
169 server
= host_create_from_chunk(AF_INET
, value
, 0);
172 printf(" %H", server
);
173 server
->destroy(server
);
179 /* enumerate IPv6 DNS servers */
180 ns
= db
->query(db
, "SELECT value FROM attributes WHERE type = ?",
181 DB_INT
, INTERNAL_IP6_DNS
, DB_BLOB
);
184 while (ns
->enumerate(ns
, &value
))
188 printf("dns servers:");
191 server
= host_create_from_chunk(AF_INET6
, value
, 0);
194 printf(" %H", server
);
195 server
->destroy(server
);
206 printf("no dns servers found.\n");
210 /* enumerate IPv4 NBNS servers */
211 ns
= db
->query(db
, "SELECT value FROM attributes WHERE type = ?",
212 DB_INT
, INTERNAL_IP4_NBNS
, DB_BLOB
);
215 while (ns
->enumerate(ns
, &value
))
219 printf("nbns servers:");
222 server
= host_create_from_chunk(AF_INET
, value
, 0);
225 printf(" %H", server
);
226 server
->destroy(server
);
232 /* enumerate IPv6 NBNS servers */
233 ns
= db
->query(db
, "SELECT value FROM attributes WHERE type = ?",
234 DB_INT
, INTERNAL_IP6_NBNS
, DB_BLOB
);
237 while (ns
->enumerate(ns
, &value
))
241 printf("nbns servers:");
244 server
= host_create_from_chunk(AF_INET6
, value
, 0);
247 printf(" %H", server
);
248 server
->destroy(server
);
259 printf("no nbns servers found.\n");
263 pool
= db
->query(db
, "SELECT id, name, start, end, timeout FROM pools",
264 DB_INT
, DB_TEXT
, DB_BLOB
, DB_BLOB
, DB_UINT
);
268 chunk_t start_chunk
, end_chunk
;
270 u_int id
, timeout
, online
= 0, used
= 0, size
= 0;
272 while (pool
->enumerate(pool
, &id
, &name
,
273 &start_chunk
, &end_chunk
, &timeout
))
277 printf("%8s %15s %15s %8s %6s %11s %11s\n", "name", "start",
278 "end", "timeout", "size", "online", "usage");
282 start
= host_create_from_chunk(AF_UNSPEC
, start_chunk
, 0);
283 end
= host_create_from_chunk(AF_UNSPEC
, end_chunk
, 0);
284 if (start
->is_anyaddr(start
) && end
->is_anyaddr(end
))
286 printf("%8s %15s %15s ", name
, "n/a", "n/a");
290 printf("%8s %15H %15H ", name
, start
, end
);
294 printf("%7dh ", timeout
/3600);
298 printf("%8s ", "static");
300 /* get total number of hosts in the pool */
301 lease
= db
->query(db
, "SELECT COUNT(*) FROM addresses "
302 "WHERE pool = ?", DB_UINT
, id
, DB_INT
);
305 lease
->enumerate(lease
, &size
);
306 lease
->destroy(lease
);
310 printf("%6d %11s %11s ", 0, "n/a", "n/a");
313 printf("%6d ", size
);
314 /* get number of online hosts */
315 lease
= db
->query(db
, "SELECT COUNT(*) FROM addresses "
316 "WHERE pool = ? AND released = 0",
317 DB_UINT
, id
, DB_INT
);
320 lease
->enumerate(lease
, &online
);
321 lease
->destroy(lease
);
323 printf("%5d (%2d%%) ", online
, online
*100/size
);
324 /* get number of online or valid leases */
325 lease
= db
->query(db
, "SELECT COUNT(*) FROM addresses "
326 "WHERE addresses.pool = ? "
327 "AND ((? AND acquired != 0) "
328 " OR released = 0 OR released > ?) ",
329 DB_UINT
, id
, DB_UINT
, !timeout
,
330 DB_UINT
, time(NULL
) - timeout
, DB_UINT
);
333 lease
->enumerate(lease
, &used
);
334 lease
->destroy(lease
);
336 printf("%5d (%2d%%) ", used
, used
*100/size
);
347 printf("no pools found.\n");
352 * ipsec pool --add - add a new pool
354 static void add(char *name
, host_t
*start
, host_t
*end
, int timeout
)
356 chunk_t start_addr
, end_addr
, cur_addr
;
359 start_addr
= start
->get_address(start
);
360 end_addr
= end
->get_address(end
);
361 cur_addr
= chunk_clonea(start_addr
);
362 count
= get_pool_size(start_addr
, end_addr
);
364 if (start_addr
.len
!= end_addr
.len
||
365 memcmp(start_addr
.ptr
, end_addr
.ptr
, start_addr
.len
) > 0)
367 fprintf(stderr
, "invalid start/end pair specified.\n");
370 id
= create_pool(name
, start_addr
, end_addr
, timeout
);
371 printf("allocating %d addresses... ", count
);
373 /* run population in a transaction for sqlite */
377 db
->execute(db
, NULL
,
378 "INSERT INTO addresses (pool, address, identity, acquired, released) "
379 "VALUES (?, ?, ?, ?, ?)",
380 DB_UINT
, id
, DB_BLOB
, cur_addr
, DB_UINT
, 0, DB_UINT
, 0, DB_UINT
, 1);
381 if (chunk_equals(cur_addr
, end_addr
))
385 chunk_increment(cur_addr
);
387 commit_transaction();
391 static bool add_address(u_int pool_id
, char *address_str
, int *family
)
396 char *pos_eq
= strchr(address_str
, '=');
399 identification_t
*id
= identification_create_from_string(pos_eq
+ 1);
400 user_id
= get_identity(id
);
410 address
= host_create_from_string(address_str
, 0);
413 fprintf(stderr
, "invalid address '%s'.\n", address_str
);
416 if (family
&& *family
!= AF_UNSPEC
&&
417 *family
!= address
->get_family(address
))
419 fprintf(stderr
, "invalid address family '%s'.\n", address_str
);
420 address
->destroy(address
);
424 if (db
->execute(db
, NULL
,
425 "INSERT INTO addresses "
426 "(pool, address, identity, acquired, released) "
427 "VALUES (?, ?, ?, ?, ?)",
428 DB_UINT
, pool_id
, DB_BLOB
, address
->get_address(address
),
429 DB_UINT
, user_id
, DB_UINT
, 0, DB_UINT
, 1) != 1)
431 fprintf(stderr
, "inserting address '%s' failed.\n", address_str
);
432 address
->destroy(address
);
437 *family
= address
->get_family(address
);
439 address
->destroy(address
);
444 static void add_addresses(char *pool
, char *path
, int timeout
)
446 u_int pool_id
, count
= 0;
447 int family
= AF_UNSPEC
;
448 char address_str
[512];
452 /* run population in a transaction for sqlite */
455 addr
= host_create_from_string("%any", 0);
456 pool_id
= create_pool(pool
, addr
->get_address(addr
),
457 addr
->get_address(addr
), timeout
);
460 file
= (strcmp(path
, "-") == 0 ? stdin
: fopen(path
, "r"));
463 fprintf(stderr
, "opening '%s' failed: %s\n", path
, strerror(errno
));
467 printf("starting allocation... ");
470 while (fgets(address_str
, sizeof(address_str
), file
))
472 size_t addr_len
= strlen(address_str
);
473 char *last_chr
= address_str
+ addr_len
- 1;
474 if (*last_chr
== '\n')
482 if (add_address(pool_id
, address_str
, &family
) == FALSE
)
498 if (family
== AF_INET6
)
499 { /* update address family if necessary */
500 addr
= host_create_from_string("%any6", 0);
501 if (db
->execute(db
, NULL
,
502 "UPDATE pools SET start = ?, end = ? WHERE id = ?",
503 DB_BLOB
, addr
->get_address(addr
),
504 DB_BLOB
, addr
->get_address(addr
), DB_UINT
, pool_id
) <= 0)
507 fprintf(stderr
, "updating pool address family failed.\n");
513 commit_transaction();
515 printf("%d addresses done.\n", count
);
519 * ipsec pool --del - delete a pool
521 static void del(char *name
)
527 query
= db
->query(db
, "SELECT id FROM pools WHERE name = ?",
528 DB_TEXT
, name
, DB_UINT
);
531 fprintf(stderr
, "deleting pool failed.\n");
534 while (query
->enumerate(query
, &id
))
537 if (db
->execute(db
, NULL
,
538 "DELETE FROM leases WHERE address IN ("
539 " SELECT id FROM addresses WHERE pool = ?)", DB_UINT
, id
) < 0 ||
540 db
->execute(db
, NULL
,
541 "DELETE FROM addresses WHERE pool = ?", DB_UINT
, id
) < 0 ||
542 db
->execute(db
, NULL
,
543 "DELETE FROM pools WHERE id = ?", DB_UINT
, id
) < 0)
545 fprintf(stderr
, "deleting pool failed.\n");
546 query
->destroy(query
);
550 query
->destroy(query
);
553 fprintf(stderr
, "pool '%s' not found.\n", name
);
559 * ipsec pool --resize - resize a pool
561 static void resize(char *name
, host_t
*end
)
564 chunk_t old_addr
, new_addr
, cur_addr
;
568 new_addr
= end
->get_address(end
);
570 query
= db
->query(db
, "SELECT id, end FROM pools WHERE name = ?",
571 DB_TEXT
, name
, DB_UINT
, DB_BLOB
);
572 if (!query
|| !query
->enumerate(query
, &id
, &old_addr
))
575 fprintf(stderr
, "resizing pool failed.\n");
578 if (old_addr
.len
!= new_addr
.len
||
579 memcmp(new_addr
.ptr
, old_addr
.ptr
, old_addr
.len
) < 0)
581 fprintf(stderr
, "shrinking of pools not supported.\n");
582 query
->destroy(query
);
585 cur_addr
= chunk_clonea(old_addr
);
586 count
= get_pool_size(old_addr
, new_addr
) - 1;
587 query
->destroy(query
);
589 /* Check whether pool is resizable */
590 old_end
= host_create_from_chunk(AF_UNSPEC
, old_addr
, 0);
591 if (old_end
&& old_end
->is_anyaddr(old_end
))
593 fprintf(stderr
, "pool is not resizable.\n");
594 old_end
->destroy(old_end
);
599 if (db
->execute(db
, NULL
,
600 "UPDATE pools SET end = ? WHERE name = ?",
601 DB_BLOB
, new_addr
, DB_TEXT
, name
) <= 0)
603 fprintf(stderr
, "pool '%s' not found.\n", name
);
607 printf("allocating %d new addresses... ", count
);
609 /* run population in a transaction for sqlite */
613 chunk_increment(cur_addr
);
614 db
->execute(db
, NULL
,
615 "INSERT INTO addresses (pool, address, identity, acquired, released) "
616 "VALUES (?, ?, ?, ?, ?)",
617 DB_UINT
, id
, DB_BLOB
, cur_addr
, DB_UINT
, 0, DB_UINT
, 0, DB_UINT
, 1);
619 commit_transaction();
625 * create the lease query using the filter string
627 static enumerator_t
*create_lease_query(char *filter
)
630 identification_t
*id
= NULL
;
633 bool online
= FALSE
, valid
= FALSE
, expired
= FALSE
;
634 char *value
, *pos
, *pool
= NULL
;
642 char *const token
[] = {
646 [FIL_TSTAMP
] = "tstamp",
647 [FIL_STATE
] = "status",
651 /* if the filter string contains a distinguished name as a ID, we replace
652 * ", " by "/ " in order to not confuse the getsubopt parser */
654 while ((pos
= strchr(pos
, ',')))
663 while (filter
&& *filter
!= '\0')
665 switch (getsubopt(&filter
, token
, &value
))
676 id
= identification_create_from_string(value
);
682 addr
= host_create_from_string(value
, 0);
686 fprintf(stderr
, "invalid 'addr' in filter string.\n");
693 tstamp
= atoi(value
);
703 if (streq(value
, "online"))
707 else if (streq(value
, "valid"))
711 else if (streq(value
, "expired"))
717 fprintf(stderr
, "invalid 'state' in filter string.\n");
723 fprintf(stderr
, "invalid filter string.\n");
728 query
= db
->query(db
,
729 "SELECT name, addresses.address, identities.type, "
730 "identities.data, leases.acquired, leases.released, timeout "
731 "FROM leases JOIN addresses ON leases.address = addresses.id "
732 "JOIN pools ON addresses.pool = pools.id "
733 "JOIN identities ON leases.identity = identities.id "
734 "WHERE (? OR name = ?) "
735 "AND (? OR (identities.type = ? AND identities.data = ?)) "
736 "AND (? OR addresses.address = ?) "
737 "AND (? OR (? >= leases.acquired AND (? <= leases.released))) "
738 "AND (? OR leases.released > ? - timeout) "
739 "AND (? OR leases.released < ? - timeout) "
742 "SELECT name, address, identities.type, identities.data, "
743 "acquired, released, timeout FROM addresses "
744 "JOIN pools ON addresses.pool = pools.id "
745 "JOIN identities ON addresses.identity = identities.id "
746 "WHERE ? AND released = 0 "
747 "AND (? OR name = ?) "
748 "AND (? OR (identities.type = ? AND identities.data = ?)) "
749 "AND (? OR address = ?)",
750 DB_INT
, pool
== NULL
, DB_TEXT
, pool
,
752 DB_INT
, id ? id
->get_type(id
) : 0,
753 DB_BLOB
, id ? id
->get_encoding(id
) : chunk_empty
,
754 DB_INT
, addr
== NULL
,
755 DB_BLOB
, addr ? addr
->get_address(addr
) : chunk_empty
,
756 DB_INT
, tstamp
== 0, DB_UINT
, tstamp
, DB_UINT
, tstamp
,
757 DB_INT
, !valid
, DB_INT
, time(NULL
),
758 DB_INT
, !expired
, DB_INT
, time(NULL
),
761 DB_INT
, !(valid
|| expired
),
762 DB_INT
, pool
== NULL
, DB_TEXT
, pool
,
764 DB_INT
, id ? id
->get_type(id
) : 0,
765 DB_BLOB
, id ? id
->get_encoding(id
) : chunk_empty
,
766 DB_INT
, addr
== NULL
,
767 DB_BLOB
, addr ? addr
->get_address(addr
) : chunk_empty
,
769 DB_TEXT
, DB_BLOB
, DB_INT
, DB_BLOB
, DB_UINT
, DB_UINT
, DB_UINT
);
770 /* id and addr leak but we can't destroy them until query is destroyed. */
775 * ipsec pool --leases - show lease information of a pool
777 static void leases(char *filter
, bool utc
)
780 chunk_t address_chunk
, identity_chunk
;
783 u_int db_acquired
, db_released
, db_timeout
;
784 time_t acquired
, released
, timeout
;
786 identification_t
*identity
;
789 query
= create_lease_query(filter
);
792 fprintf(stderr
, "querying leases failed.\n");
795 while (query
->enumerate(query
, &name
, &address_chunk
, &identity_type
,
796 &identity_chunk
, &db_acquired
, &db_released
, &db_timeout
))
800 int len
= utc ?
25 : 21;
803 printf("%-8s %-15s %-7s %-*s %-*s %s\n",
804 "name", "address", "status", len
, "start", len
, "end", "identity");
806 address
= host_create_from_chunk(AF_UNSPEC
, address_chunk
, 0);
807 identity
= identification_create_from_encoding(identity_type
, identity_chunk
);
809 /* u_int is not always equal to time_t */
810 acquired
= (time_t)db_acquired
;
811 released
= (time_t)db_released
;
812 timeout
= (time_t)db_timeout
;
814 printf("%-8s %-15H ", name
, address
);
817 printf("%-7s ", "online");
819 else if (timeout
== 0)
821 printf("%-7s ", "static");
823 else if (released
>= time(NULL
) - timeout
)
825 printf("%-7s ", "valid");
829 printf("%-7s ", "expired");
832 printf(" %T ", &acquired
, utc
);
835 printf("%T ", &released
, utc
);
845 printf("%Y\n", identity
);
847 identity
->destroy(identity
);
849 query
->destroy(query
);
852 fprintf(stderr
, "no matching leases found.\n");
858 * ipsec pool --purge - delete expired leases
860 static void purge(char *name
)
864 purged
= db
->execute(db
, NULL
,
865 "DELETE FROM leases WHERE address IN ("
866 " SELECT id FROM addresses WHERE pool IN ("
867 " SELECT id FROM pools WHERE name = ?))",
871 fprintf(stderr
, "purging pool '%s' failed.\n", name
);
874 fprintf(stderr
, "purged %d leases in pool '%s'.\n", purged
, name
);
879 static void argv_add(char **argv
, int argc
, char *value
)
881 if (argc
>= ARGV_SIZE
)
883 fprintf(stderr
, "too many arguments: %s\n", value
);
890 * ipsec pool --batch - read commands from a file
892 static void batch(char *argv0
, char *name
)
896 FILE *file
= strncmp(name
, "-", 1) == 0 ? stdin
: fopen(name
, "r");
899 fprintf(stderr
, "opening '%s' failed: %s\n", name
, strerror(errno
));
904 while (fgets(command
, sizeof(command
), file
))
906 char *argv
[ARGV_SIZE
], *start
;
908 size_t cmd_len
= strlen(command
);
910 /* ignore empty lines */
911 if (cmd_len
== 1 && *(command
+ cmd_len
- 1) == '\n')
916 /* parse command into argv */
918 argv_add(argv
, argc
++, argv0
);
919 for (i
= 0; i
< cmd_len
; ++i
)
921 if (command
[i
] == ' ' || command
[i
] == '\n')
923 if (command
+ i
== start
)
925 /* ignore leading whitespace */
930 argv_add(argv
, argc
++, start
);
931 start
= command
+ i
+ 1;
934 if (strlen(start
) > 0)
936 argv_add(argv
, argc
++, start
);
938 argv_add(argv
, argc
, NULL
);
942 commit_transaction();
951 * atexit handler to close db on shutdown
953 static void cleanup(void)
960 static void do_args(int argc
, char *argv
[])
962 char *name
= "", *value
= "", *filter
= "";
963 char *pool
= NULL
, *identity
= NULL
, *addresses
= NULL
;
964 value_type_t value_type
= VALUE_NONE
;
966 bool utc
= FALSE
, hexout
= FALSE
;
982 } operation
= OP_UNDEF
;
984 /* reinit getopt state */
991 struct option long_opts
[] = {
992 { "help", no_argument
, NULL
, 'h' },
994 { "utc", no_argument
, NULL
, 'u' },
995 { "status", no_argument
, NULL
, 'w' },
996 { "add", required_argument
, NULL
, 'a' },
997 { "replace", required_argument
, NULL
, 'c' },
998 { "del", required_argument
, NULL
, 'd' },
999 { "resize", required_argument
, NULL
, 'r' },
1000 { "leases", no_argument
, NULL
, 'l' },
1001 { "purge", required_argument
, NULL
, 'p' },
1002 { "statusattr", no_argument
, NULL
, '1' },
1003 { "addattr", required_argument
, NULL
, '2' },
1004 { "delattr", required_argument
, NULL
, '3' },
1005 { "showattr", no_argument
, NULL
, '4' },
1006 { "batch", required_argument
, NULL
, 'b' },
1008 { "start", required_argument
, NULL
, 's' },
1009 { "end", required_argument
, NULL
, 'e' },
1010 { "addresses", required_argument
, NULL
, 'y' },
1011 { "timeout", required_argument
, NULL
, 't' },
1012 { "filter", required_argument
, NULL
, 'f' },
1013 { "addr", required_argument
, NULL
, 'v' },
1014 { "mask", required_argument
, NULL
, 'v' },
1015 { "server", required_argument
, NULL
, 'v' },
1016 { "subnet", required_argument
, NULL
, 'n' },
1017 { "string", required_argument
, NULL
, 'g' },
1018 { "hex", required_argument
, NULL
, 'x' },
1019 { "hexout", no_argument
, NULL
, '5' },
1020 { "pool", required_argument
, NULL
, '6' },
1021 { "identity", required_argument
, NULL
, '7' },
1025 c
= getopt_long(argc
, argv
, "", long_opts
, NULL
);
1031 operation
= OP_USAGE
;
1034 operation
= OP_STATUS
;
1037 operation
= OP_STATUS_ATTR
;
1043 replace_pool
= TRUE
;
1047 operation
= is_attribute(name
) ? OP_ADD_ATTR
: OP_ADD
;
1048 if (replace_pool
&& operation
== OP_ADD_ATTR
)
1050 fprintf(stderr
, "invalid pool name: "
1051 "reserved for '%s' attribute.\n", optarg
);
1058 operation
= OP_ADD_ATTR
;
1062 operation
= is_attribute(name
) ? OP_DEL_ATTR
: OP_DEL
;
1066 operation
= OP_DEL_ATTR
;
1069 operation
= OP_SHOW_ATTR
;
1073 operation
= OP_RESIZE
;
1076 operation
= OP_LEASES
;
1080 operation
= OP_PURGE
;
1084 if (operation
== OP_BATCH
)
1086 fprintf(stderr
, "--batch commands can not be nested\n");
1089 operation
= OP_BATCH
;
1093 start
= host_create_from_string(optarg
, 0);
1096 fprintf(stderr
, "invalid start address: '%s'.\n", optarg
);
1103 end
= host_create_from_string(optarg
, 0);
1106 fprintf(stderr
, "invalid end address: '%s'.\n", optarg
);
1112 timeout
= atoi(optarg
);
1113 if (timeout
== 0 && strcmp(optarg
, "0") != 0)
1115 fprintf(stderr
, "invalid timeout '%s'.\n", optarg
);
1127 value_type
= VALUE_STRING
;
1131 value_type
= VALUE_SUBNET
;
1135 value_type
= VALUE_ADDR
;
1139 value_type
= VALUE_HEX
;
1167 case OP_STATUS_ATTR
:
1168 status_attr(hexout
);
1171 if (addresses
!= NULL
)
1173 add_addresses(name
, addresses
, timeout
);
1175 else if (start
!= NULL
&& end
!= NULL
)
1177 add(name
, start
, end
, timeout
);
1181 fprintf(stderr
, "missing arguments.\n");
1187 if (value_type
== VALUE_NONE
)
1189 fprintf(stderr
, "missing arguments.\n");
1193 if (identity
&& !pool
)
1195 fprintf(stderr
, "--identity option can't be used without --pool.\n");
1199 add_attr(name
, pool
, identity
, value
, value_type
);
1205 if (identity
&& !pool
)
1207 fprintf(stderr
, "--identity option can't be used without --pool.\n");
1211 del_attr(name
, pool
, identity
, value
, value_type
);
1219 fprintf(stderr
, "missing arguments.\n");
1226 leases(filter
, utc
);
1234 fprintf(stderr
, "missing arguments.\n");
1238 batch(argv
[0], name
);
1246 int main(int argc
, char *argv
[])
1250 atexit(library_deinit
);
1252 /* initialize library */
1253 if (!library_init(NULL
))
1255 exit(SS_RC_LIBSTRONGSWAN_INTEGRITY
);
1257 if (lib
->integrity
&&
1258 !lib
->integrity
->check_file(lib
->integrity
, "pool", argv
[0]))
1260 fprintf(stderr
, "integrity check of pool failed\n");
1261 exit(SS_RC_DAEMON_INTEGRITY
);
1263 if (!lib
->plugins
->load(lib
->plugins
,
1264 lib
->settings
->get_str(lib
->settings
, "pool.load", PLUGINS
)))
1266 exit(SS_RC_INITIALIZATION_FAILED
);
1269 uri
= lib
->settings
->get_str(lib
->settings
, "libhydra.plugins.attr-sql.database", NULL
);
1272 fprintf(stderr
, "database URI libhydra.plugins.attr-sql.database not set.\n");
1273 exit(SS_RC_INITIALIZATION_FAILED
);
1275 db
= lib
->db
->create(lib
->db
, uri
);
1278 fprintf(stderr
, "opening database failed.\n");
1279 exit(SS_RC_INITIALIZATION_FAILED
);
1283 do_args(argc
, argv
);