Glenn L McGrath | c11986d | 2002-11-10 23:42:27 +0000 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4 ai: */ |
| 2 | /* |
| 3 | * Mini ipcalc implementation for busybox |
| 4 | * |
| 5 | * By Jordan Crouse <jordan@cosmicpenguin.net> |
| 6 | * Stephan Linz <linz@li-pro.net> |
| 7 | * |
| 8 | * This is a complete reimplentation of the ipcalc program |
| 9 | * from Redhat. I didn't look at their source code, but there |
| 10 | * is no denying that this is a loving reimplementation |
| 11 | */ |
| 12 | |
| 13 | #include <stdio.h> |
| 14 | #include <stdlib.h> |
| 15 | #include <ctype.h> |
| 16 | #include <getopt.h> |
| 17 | #include <sys/socket.h> |
| 18 | #include <netinet/in.h> |
| 19 | #include <arpa/inet.h> |
| 20 | |
| 21 | #include "busybox.h" |
| 22 | |
| 23 | #define IPCALC_MSG(CMD,ALTCMD) if (mode & SILENT) {ALTCMD;} else {CMD;} |
| 24 | |
| 25 | static unsigned long get_netmask(unsigned long ipaddr) |
| 26 | { |
| 27 | if (ipaddr & 0xC0) { |
| 28 | return 0x00FFFFFF; /* Class C */ |
| 29 | } |
| 30 | if (ipaddr & 0x10) { |
| 31 | return 0x0000FFFF; /* Class B */ |
| 32 | } |
| 33 | return 0x000000FF; /* Class A */ |
| 34 | } |
| 35 | |
| 36 | #define NETMASK 0x01 |
| 37 | #define BROADCAST 0x02 |
| 38 | #define NETWORK 0x04 |
| 39 | #define HOSTNAME 0x08 |
| 40 | #define SILENT 0x80 |
| 41 | |
| 42 | int ipcalc_main(int argc, char **argv) |
| 43 | { |
| 44 | unsigned char mode = 0; |
| 45 | |
| 46 | unsigned long netmask = 0; |
| 47 | unsigned long broadcast = 0; |
| 48 | unsigned long network = 0; |
| 49 | unsigned long ipaddr = 0; |
| 50 | |
| 51 | int opt = 0; |
| 52 | |
| 53 | struct option long_options[] = { |
| 54 | {"netmask", no_argument, NULL, 'n'}, |
| 55 | {"broadcast", no_argument, NULL, 'b'}, |
| 56 | {"network", no_argument, NULL, 'w'}, |
| 57 | #ifdef CONFIG_FEATURE_IPCALC_FANCY |
| 58 | {"hostname", no_argument, NULL, 'h'}, |
| 59 | {"silent", no_argument, NULL, 's'}, |
| 60 | #endif |
| 61 | {NULL, 0, NULL, 0} |
| 62 | }; |
| 63 | |
| 64 | |
| 65 | while ((opt = getopt_long(argc, argv, |
| 66 | #ifdef CONFIG_FEATURE_IPCALC_FANCY |
| 67 | "nbwhs", |
| 68 | #else |
| 69 | "nbw", |
| 70 | #endif |
| 71 | long_options, NULL)) != EOF) { |
| 72 | if (opt == 'n') |
| 73 | mode |= NETMASK; |
| 74 | else if (opt == 'b') |
| 75 | mode |= BROADCAST; |
| 76 | else if (opt == 'w') |
| 77 | mode |= NETWORK; |
| 78 | #ifdef CONFIG_FEATURE_IPCALC_FANCY |
| 79 | else if (opt == 'h') |
| 80 | mode |= HOSTNAME; |
| 81 | else if (opt == 's') |
| 82 | mode |= SILENT; |
| 83 | #endif |
| 84 | else { |
| 85 | show_usage(); |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | if (mode & (BROADCAST | NETWORK)) { |
| 90 | if (argc - optind > 2) { |
| 91 | show_usage(); |
| 92 | } |
| 93 | } else { |
| 94 | if (argc - optind != 1) { |
| 95 | show_usage(); |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | ipaddr = inet_addr(argv[optind]); |
| 100 | |
| 101 | if (ipaddr == INADDR_NONE) { |
| 102 | IPCALC_MSG(error_msg_and_die("bad IP address: %s\n", argv[optind]), |
| 103 | exit(EXIT_FAILURE)); |
| 104 | } |
| 105 | |
| 106 | |
| 107 | if (argc - optind == 2) { |
| 108 | netmask = inet_addr(argv[optind + 1]); |
| 109 | } |
| 110 | |
| 111 | if (ipaddr == INADDR_NONE) { |
| 112 | IPCALC_MSG(error_msg_and_die("bad netmask: %s\n", argv[optind + 1]), |
| 113 | exit(EXIT_FAILURE)); |
| 114 | } |
| 115 | |
| 116 | /* JHC - If the netmask wasn't provided then calculate it */ |
| 117 | if (!netmask) { |
| 118 | netmask = get_netmask(ipaddr); |
| 119 | } |
| 120 | |
| 121 | if (mode & NETMASK) { |
| 122 | printf("NETMASK=%s\n", inet_ntoa((*(struct in_addr *) &netmask))); |
| 123 | } |
| 124 | |
| 125 | if (mode & BROADCAST) { |
| 126 | broadcast = (ipaddr & netmask) | ~netmask; |
| 127 | printf("BROADCAST=%s\n", inet_ntoa((*(struct in_addr *) &broadcast))); |
| 128 | } |
| 129 | |
| 130 | if (mode & NETWORK) { |
| 131 | network = ipaddr & netmask; |
| 132 | printf("NETWORK=%s\n", inet_ntoa((*(struct in_addr *) &network))); |
| 133 | } |
| 134 | #ifdef CONFIG_FEATURE_IPCALC_FANCY |
| 135 | if (mode & HOSTNAME) { |
| 136 | struct hostent *hostinfo; |
| 137 | int x; |
| 138 | |
| 139 | hostinfo = gethostbyaddr((char *) &ipaddr, sizeof(ipaddr), AF_INET); |
| 140 | if (!hostinfo) { |
| 141 | IPCALC_MSG(error_msg("cannot find hostname for %s", argv[optind]); |
| 142 | herror(NULL); |
| 143 | putc('\n', stderr);,); |
| 144 | exit(EXIT_FAILURE); |
| 145 | } |
| 146 | for (x = 0; hostinfo->h_name[x]; x++) { |
| 147 | hostinfo->h_name[x] = tolower(hostinfo->h_name[x]); |
| 148 | } |
| 149 | |
| 150 | printf("HOSTNAME=%s\n", hostinfo->h_name); |
| 151 | } |
| 152 | #endif |
| 153 | |
| 154 | return EXIT_SUCCESS; |
| 155 | } |
| 156 | |
| 157 | /* END CODE */ |
| 158 | /* |
| 159 | Local Variables: |
| 160 | c-file-style: "linux" |
| 161 | c-basic-offset: 4 |
| 162 | tab-width: 4 |
| 163 | End: |
| 164 | */ |