title: how to join or split ip networks with php
body: <p>I have a task that seems to include a subtask. Take two or more ip segments ( could be 192.168.1.32/27, 192.168.1.64/28 and 192.168.1.128/25) and join them into the closest segment (192.168.1.0/24 using the former ip segments). A check if its possible to join the segments must be .</p>
  
  <p>Anyone know if there is a php class with tools that can do that - or a couple of functions likewise?</p>
  
  <p>/Lars </p>
  
  <p>EDIT:
  [code]</p>
  
  <pre><code>$ip_id_array = array();
  $ip_level_array = array();
  $ip_segment_array = array();
  $ip_cidr_array = array();
  $toplevel_array = array();
  
  foreach ($_POST["net_ip_id"] AS $ip_id)
  {
      $sql = "
      SELECT
          ip_segments.ip_id,
          ip_segments.ip_segment,
          ip_segments.ip_level,
          ip_segments.ip_cidr
      FROM
          ip_segments
      WHERE
          ip_id = '".$ip_id."'
      ";
      $relip_res = mysqli_query($db, $sql) or cc("ERROR: SQL Select subsegments related", $sql, mysqli_error($db) , $_SESSION["u_id"], $this_document);
      $ip_array = mysqli_fetch_assoc($relip_res);
      $ip_id_array[] = $ip_array["ip_id"];
      $ip_level_array[] = $ip_array["ip_level"];
      $ip_segment_array[] = $ip_array["ip_segment"];
      $ip_cidr_array[] = $ip_array["ip_cidr"];
  
      if ($ip_array["ip_level"] != 0 &amp;&amp; !empty($ip_array["ip_level"]))
      {
          $sql = "
          SELECT
              ip_segments.ip_id,
              ip_segments.ip_segment,
              ip_segments.ip_level,
              ip_segments.ip_cidr
          FROM
              ip_segments
          WHERE
              ip_id = '".$ip_array["ip_level"]."'
          ";
          $relip_res = mysqli_query($db, $sql) or cc("ERROR: SQL Select subsegments related", $sql, mysqli_error($db) , $_SESSION["u_id"], $this_document);
          $toplevel[] = mysqli_fetch_assoc($relip_res);
      }
  }
  
  $ip_level_array = array_unique($ip_level_array);
  $ip_cidr_array = array_unique($ip_cidr_array);
  $toplevel = array_unique($toplevel);
  
  if(sizeof($ip_level_array) &gt; 1)
      $field_alerts[] = "IP Segments must be within the same segment.!";
  if ($ip_cidr_array[0] &lt;= 1)
      $field_alerts[] = "Subnetmasks must be larger than or equal to 1";
  if ($toplevel &lt;= 1)
      $field_alerts[] = "No Toplevel to merge to!";
  
  if (sizeof($field_alerts) &lt; 1)
  {
      $new_segment = $ip_id_array[0];
      $new_cidr = $toplevel[0]["ip_cidr"];
  }
  </code></pre>
  
  <p>[/code]</p>
  
  <p>Edit:
  A segment is toplevel 192.168.1.0/24 (id 1 - level 0)
  It can be subnetted into several different types of subnets ranging from /25 and down to /32 (host).
  Say we segment to /26. That gives the following:</p>
  
  <pre><code>ID, Level, IP, CIDR
  2,1,192.168.1.0,26
  3,1,192.168.1.64,26
  4,1,192.168.1.128,26
  5,1,192.168.1.192,26
  </code></pre>
  
  <p>See: <a href="http://jodies.de/ipcalc?host=192.168.1.0&amp;mask1=24&amp;mask2=26" rel="nofollow">http://jodies.de/ipcalc?host=192.168.1.0&amp;mask1=24&amp;mask2=26</a></p>
  
  <p>What I need is a piece of code that can take an array of id's, look at the segment and cidr and look at the possibility to join the segments to closest supernet (in this case /25 or /24)
  Options:</p>
  
  <pre><code>Join ID, Result
  2,3 =&gt; true (/25)
  2,4 =&gt; false (networks not "next" to each other (a /26 between))
  3,4 =&gt; false (subsegments will split toplevel (/25) segment
  4,5 =&gt; true (/25)
  </code></pre>
  
  <p>Let me know if more info is needed.</p>