aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/netcalc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/netcalc.c')
-rw-r--r--src/netcalc.c478
1 files changed, 344 insertions, 134 deletions
diff --git a/src/netcalc.c b/src/netcalc.c
index e4fa60a..5b5ebda 100644
--- a/src/netcalc.c
+++ b/src/netcalc.c
@@ -100,6 +100,9 @@
100#define NETCALC_IPV6_EXPAND 0x0002 100#define NETCALC_IPV6_EXPAND 0x0002
101#define NETCALC_IPV6_FULL 0x0004 101#define NETCALC_IPV6_FULL 0x0004
102#define NETCALC_NO_MAP 0x0008 102#define NETCALC_NO_MAP 0x0008
103#define NETCALC_VERBOSE 0x0010
104#define NETCALC_LIST 0x0020
105#define NETCALC_SUPERBLOCK 0x0040
103 106
104#define NETCALC_INET 4 107#define NETCALC_INET 4
105#define NETCALC_INET6 6 108#define NETCALC_INET6 6
@@ -116,6 +119,7 @@ typedef struct _netcalc netcalc;
116 119
117struct _netcalc_ip 120struct _netcalc_ip
118{ 121{
122 int32_t cidr;
119 uint32_t addr[8]; 123 uint32_t addr[8];
120}; 124};
121 125
@@ -132,6 +136,11 @@ struct _netcalc
132 size_t count; 136 size_t count;
133 netcalc_ip * lower; 137 netcalc_ip * lower;
134 netcalc_ip * upper; 138 netcalc_ip * upper;
139 netcalc_ip * superblock;
140 netcalc_ip ** list;
141 size_t list_len;
142 int padint;
143 int len_address;
135 int len_netmask; 144 int len_netmask;
136 int len_broadcast; 145 int len_broadcast;
137 int len_network; 146 int len_network;
@@ -156,6 +165,11 @@ netcalc_free(
156 165
157 166
158int 167int
168netcalc_ip_append(
169 netcalc * cnf,
170 netcalc_ip * ip );
171
172int
159netcalc_ip_cmp( 173netcalc_ip_cmp(
160 netcalc_ip * ip1, 174 netcalc_ip * ip1,
161 netcalc_ip * ip2 ); 175 netcalc_ip * ip2 );
@@ -249,6 +263,12 @@ netcalc_net_network_r(
249 int32_t cidr ); 263 int32_t cidr );
250 264
251 265
266int
267netcalc_net_sort_cmp(
268 const void * ap,
269 const void * bp );
270
271
252void 272void
253netcalc_net_wildmask_r( 273netcalc_net_wildmask_r(
254 netcalc_ip * wildmask, 274 netcalc_ip * wildmask,
@@ -260,7 +280,24 @@ netcalc_print_ip(
260 netcalc * cnf, 280 netcalc * cnf,
261 netcalc_ip * ip, 281 netcalc_ip * ip,
262 int32_t cidr, 282 int32_t cidr,
263 int header ); 283 uint64_t opts );
284
285
286void
287netcalc_print_space(
288 netcalc * cnf,
289 netcalc_ip * ip,
290 int32_t cidr );
291
292
293void
294netcalc_results_default(
295 netcalc * cnf );
296
297
298void
299netcalc_results_verbose(
300 netcalc * cnf );
264 301
265 302
266// displays usage 303// displays usage
@@ -292,9 +329,23 @@ char buff[1024];
292 329
293void netcalc_free( netcalc * cnf ) 330void netcalc_free( netcalc * cnf )
294{ 331{
332 size_t pos;
333
295 if (!(cnf)) 334 if (!(cnf))
296 return; 335 return;
297 336
337 for(pos = 0; (pos < cnf->list_len); pos++)
338 {
339 netcalc_ip_free(cnf->list[pos]);
340 cnf->list[pos] = NULL;
341 };
342
343 if (cnf->superblock != NULL)
344 {
345 netcalc_ip_free(cnf->superblock);
346 cnf->superblock = NULL;
347 };
348
298 bzero(cnf, sizeof(netcalc)); 349 bzero(cnf, sizeof(netcalc));
299 free(cnf); 350 free(cnf);
300 351
@@ -313,12 +364,29 @@ int netcalc_init( netcalc ** cnfp )
313 }; 364 };
314 bzero(*cnfp, sizeof(netcalc)); 365 bzero(*cnfp, sizeof(netcalc));
315 366
367 if (((*cnfp)->list = malloc(sizeof(netcalc_ip *))) == NULL)
368 {
369 netcalc_free(*cnfp);
370 fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME);
371 return(1);
372 };
373 (*cnfp)->list[0] = NULL;
374
375 if (((*cnfp)->superblock = malloc(sizeof(netcalc_ip))) == NULL)
376 {
377 netcalc_free(*cnfp);
378 fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME);
379 return(1);
380 };
381 bzero((*cnfp)->superblock, sizeof(netcalc_ip));
382
316 (*cnfp)->cidr = 128; 383 (*cnfp)->cidr = 128;
317 (*cnfp)->cidr_limit = -1; 384 (*cnfp)->cidr_limit = -1;
318 (*cnfp)->cidr_incr = -1; 385 (*cnfp)->cidr_incr = -1;
319 (*cnfp)->family = NETCALC_INET; 386 (*cnfp)->family = NETCALC_INET;
320 (*cnfp)->display = NETCALC_INET; 387 (*cnfp)->display = NETCALC_INET;
321 388
389 (*cnfp)->len_address = strlen("SUPERBLOCK");;
322 (*cnfp)->len_netmask = 7; 390 (*cnfp)->len_netmask = 7;
323 (*cnfp)->len_network = 7; 391 (*cnfp)->len_network = 7;
324 (*cnfp)->len_wildmask = 8; 392 (*cnfp)->len_wildmask = 8;
@@ -328,6 +396,30 @@ int netcalc_init( netcalc ** cnfp )
328} 396}
329 397
330 398
399int netcalc_ip_append( netcalc * cnf, netcalc_ip * ip )
400{
401 size_t size;
402 void * ptr;
403
404 assert(cnf != NULL);
405 assert(ip != NULL);
406
407 size = sizeof(netcalc_ip *) * (cnf->list_len+1);
408
409 if ((ptr = realloc(cnf->list, size)) == NULL)
410 {
411 fprintf(stderr, "%s:%i: out of virtual memory\n", PROGRAM_NAME, __LINE__);
412 return(1);
413 };
414 cnf->list = ptr;
415
416 cnf->list[cnf->list_len] = ip;
417 cnf->list_len++;
418
419 return(0);
420}
421
422
331int netcalc_ip_cmp( netcalc_ip * ip1, netcalc_ip * ip2 ) 423int netcalc_ip_cmp( netcalc_ip * ip1, netcalc_ip * ip2 )
332{ 424{
333 int pos; 425 int pos;
@@ -358,7 +450,6 @@ int netcalc_ip_parse( netcalc * cnf, netcalc_ip ** ipp, const char * ipstr )
358 netcalc_ip * ip; 450 netcalc_ip * ip;
359 char * ptr; 451 char * ptr;
360 char * endptr; 452 char * endptr;
361 int32_t cidr;
362 char * str; 453 char * str;
363 454
364 assert(cnf != NULL); 455 assert(cnf != NULL);
@@ -369,6 +460,7 @@ int netcalc_ip_parse( netcalc * cnf, netcalc_ip ** ipp, const char * ipstr )
369 fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME); 460 fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME);
370 return(1); 461 return(1);
371 }; 462 };
463 ip->cidr = -1;
372 if ((str = strdup(ipstr)) == NULL) 464 if ((str = strdup(ipstr)) == NULL)
373 { 465 {
374 netcalc_ip_free(ip); 466 netcalc_ip_free(ip);
@@ -377,11 +469,10 @@ int netcalc_ip_parse( netcalc * cnf, netcalc_ip ** ipp, const char * ipstr )
377 }; 469 };
378 470
379 // parses CIDR 471 // parses CIDR
380 cidr = -1;
381 if ((ptr = strrchr(str, '/')) != NULL) 472 if ((ptr = strrchr(str, '/')) != NULL)
382 { 473 {
383 ptr[0] = '\0'; 474 ptr[0] = '\0';
384 cidr = (int32_t)strtol(&ptr[1], &endptr, 0); 475 ip->cidr = (int32_t)strtol(&ptr[1], &endptr, 0);
385 if ((endptr[0] != '\0') || (&ptr[1] == endptr)) 476 if ((endptr[0] != '\0') || (&ptr[1] == endptr))
386 { 477 {
387 fprintf(stderr, "%s: invalid CIDR\n", PROGRAM_NAME); 478 fprintf(stderr, "%s: invalid CIDR\n", PROGRAM_NAME);
@@ -394,20 +485,6 @@ int netcalc_ip_parse( netcalc * cnf, netcalc_ip ** ipp, const char * ipstr )
394 // parses string 485 // parses string
395 if ((ptr = strchr(str, ':')) == NULL) 486 if ((ptr = strchr(str, ':')) == NULL)
396 { 487 {
397 // verifies cidr
398 if ((cidr < -1) || (cidr > 32))
399 {
400 fprintf(stderr, "%s: invalid CIDR\n", PROGRAM_NAME);
401 netcalc_ip_free(ip);
402 free(str);
403 return(1);
404 };
405
406 // normalizes CIDR for IPv6
407 if (cidr >= 0)
408 cidr += 128 - 32;
409
410 // parse string
411 if ((rc = netcalc_ip_parse_ipv4(cnf, ip, str)) != 0) 488 if ((rc = netcalc_ip_parse_ipv4(cnf, ip, str)) != 0)
412 { 489 {
413 netcalc_ip_free(ip); 490 netcalc_ip_free(ip);
@@ -415,16 +492,6 @@ int netcalc_ip_parse( netcalc * cnf, netcalc_ip ** ipp, const char * ipstr )
415 return(1); 492 return(1);
416 }; 493 };
417 } else { 494 } else {
418 // verifies cidr
419 if ((cidr < -1) || (cidr > 128))
420 {
421 fprintf(stderr, "%s: invalid CIDR\n", PROGRAM_NAME);
422 netcalc_ip_free(ip);
423 free(str);
424 return(1);
425 };
426
427 // parses string
428 if ((rc = netcalc_ip_parse_ipv6(cnf, ip, str)) != 0) 495 if ((rc = netcalc_ip_parse_ipv6(cnf, ip, str)) != 0)
429 { 496 {
430 netcalc_ip_free(ip); 497 netcalc_ip_free(ip);
@@ -434,8 +501,10 @@ int netcalc_ip_parse( netcalc * cnf, netcalc_ip ** ipp, const char * ipstr )
434 }; 501 };
435 502
436 // normalizes CIDR 503 // normalizes CIDR
437 if ((cnf->cidr > cidr) && (cidr != -1)) 504 if (ip->cidr == -1)
438 cnf->cidr = cidr; 505 ip->cidr = 128;
506 if ((cnf->cidr > ip->cidr) && (ip->cidr != -1))
507 cnf->cidr = ip->cidr;
439 508
440 // frees resources 509 // frees resources
441 free(str); 510 free(str);
@@ -451,6 +520,18 @@ int netcalc_ip_parse_ipv4( netcalc * cnf, netcalc_ip * ip, char * str )
451 assert(cnf != NULL); 520 assert(cnf != NULL);
452 assert(ip != NULL); 521 assert(ip != NULL);
453 522
523 // verifies cidr
524 if ((ip->cidr < -1) || (ip->cidr > 32))
525 {
526 fprintf(stderr, "%s: invalid CIDR\n", PROGRAM_NAME);
527 return(1);
528 };
529
530 // normalizes CIDR for IPv6
531 if (ip->cidr >= 0)
532 ip->cidr += 128 - 32;
533
534 // sets prefix for IPv6 mapped IPv4 addresses
454 ip->addr[5] = 0xffff; 535 ip->addr[5] = 0xffff;
455 536
456 // parses IPv4 string 537 // parses IPv4 string
@@ -522,6 +603,13 @@ int netcalc_ip_parse_ipv6( netcalc * cnf, netcalc_ip * ip, char * str)
522 603
523 cnf->family = NETCALC_INET6; 604 cnf->family = NETCALC_INET6;
524 605
606 // verifies cidr
607 if ((ip->cidr < -1) || (ip->cidr > 128))
608 {
609 fprintf(stderr, "%s: invalid CIDR\n", PROGRAM_NAME);
610 return(1);
611 };
612
525 // verifies zero compression 613 // verifies zero compression
526 compress = 0; 614 compress = 0;
527 for(pos = 1; (pos < (int)strlen(str)); pos++) 615 for(pos = 1; (pos < (int)strlen(str)); pos++)
@@ -793,10 +881,40 @@ void netcalc_net_network_r( netcalc_ip * network, netcalc_ip * ip, int32_t cidr
793 netcalc_net_netmask_r(&netmask, cidr); 881 netcalc_net_netmask_r(&netmask, cidr);
794 for(pos = 0; (pos < 8); pos++) 882 for(pos = 0; (pos < 8); pos++)
795 network->addr[pos] = ip->addr[pos] & netmask.addr[pos]; 883 network->addr[pos] = ip->addr[pos] & netmask.addr[pos];
884 network->cidr = cidr;
796 return; 885 return;
797} 886}
798 887
799 888
889int netcalc_net_sort_cmp( const void * ap, const void * bp )
890{
891 int i;
892 const netcalc_ip * a;
893 const netcalc_ip * b;
894
895 assert( ap != NULL );
896 assert( bp != NULL );
897 a = *(const netcalc_ip * const *) ap;
898 b = *(const netcalc_ip * const *) bp;
899
900 for(i = 0; ( (i < 7) && (a->addr[i] == b->addr[i]) ); i++);
901
902 if ( a->addr[i] < b->addr[i] )
903 return(-1);
904
905 if ( a->addr[i] > b->addr[i] )
906 return(1);
907
908 if ( a->cidr < b->cidr )
909 return(-1);
910
911 if ( a->cidr > b->cidr )
912 return(1);
913
914 return(0);
915}
916
917
800void netcalc_net_wildmask_r( netcalc_ip * wildmask, int32_t cidr ) 918void netcalc_net_wildmask_r( netcalc_ip * wildmask, int32_t cidr )
801{ 919{
802 int32_t pos; 920 int32_t pos;
@@ -807,37 +925,51 @@ void netcalc_net_wildmask_r( netcalc_ip * wildmask, int32_t cidr )
807} 925}
808 926
809 927
810void netcalc_print_ip( netcalc * cnf, netcalc_ip * ip, int32_t cidr, int header ) 928void netcalc_print_ip( netcalc * cnf, netcalc_ip * ip, int32_t cidr, uint64_t opts )
811{ 929{
812 int pos; 930 int pos;
813 netcalc_ip netmask; 931 netcalc_ip netmask;
814 netcalc_ip broadcast; 932 netcalc_ip broadcast;
815 netcalc_ip network; 933 netcalc_ip network;
816 netcalc_ip wildmask; 934 netcalc_ip wildmask;
935 char str_address[56];
817 char str_netmask[56]; 936 char str_netmask[56];
818 char str_broadcast[56]; 937 char str_broadcast[56];
819 char str_network[56]; 938 char str_network[56];
820 char str_wildmask[56]; 939 char str_wildmask[56];
821 char str_subnets[128]; 940 char str_subnets[128];
941 char str_ip[56];
822 uint64_t count; 942 uint64_t count;
823 943
944 opts |= cnf->opts;
945
824 if ((ip)) 946 if ((ip))
825 { 947 {
826 netcalc_net_netmask_r( &netmask, cidr ); 948 netcalc_net_netmask_r( &netmask, cidr );
827 netcalc_net_wildmask_r( &wildmask, cidr ); 949 netcalc_net_wildmask_r( &wildmask, cidr );
828 netcalc_net_network_r( &network, ip, cidr ); 950 netcalc_net_network_r( &network, ip, cidr );
829 netcalc_net_broadcast_r( &broadcast, ip, cidr ); 951 netcalc_net_broadcast_r( &broadcast, ip, cidr );
952 netcalc_ip_string( cnf, ip, str_ip, sizeof(str_ip) );
830 netcalc_ip_string( cnf, &netmask, str_netmask, sizeof(str_netmask) ); 953 netcalc_ip_string( cnf, &netmask, str_netmask, sizeof(str_netmask) );
831 netcalc_ip_string( cnf, &wildmask, str_wildmask, sizeof(str_wildmask) ); 954 netcalc_ip_string( cnf, &wildmask, str_wildmask, sizeof(str_wildmask) );
832 netcalc_ip_string( cnf, &network, str_network, sizeof(str_network) ); 955 netcalc_ip_string( cnf, &network, str_network, sizeof(str_network) );
833 netcalc_ip_string( cnf, &broadcast, str_broadcast, sizeof(str_broadcast) ); 956 netcalc_ip_string( cnf, &broadcast, str_broadcast, sizeof(str_broadcast) );
957 if ((opts & NETCALC_SUPERBLOCK))
958 {
959 snprintf(str_address, sizeof(str_address), "SUPERBLOCK");
960 } else {
961 if (cnf->display == NETCALC_INET6)
962 snprintf(str_address, sizeof(str_address), "%s/%i", str_ip, ip->cidr);
963 else
964 snprintf(str_address, sizeof(str_address), "%s/%i", str_ip, ip->cidr+32-128);
965 };
834 }; 966 };
835 967
836 // network count 968 // network count
837 if (cnf->cidr_incr >= cnf->cidr) 969 if (cnf->cidr_incr >= cidr)
838 { 970 {
839 count = 1; 971 count = 1;
840 for(pos = 0; (pos < (cnf->cidr_incr - cnf->cidr)); pos++) 972 for(pos = 0; (pos < (cnf->cidr_incr - cidr)); pos++)
841 count *= 2; 973 count *= 2;
842 } else { 974 } else {
843 count = 0; 975 count = 0;
@@ -846,75 +978,166 @@ void netcalc_print_ip( netcalc * cnf, netcalc_ip * ip, int32_t cidr, int header
846 // print IPv4 information 978 // print IPv4 information
847 if (cnf->display == NETCALC_INET) 979 if (cnf->display == NETCALC_INET)
848 { 980 {
849 if ((header)) 981 if (!(ip))
850 { 982 {
851 snprintf(str_subnets, sizeof(str_subnets), "/%" PRIu32 "s", (cnf->cidr_incr + 32 - 128)); 983 snprintf(str_subnets, sizeof(str_subnets), "/%" PRIu32 "s", (cnf->cidr_incr + 32 - 128));
852 // prints field names 984 // prints field names
853 printf("%-15s", "Network"); 985 if ((cnf->opts & NETCALC_VERBOSE))
854 printf(" %-15s", "Broadcast"); 986 printf( "%-15s ", "Address");
855 printf(" %-15s", "Netmask"); 987 printf( "%-15s ", "Network");
856 printf(" %-15s", "Wildcard"); 988 printf( "%-15s ", "Broadcast");
857 printf(" %-4s", "CIDR"); 989 printf( "%-15s ", "Netmask");
858 printf(" %s", str_subnets); 990 printf( "%-15s ", "Wildcard");
859 printf("\n"); 991 printf( "%-4s ", "CIDR");
992 printf( "%s", str_subnets);
993 printf( "\n");
860 return; 994 return;
861 }; 995 };
862 printf("%-15s", str_network); 996 if ((cnf->opts & NETCALC_VERBOSE))
863 printf(" %-15s", str_broadcast); 997 printf( "%-15s ", str_address );
864 printf(" %-15s", str_netmask); 998 printf( "%-15s ", str_network );
865 printf(" %-15s", str_wildmask); 999 printf( "%-15s ", str_broadcast );
866 printf(" %-4i", cidr + 32 - 128); 1000 printf( "%-15s ", str_netmask );
867 printf(" %" PRIu64, count); 1001 printf( "%-15s ", str_wildmask );
868 printf("\n"); 1002 printf( "%-4i ", cidr + 32 - 128 );
1003 if ((cnf->cidr_incr >= cidr) && ((cnf->cidr_incr - cidr) < 64))
1004 printf("%" PRIu64 " ", count);
1005 else
1006 printf("n/a ");
1007 printf( "\n" );
869 return; 1008 return;
870 }; 1009 };
871 1010
872 cnf->len_netmask = (cnf->len_netmask < (int)strlen(str_netmask)) ? (int)strlen(str_netmask) : cnf->len_netmask;
873 cnf->len_network = (cnf->len_network < (int)strlen(str_network)) ? (int)strlen(str_network) : cnf->len_network;
874 cnf->len_wildmask = (cnf->len_wildmask < (int)strlen(str_wildmask)) ? (int)strlen(str_wildmask) : cnf->len_wildmask;
875 cnf->len_broadcast = (cnf->len_broadcast < (int)strlen(str_broadcast)) ? (int)strlen(str_broadcast) : cnf->len_broadcast;
876
877 // print IPv6 information 1011 // print IPv6 information
878 if ((header)) 1012 if (!(ip))
879 { 1013 {
880 snprintf(str_subnets, sizeof(str_subnets), "/%" PRIu32 "s", cnf->cidr_incr); 1014 snprintf(str_subnets, sizeof(str_subnets), "/%" PRIu32 "s", cnf->cidr_incr);
881 // prints field names 1015 // prints field names
882 printf("%-*s", cnf->len_network, "Network"); 1016 if ((cnf->opts & NETCALC_VERBOSE))
883 printf(" %-*s", cnf->len_broadcast, "Broadcast"); 1017 printf( "%-*s ", cnf->len_address, "Address" );
884 printf(" %-*s", cnf->len_netmask, "Netmask"); 1018 printf( "%-*s ", cnf->len_network, "Network" );
885 printf(" %-*s", cnf->len_wildmask, "Wildcard"); 1019 printf( "%-*s ", cnf->len_broadcast, "Broadcast" );
886 printf(" %-4s", "CIDR"); 1020 printf( "%-*s ", cnf->len_netmask, "Netmask" );
887 printf(" %s", str_subnets); 1021 printf( "%-*s ", cnf->len_wildmask, "Wildcard" );
888 printf("\n"); 1022 printf( "%-4s ", "CIDR" );
1023 printf( "%s", str_subnets );
1024 printf( "\n");
889 return; 1025 return;
890 }; 1026 };
891 printf("%-*s", cnf->len_network, str_network); 1027 if ((cnf->opts & NETCALC_VERBOSE))
892 printf(" %-*s", cnf->len_broadcast, str_broadcast); 1028 printf( "%-*s ", cnf->len_address, str_address);
893 printf(" %-*s", cnf->len_netmask, str_netmask); 1029 printf( "%-*s ", cnf->len_network, str_network);
894 printf(" %-*s", cnf->len_wildmask, str_wildmask); 1030 printf( "%-*s ", cnf->len_broadcast, str_broadcast);
895 printf(" %-4i", cidr); 1031 printf( "%-*s ", cnf->len_netmask, str_netmask);
896 if ((cnf->cidr_incr >= cnf->cidr) && ((cnf->cidr_incr - cnf->cidr) < 64)) 1032 printf( "%-*s ", cnf->len_wildmask, str_wildmask);
897 printf(" %" PRIu64, count); 1033 printf( "%-4i ", cidr);
1034 if ((cnf->cidr_incr >= cidr) && ((cnf->cidr_incr - cidr) < 64))
1035 printf("%" PRIu64 " ", count);
898 else 1036 else
899 printf(" n/a"); 1037 printf("n/a ");
900 printf("\n"); 1038 printf("\n");
901 1039
902 return; 1040 return;
903} 1041}
904 1042
905 1043
1044void netcalc_print_space( netcalc * cnf, netcalc_ip * ip, int32_t cidr )
1045{
1046 netcalc_ip netmask;
1047 netcalc_ip broadcast;
1048 netcalc_ip network;
1049 netcalc_ip wildmask;
1050 char str_address[56];
1051 char str_netmask[56];
1052 char str_broadcast[56];
1053 char str_network[56];
1054 char str_wildmask[56];
1055 char str_cidr[5];
1056 int len_address;
1057
1058 netcalc_net_netmask_r( &netmask, cidr );
1059 netcalc_net_wildmask_r( &wildmask, cidr );
1060 netcalc_net_network_r( &network, ip, cidr );
1061 netcalc_net_broadcast_r( &broadcast, ip, cidr );
1062
1063 netcalc_ip_string( cnf, ip, str_address, sizeof(str_address) );
1064 netcalc_ip_string( cnf, &netmask, str_netmask, sizeof(str_netmask) );
1065 netcalc_ip_string( cnf, &wildmask, str_wildmask, sizeof(str_wildmask) );
1066 netcalc_ip_string( cnf, &network, str_network, sizeof(str_network) );
1067 netcalc_ip_string( cnf, &broadcast, str_broadcast, sizeof(str_broadcast) );
1068
1069 len_address = (int)strlen(str_address);
1070 if (cnf->display == NETCALC_INET6)
1071 len_address += snprintf(str_cidr, sizeof(str_cidr), "/%i", ip->cidr);
1072 else
1073 len_address += snprintf(str_cidr, sizeof(str_cidr), "/%i", ip->cidr + 32 - 128);
1074
1075 cnf->len_address = (cnf->len_address < len_address) ? len_address : cnf->len_address;
1076 cnf->len_netmask = (cnf->len_netmask < (int)strlen(str_netmask)) ? (int)strlen(str_netmask) : cnf->len_netmask;
1077 cnf->len_network = (cnf->len_network < (int)strlen(str_network)) ? (int)strlen(str_network) : cnf->len_network;
1078 cnf->len_wildmask = (cnf->len_wildmask < (int)strlen(str_wildmask)) ? (int)strlen(str_wildmask) : cnf->len_wildmask;
1079 cnf->len_broadcast = (cnf->len_broadcast < (int)strlen(str_broadcast)) ? (int)strlen(str_broadcast) : cnf->len_broadcast;
1080
1081 return;
1082}
1083
1084
1085void netcalc_results_default( netcalc * cnf )
1086{
1087 int32_t cidr;
1088 int32_t cidr_floor;
1089
1090 cidr_floor = (cnf->family == NETCALC_INET6) ? 0 : 128-32;
1091
1092 // calculate spacing
1093 netcalc_print_space(cnf, cnf->superblock, cnf->cidr);
1094 if ((cnf->opts & NETCALC_ALL_NETWORKS))
1095 for(cidr = cnf->cidr; (cidr > cidr_floor); cidr--)
1096 netcalc_print_space(cnf, cnf->lower, cidr);
1097
1098 // print data
1099 netcalc_print_ip(cnf, NULL, cnf->cidr, 0);
1100 netcalc_print_ip(cnf, cnf->superblock, cnf->cidr, 0);
1101 if ((cnf->opts & NETCALC_ALL_NETWORKS))
1102 for(cidr = cnf->cidr; (cidr > cidr_floor); cidr--)
1103 netcalc_print_ip(cnf, cnf->lower, cidr-1, 0);
1104
1105 return;
1106}
1107
1108
1109void netcalc_results_verbose( netcalc * cnf )
1110{
1111 size_t pos;
1112
1113 // calculate spacing
1114 netcalc_print_space(cnf, cnf->superblock, cnf->cidr);
1115 for(pos = 0; (pos < cnf->list_len); pos++)
1116 netcalc_print_space(cnf, cnf->list[pos], cnf->list[pos]->cidr);
1117
1118 // print data
1119 netcalc_print_ip(cnf, NULL, cnf->cidr, 0);
1120 netcalc_print_ip(cnf, cnf->superblock, cnf->cidr, NETCALC_SUPERBLOCK);
1121 for(pos = 0; (pos < cnf->list_len); pos++)
1122 netcalc_print_ip(cnf, cnf->list[pos], cnf->list[pos]->cidr, 0);
1123
1124 return;
1125}
1126
1127
906/// displays usage 1128/// displays usage
907void netcalc_usage(void) 1129void netcalc_usage(void)
908{ 1130{
909 printf("Usage: %s [OPTIONS] address1 address2 ... addressN\n", PROGRAM_NAME); 1131 printf("Usage: %s [OPTIONS] address1 address2 ... addressN\n", PROGRAM_NAME);
910 printf(" -a display all matching networks\n"); 1132 printf(" -a display all inclusive networks (incompatible with -v)\n");
911 printf(" -c cidr requested network size in CIDR notation\n"); 1133 printf(" -c cidr requested network size in CIDR notation\n");
912 printf(" -f print full IPv6 notation (do not compress zeros)\n"); 1134 printf(" -f print full IPv6 notation (do not compress zeros)\n");
913 printf(" -h, --help print this help and exit\n"); 1135 printf(" -h, --help print this help and exit\n");
914 printf(" -i cidr increment size of network list\n"); 1136 printf(" -i cidr increment size of network list\n");
915 printf(" -m do not display IPv4 mapped addresses\n"); 1137 printf(" -m do not display IPv4 mapped addresses\n");
916 printf(" -V, --version print version number and exit\n"); 1138 printf(" -V, --version print version number and exit\n");
917 printf(" -x print IPv6 expanded notation (print leading zeros)\n"); 1139 printf(" -v, --verbose display all input networks (incompatible with -a)\n");
1140 printf(" -x print IPv6 expanded notation (print leading zeros)\n");
918 printf("\n"); 1141 printf("\n");
919 printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT); 1142 printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
920 return; 1143 return;
@@ -944,8 +1167,9 @@ int main(int argc, char * argv[])
944 int opt_index; 1167 int opt_index;
945 netcalc * cnf; 1168 netcalc * cnf;
946 netcalc_ip * ip; 1169 netcalc_ip * ip;
1170 size_t pos;
947 1171
948 static char short_opt[] = "6ac:fhi:mVx"; 1172 static char short_opt[] = "6ac:fhi:mVvx";
949 static struct option long_opt[] = 1173 static struct option long_opt[] =
950 { 1174 {
951 {"help", no_argument, 0, 'h'}, 1175 {"help", no_argument, 0, 'h'},
@@ -969,9 +1193,9 @@ int main(int argc, char * argv[])
969 break; 1193 break;
970 1194
971 case 'a': 1195 case 'a':
972 cnf->opts |= NETCALC_ALL_NETWORKS; 1196 cnf->opts |= NETCALC_ALL_NETWORKS;
973 cnf->len_wildmask = 39; 1197 cnf->opts &= ~NETCALC_LIST;
974 cnf->len_broadcast = 39; 1198 cnf->opts &= ~NETCALC_VERBOSE;
975 break; 1199 break;
976 1200
977 case 'c': 1201 case 'c':
@@ -1002,6 +1226,12 @@ int main(int argc, char * argv[])
1002 }; 1226 };
1003 break; 1227 break;
1004 1228
1229 case 'l':
1230 cnf->opts &= ~NETCALC_ALL_NETWORKS;
1231 cnf->opts |= NETCALC_LIST;
1232 cnf->opts &= ~NETCALC_VERBOSE;
1233 break;
1234
1005 case 'm': 1235 case 'm':
1006 cnf->opts |= NETCALC_NO_MAP; 1236 cnf->opts |= NETCALC_NO_MAP;
1007 break; 1237 break;
@@ -1010,6 +1240,12 @@ int main(int argc, char * argv[])
1010 netcalc_version(); 1240 netcalc_version();
1011 return(0); 1241 return(0);
1012 1242
1243 case 'v':
1244 cnf->opts &= ~NETCALC_ALL_NETWORKS;
1245 cnf->opts &= ~NETCALC_LIST;
1246 cnf->opts |= NETCALC_VERBOSE;
1247 break;
1248
1013 case 'x': 1249 case 'x':
1014 cnf->opts |= NETCALC_IPV6_EXPAND; 1250 cnf->opts |= NETCALC_IPV6_EXPAND;
1015 cnf->opts |= NETCALC_IPV6_FULL; 1251 cnf->opts |= NETCALC_IPV6_FULL;
@@ -1042,40 +1278,25 @@ int main(int argc, char * argv[])
1042 return(1); 1278 return(1);
1043 }; 1279 };
1044 1280
1045 // initialize bounds 1281 if ((rc = netcalc_ip_append(cnf, ip)) != 0)
1046 if (!(cnf->lower))
1047 { 1282 {
1048 if ((cnf->lower = malloc(sizeof(netcalc_ip))) == NULL) 1283 netcalc_ip_free(ip);
1049 { 1284 netcalc_free(cnf);
1050 fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME); 1285 return(1);
1051 netcalc_ip_free(ip);
1052 netcalc_free(cnf);
1053 return(1);
1054 };
1055 memcpy(cnf->lower, ip, sizeof(netcalc_ip));
1056 };
1057 if (!(cnf->upper))
1058 {
1059 if ((cnf->upper = malloc(sizeof(netcalc_ip))) == NULL)
1060 {
1061 fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME);
1062 netcalc_ip_free(ip);
1063 netcalc_free(cnf);
1064 return(1);
1065 };
1066 memcpy(cnf->upper, ip, sizeof(netcalc_ip));
1067 }; 1286 };
1287 };
1288 qsort(cnf->list, cnf->list_len, sizeof(netcalc_ip *), netcalc_net_sort_cmp);
1068 1289
1069 // updates bounds 1290 // initialize bounds
1070 if (netcalc_ip_cmp(ip, cnf->lower) < 0) 1291 cnf->lower = cnf->list[0];
1292 cnf->upper = cnf->list[0];
1293 for(pos = 0; (pos < cnf->list_len); pos++)
1294 {
1295 if (netcalc_ip_cmp(cnf->list[pos], cnf->lower) < 0)
1071 { 1296 {
1072 netcalc_ip_free(cnf->lower); 1297 cnf->lower = cnf->list[pos];
1073 cnf->lower = ip; 1298 } else if (netcalc_ip_cmp(cnf->list[pos], cnf->upper) > 0) {
1074 } else if (netcalc_ip_cmp(ip, cnf->upper) > 0) { 1299 cnf->upper = cnf->list[pos];
1075 netcalc_ip_free(cnf->upper);
1076 cnf->upper = ip;
1077 } else {
1078 netcalc_ip_free(ip);
1079 }; 1300 };
1080 }; 1301 };
1081 1302
@@ -1091,33 +1312,22 @@ int main(int argc, char * argv[])
1091 cnf->cidr_incr = (cnf->cidr_incr == -1) ? 64 : cnf->cidr_incr; 1312 cnf->cidr_incr = (cnf->cidr_incr == -1) ? 64 : cnf->cidr_incr;
1092 cnf->cidr = (cnf->cidr < cnf->cidr_limit) ? cnf->cidr : cnf->cidr_limit; 1313 cnf->cidr = (cnf->cidr < cnf->cidr_limit) ? cnf->cidr : cnf->cidr_limit;
1093 }; 1314 };
1315 if ((cnf->opts & NETCALC_ALL_NETWORKS))
1316 {
1317 cnf->len_wildmask = 39;
1318 cnf->len_broadcast = 39;
1319 };
1094 1320
1095 // calculate inclusive CIDR 1321 // calculate inclusive CIDR
1096 while ((rc = netcalc_net_cmp(cnf->lower, cnf->upper, cnf->cidr)) != 0) 1322 while ((rc = netcalc_net_cmp(cnf->lower, cnf->upper, cnf->cidr)) != 0)
1097 cnf->cidr--; 1323 cnf->cidr--;
1324 netcalc_net_network_r(cnf->superblock, cnf->lower, cnf->cidr);
1098 1325
1099 // print header 1326 // display results
1100 netcalc_print_ip(cnf, cnf->lower, cnf->cidr, 1); 1327 if ((cnf->opts & NETCALC_VERBOSE))
1101 netcalc_print_ip(cnf, cnf->lower, cnf->cidr, 0); 1328 netcalc_results_verbose(cnf);
1102 1329 else
1103 // print all matching subnets 1330 netcalc_results_default(cnf);
1104 if ((cnf->opts & NETCALC_ALL_NETWORKS))
1105 {
1106 if (cnf->family == NETCALC_INET6)
1107 {
1108 while(cnf->cidr > 0)
1109 {
1110 cnf->cidr--;
1111 netcalc_print_ip(cnf, cnf->lower, cnf->cidr, 0);
1112 };
1113 } else {
1114 while(cnf->cidr > (128-32))
1115 {
1116 cnf->cidr--;
1117 netcalc_print_ip(cnf, cnf->lower, cnf->cidr, 0);
1118 };
1119 };
1120 };
1121 1331
1122 return(0); 1332 return(0);
1123} 1333}