1 /**
2 * Copyright (C) 2015 Aaron Ball <nullspoon@iohq.net>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "ipv4.h"
18
19 /**
20 * Ipv4 initializer
21 *
22 * @param ip Declared ipv4 struct to be (re-)initialized
23 *
24 * @return void
25 */
26 void ipv4_new(ipv4* ip) {
27 ip->octets[0] = 0;
28 ip->octets[1] = 0;
29 ip->octets[2] = 0;
30 ip->octets[3] = 0;
31 ip->mask = 32; // assume a /32
32 }
33
34
35 /**
36 * Ipv4 initializer
37 *
38 * @param ip Declared ipv4 struct to be (re-)initialized
39 *
40 * @return void
41 */
42 void ipv4_cpy(ipv4* orig, ipv4* new) {
43 new->octets[0] = orig->octets[0];
44 new->octets[1] = orig->octets[1];
45 new->octets[2] = orig->octets[2];
46 new->octets[3] = orig->octets[3];
47 new->mask = orig->mask;
48 }
49
50
51 /**
52 * Converts the given ipv4 struct to its binary equivelant.
53 * Note that despite the specified netmask, this converts the ipv4 struct as if
54 * it were a /32 (a single ip address).
55 *
56 * @param addr Initialized ipv4 struct
57 *
58 * @return unsigned int Integer representation of the specified ipv4 address
59 */
60 unsigned int ipv4_to_int(ipv4* addr) {
61 unsigned int out;
62 out = addr->octets[3] * 16777216; // 2^24 or 256^3
63 out += addr->octets[2] * 65536; // 2^16 or 256^2
64 out += addr->octets[1] * 256; // 2^8 or 256^1
65 out += addr->octets[0]; // 2^1 or na
66
67 return out;
68 }
69
70
71 /**
72 * Converts a string to an ipv4 struct
73 *
74 * @param ip String representation of an ipv4 address
75 *
76 * @return ipv4 Initialized ipv4 struct
77 */
78 ipv4 str_to_ipv4(char* ip) {
79 int octet = 3;
80 int cursor = 0;
81 int i = 0;
82 char buf[4];
83 ipv4 out;
84
85 // Initialize
86 ipv4_new(&out);
87
88 while(ip[i] != '\0' && ip[i] != '/') {
89 if(ip[i] == '.') {
90 // Copy the string contents
91 strncpy(buf, &ip[cursor], i-cursor);
92 // Place the trailing null byte
93 buf[i-cursor] = '\0';
94 // Convert string octet to int
95 out.octets[octet] = atoi(buf);
96
97 cursor = i+1;
98 octet--;
99 }
100 i++;
101 }
102
103 // For the last octet, one more do-over
104 strncpy(buf, &ip[cursor], i-cursor);
105 buf[i-cursor] = '\0';
106 out.octets[octet] = atoi(buf);
107
108 // Set the mask
109 // Default the mask to /32. It'll be overwritten if it was specified.
110 char cmask[4] = "32";
111 if(ip[i] == '/') {
112 strcpy(&cmask[0], &ip[i+1]);
113 }
114 out.mask = atoi(cmask);
115
116 return out;
117 }
118
119
120 /**
121 * Converts an ipv4 struct to a string, using slash notation to indicate
122 * netmask.
123 *
124 * @param ip Initialized ipv4 struct to be converted to string
125 * @param out Output char array where the ipv4 string will be copied
126 *
127 * @return void
128 */
129 void ipv4_to_str(ipv4* ip, char* out) {
130 int octet = 3;
131 int cursor = 0;
132
133 out[0] = '\0';
134 while(octet >= 0) {
135 int len = itoa(ip->octets[octet], &out[cursor]);
136 cursor += len;
137 out[cursor] = '.';
138 cursor++;
139 octet--;
140 }
141 // Erase the trailing period
142 out[cursor - 1] = '\0';
143 }
144
145
146 /**
147 * Increments an ipv4 address
148 * Handles octet resets and carrying the 1.
149 *
150 * @param ip Initialized ipv4 struct
151 *
152 * @return void
153 */
154 void ipv4_inc(ipv4* ip) {
155 int octet = 0;
156 while(ip->octets[octet] == 255) {
157 ip->octets[octet] = 0;
158 octet++;
159 }
160 ip->octets[octet]++;
161 }
162
163
164 /**
165 * Prints all ip addresses for the given ipv4 network (uses the mask value from
166 * the ipv4 struct)
167 *
168 * @param ip Initialized ipv4 struct pointer containing all the information to
169 * calculate every ip in the specified ipv4 network.
170 *
171 * @return void
172 */
173 void ipv4_ips(ipv4* ip) {
174 unsigned long count = pow(2, 32 - ip->mask);
175 char buf[20];
176
177 while(count > 0) {
178 ipv4_to_str(ip, buf);
179 // TODO: Move this into a return array
180 printf("%s\n", buf);
181 ipv4_inc(ip);
182 count--;
183 }
184 }
|