summaryrefslogtreecommitdiff
path: root/src/ipv4.c
blob: a8f08d9d61fe54d6b20cae4e6d23a1fb3dc0cb08 (plain)
    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 }

Generated by cgit