1 /*
2 whatnet.c, Copyright (C) 2001-2003 Joe Laffey
3 Network Info Processing for Whatmask
4
5 $Revision: 1.21 $
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #else
25 #include "myTypes.h"
26 #endif
27
28
29 #include <stdlib.h>
30
31
32 #ifndef __dest_os
33 #define __dest_os 6969
34 #endif
35
36 #if __dest_os == __win32_os || __dest_os == __mac_os
37 #define EX_USAGE 64
38 #define EX_DATAERR 65
39 #define EX_SOFTWARE 70
40 #else
41 /* Windoze does not have this - or I can't find it... */
42 #include <sysexits.h>
43 #endif
44
45 #include <stdio.h>
46 #include <string.h>
47 #include "octets.h"
48 #include "bitfill.h"
49 #include "bitcount.h"
50 #include "validatemask.h"
51 #include "whatnet_printdata.h"
52 #include "myname.h"
53 #include "usage.h"
54
55
56 #include "whatnet.h"
57
whatnet_main(char * myIpPtr,char * myMaskPtr)58 int whatnet_main(char* myIpPtr, char* myMaskPtr)
59 {
60
61 uint32 myIp, /* ip address */
62 myMask, /* subnet mask */
63 myCIDR, /* CIDR style mask */
64 myBr, /* Broadcast address */
65 myNt; /* Network address */
66
67 char myIpStr[NM_LEN], /* ip address as string */
68 myMaskStr[NM_LEN], /* subnet mask as string */
69 myNtStr[NM_LEN], /* Network address as string */
70 myBrStr[NM_LEN], /* broadcast address as string */
71 myStartIpStr[NM_LEN], /* starting usable address as string */
72 myEndIpStr[NM_LEN], /* ending usable address as string */
73 myWildcardStr[NM_LEN], /* wildcard mask as string */
74 myCIDRStr[BIT_LEN]; /* CIDR bits as string */
75
76 uint32 usableIps; /* number of usable ips addresses */
77
78
79
80 /* try to convert the octets to the ip - this also returns 1 if the conversion fails */
81 if(octets_to_u_int(&myIp, myIpPtr))
82 {
83 fprintf(stderr, "%s: \"%s\" is not a valid IP address! IP addresses take the form\n\"xxx.xxx.xxx.xxx\" where each octet (group of numbers separated by dots) must be\nbetween 0 and 255 inclusive!\n", PACKAGE, myIpPtr);
84 return(EX_SOFTWARE);
85 }
86
87 if( (myMaskPtr[0] == '0')
88 && (myMaskPtr[1] =='x' || myMaskPtr[1] == 'X')
89 )
90 {
91
92 if(
93 !( (myMaskPtr[2] >= 'a' && myMaskPtr[2] <= 'f')
94 ||(myMaskPtr[2] >= 'A' && myMaskPtr[2] <= 'F')
95 ||(myMaskPtr[2] >= '0' && myMaskPtr[2] <= '9')
96 ) ||
97 !( (myMaskPtr[3] >= 'a' && myMaskPtr[3] <= 'f')
98 ||(myMaskPtr[3] >= 'A' && myMaskPtr[3] <= 'F')
99 ||(myMaskPtr[3] >= '0' && myMaskPtr[3] <= '9')
100 ) ||
101 !( (myMaskPtr[4] >= 'a' && myMaskPtr[4] <= 'f')
102 ||(myMaskPtr[4] >= 'A' && myMaskPtr[4] <= 'F')
103 ||(myMaskPtr[4] >= '0' && myMaskPtr[4] <= '9')
104 ) ||
105 !( (myMaskPtr[5] >= 'a' && myMaskPtr[5] <= 'f')
106 ||(myMaskPtr[5] >= 'A' && myMaskPtr[5] <= 'F')
107 ||(myMaskPtr[5] >= '0' && myMaskPtr[5] <= '9')
108 ) ||
109 !( (myMaskPtr[6] >= 'a' && myMaskPtr[6] <= 'f')
110 ||(myMaskPtr[6] >= 'A' && myMaskPtr[6] <= 'F')
111 ||(myMaskPtr[6] >= '0' && myMaskPtr[6] <= '9')
112 ) ||
113 !( (myMaskPtr[7] >= 'A' && myMaskPtr[7] <= 'f')
114 ||(myMaskPtr[7] >= 'A' && myMaskPtr[7] <= 'F')
115 ||(myMaskPtr[7] >= '0' && myMaskPtr[7] <= '9')
116 ) ||
117 !( (myMaskPtr[8] >= 'a' && myMaskPtr[8] <= 'f')
118 ||(myMaskPtr[8] >= 'A' && myMaskPtr[8] <= 'F')
119 ||(myMaskPtr[8] >= '0' && myMaskPtr[8] <= '9')
120 ) ||
121 !( (myMaskPtr[9] >= 'a' && myMaskPtr[9] <= 'f')
122 ||(myMaskPtr[9] >= 'A' && myMaskPtr[9] <= 'F')
123 ||(myMaskPtr[9] >= '0' && myMaskPtr[9] <= '9')
124 ) ||
125 ( strlen(myMaskPtr) != 10)
126 )
127 {
128 /*doesn't have all 8 hex chars*/
129 fprintf(stderr, "%s: \"%s\" is not a valid subnet mask!\n(Hex values need 8 chars [0-9][a-f][A-F])\n", PACKAGE, myMaskPtr);
130 return(EX_DATAERR);
131 }
132 else if( sscanf((char*)(myMaskPtr+2), "%08x", &myMask) != 1)
133 {
134 /* hex conversion failed... weird. should not happen*/
135 fprintf(stderr, "%s: Stage two hex parsing failed! Please report this as a bug with the input that caused it.\n", PACKAGE);
136 return(EX_DATAERR);
137 }
138 }
139 else
140 {
141
142
143 /* try to convert the octets for the mask - this also returns 1 if the conversion fails */
144 if(octets_to_u_int(&myMask, myMaskPtr))
145 {
146 /*assume CIDR */
147
148 if((strchr(myMaskPtr, '.') != NULL) || sscanf(myMaskPtr, "%" U_INT_32_PRINTF_STRING, &myCIDR) != 1)
149 {
150 /* not CIDR */
151 fprintf(stderr, "%s: \"%s\" is not a valid subnet mask or wildcard bit mask!\n", PACKAGE, myMaskPtr);
152 return(EX_DATAERR);
153 }
154
155
156 if(myCIDR > 32 )
157 {
158 fprintf(stderr, "CIDR netmask notations must be between 0 and 32 bits inclusive!\n");
159 return(EX_DATAERR);
160 }
161 /* Make a mask from the CIDR value */
162 myMask = bitfill_from_left(myCIDR);
163
164 }
165 }
166
167 /* check the ip and subnet mask for class A, B, C requirments and warn if inconsistent */
168 /*
169 validate_class(myIp, myMask);
170 */
171
172 /* ip */
173 u_int_to_octets(myIp, myIpStr);
174
175 /* netmask */
176 if( validatemask(myMask) )
177 {
178 /* This failed but may be Cisco-style */
179 /* not it so we can see if it is cisco-style */
180 myMask = ~myMask;
181
182 if( validatemask(myMask) )
183 {
184 /* Now we know it's bad */
185 fprintf(stderr, "%s: \"%s\" is not a valid subnet mask or wildcard bit mask!\n", PACKAGE, myMaskPtr);
186 return(EX_DATAERR);
187 }
188 }
189
190 u_int_to_octets(myMask, myMaskStr);
191
192 /* Wildcard bits as string */
193 u_int_to_octets(~myMask, myWildcardStr);
194
195 /* CIDR as a string */
196 myCIDR = (unsigned int)bitcount(myMask);
197 snprintf(myCIDRStr, BIT_LEN, "%" U_INT_32_PRINTF_STRING, myCIDR );
198
199 /* network address */
200 myNt = (myIp & myMask);
201 u_int_to_octets( myNt, myNtStr);
202
203 /* Broadcast address */
204 myBr = ( myNt + ~myMask );
205 u_int_to_octets( myBr, myBrStr) ;
206
207 /* usable ips */
208 usableIps = (myCIDR >30)?0:(myBr - myNt - 1);
209
210 if(usableIps <= 0)
211 {
212 strcpy(myStartIpStr , "<none>");
213 strcpy(myEndIpStr , "<none>");
214 }
215 else
216 {
217 /* startIp */
218 u_int_to_octets( myNt + 1, myStartIpStr);
219
220 /* endIp */
221 u_int_to_octets( myBr - 1, myEndIpStr);
222 }
223
224 whatnet_printdata( myMask, myIpStr, myMaskStr, myWildcardStr, myCIDRStr, myNtStr, myBrStr, myStartIpStr, myEndIpStr, usableIps );
225
226 return(0);
227 }
228
229