diff options
| author | David M. Syzdek <david@syzdek.net> | 2021-10-06 16:10:01 -0800 |
|---|---|---|
| committer | David M. Syzdek <david@syzdek.net> | 2021-10-06 16:11:53 -0800 |
| commit | 92f3ec647146f6413052af3ce49bb35dccf40710 (patch) | |
| tree | 6b557ea284f7cfc568c580013b4d77678e8b5dc4 /src | |
| parent | e03768df3eea22c8690cb56fd240776e85a86883 (diff) | |
| download | dmstools-92f3ec647146f6413052af3ce49bb35dccf40710.tar.gz dmstools-92f3ec647146f6413052af3ce49bb35dccf40710.tar.bz2 dmstools-92f3ec647146f6413052af3ce49bb35dccf40710.tar.xz dmstools-92f3ec647146f6413052af3ce49bb35dccf40710.zip | |
netcalc: adding verbose mode
Diffstat (limited to 'src')
| -rw-r--r-- | src/netcalc.c | 478 |
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 | ||
| 117 | struct _netcalc_ip | 120 | struct _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 | ||
| 158 | int | 167 | int |
| 168 | netcalc_ip_append( | ||
| 169 | netcalc * cnf, | ||
| 170 | netcalc_ip * ip ); | ||
| 171 | |||
| 172 | int | ||
| 159 | netcalc_ip_cmp( | 173 | netcalc_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 | ||
| 266 | int | ||
| 267 | netcalc_net_sort_cmp( | ||
| 268 | const void * ap, | ||
| 269 | const void * bp ); | ||
| 270 | |||
| 271 | |||
| 252 | void | 272 | void |
| 253 | netcalc_net_wildmask_r( | 273 | netcalc_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 | |||
| 286 | void | ||
| 287 | netcalc_print_space( | ||
| 288 | netcalc * cnf, | ||
| 289 | netcalc_ip * ip, | ||
| 290 | int32_t cidr ); | ||
| 291 | |||
| 292 | |||
| 293 | void | ||
| 294 | netcalc_results_default( | ||
| 295 | netcalc * cnf ); | ||
| 296 | |||
| 297 | |||
| 298 | void | ||
| 299 | netcalc_results_verbose( | ||
| 300 | netcalc * cnf ); | ||
| 264 | 301 | ||
| 265 | 302 | ||
| 266 | // displays usage | 303 | // displays usage |
| @@ -292,9 +329,23 @@ char buff[1024]; | |||
| 292 | 329 | ||
| 293 | void netcalc_free( netcalc * cnf ) | 330 | void 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 | ||
| 399 | int 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 | |||
| 331 | int netcalc_ip_cmp( netcalc_ip * ip1, netcalc_ip * ip2 ) | 423 | int 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 | ||
| 889 | int 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 | |||
| 800 | void netcalc_net_wildmask_r( netcalc_ip * wildmask, int32_t cidr ) | 918 | void 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 | ||
| 810 | void netcalc_print_ip( netcalc * cnf, netcalc_ip * ip, int32_t cidr, int header ) | 928 | void 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 | ||
| 1044 | void 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 | |||
| 1085 | void 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 | |||
| 1109 | void 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 |
| 907 | void netcalc_usage(void) | 1129 | void 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 | } |
