function ospf_net($cnmlid) { $nmax = 200; //num maxim de nodes a procesar $networks = array(); //array de subxarxes de la zona $nodes = array(); //array de nodes id de la zona $nodesid = array(); //array de dades del node + control de repeticions $subnets = array(); //array de subxarxes agrupades $azones = array(); //array de zones implicades $aznets = array(); //array de xarxes de les zones implicades $nreg = 0; $n = 0; $CNML = new SimpleXMLElement('<cnml></cnml>'); $tbegin = microtime(TRUE); $CNML->addAttribute('version', '0.1'); $CNML->addAttribute('server_id', '1'); $CNML->addAttribute('server_url', 'http://guifi.net'); $CNML->addAttribute('generated', date('Ymd hi', time())); $CNML->addAttribute('description', 'ospf zone networks'); $nodesid["{$cnmlid}"] = ""; $nodes[] = $cnmlid; //busqueda de nodes de la zona ospf $tnodes = 0; while (isset($nodes[$n])) { $tnodes = $tnodes + ospf_net_search_links($nodes, $nodesid, $nodes[$n]); if ($tnodes < $nmax) { $n++; } else { break; } } ksort($nodesid); //busqueda de dades node, subxarxes de cada node, llista de zones $nreg = count($nodes); for ($n = 0; $n < $nreg; $n++) { $result = db_query(sprintf("SELECT t1.nick as nnick, t1.zone_id as zid, t2.nick as znick\n FROM guifi_location as t1\n join guifi_zone as t2 on t1.zone_id = t2.id\n where t1.id = (%s)", $nodes[$n])); if ($record = db_fetch_object($result)) { $nodesid["{$nodes[$n]}"] = array("nnick" => $record->nnick, "zid" => $record->zid); if (!isset($azones[$record->zid])) { $azones[$record->zid] = $record->znick; } } ospf_net_add_node_networks($networks, $nodes[$n]); } ksort($networks); //busqueda de xarxes de la zona if (count($azones)) { foreach ($azones as $key => $azone) { $result = db_query(sprintf("SELECT t1.base as netid, t1.mask as mask\n FROM guifi_networks as t1\n where t1.zone = (%s)", $key)); while ($record = db_fetch_object($result)) { $a = _ipcalc($record->netid, $record->mask); $splitip = explode(".", $a["netid"]); $c = $splitip[0] * pow(256, 3) + $splitip[1] * pow(256, 2) + $splitip[2] * 256 + $splitip[3]; if (!isset($aznets[$c])) { $aznets[$c] = array("netid" => $a["netid"], "maskbits" => $a["maskbits"], "broadcast" => $a["broadcast"], "zid" => $key, "swagr" => 0); } elseif ($aznets[$c]["maskbits"] > $a["maskbits"]) { $aznets[$c] = array("netid" => $a["netid"], "maskbits" => $a["maskbits"], "broadcast" => $a["broadcast"], "zid" => $key, "swagr" => 0); } } } } ksort($aznets); //verifica que les xarxes de zona estiguin als nodes de la zona ospf $result = db_query("SELECT ipv4, netmask FROM {guifi_ipv4} where ipv4_type = 1"); while ($ip = db_fetch_array($result)) { if ($ip['ipv4'] != 'dhcp' and !empty($ip['ipv4'])) { $ip_dec = ip2long($ip['ipv4']); $min = FALSE; $max = FALSE; if (!isset($ips[$ip_dec])) { // save memory by storing just the maskbits // by now, 1MB array contains 7,750 ips $ips[$ip_dec] = guifi_ipcalc_get_maskbits($ip['netmask']); } } } //agrupació de subxarxes $subnets = array_values($networks); for ($nmaskbits = 30; $nmaskbits > 16; $nmaskbits--) { $net1 = ""; $knet1 = 0; $nreg = 0; if (count($subnets)) { foreach ($subnets as $key => $subnet) { if ($subnet["maskbits"] == $nmaskbits) { $nreg++; $a = _ipcalc_by_netbits($subnet["netid"], $nmaskbits - 1); if ($a["netid"] != $net1) { $net1 = $a["netid"]; $knet1 = $key; } else { $subnets[$knet1]["maskbits"] = $nmaskbits - 1; unset($subnets[$key]); $net1 = ""; $knet1 = 0; } } else { $net1 = ""; $knet1 = 0; } } } //if($nreg==0){ // break; //} } // $networks[$c]=Array("ipv4" => $record->ipv4,"netmask" => $record->netmask,"netid" => $a["netid"],"maskbits" => $a["maskbits"],"nid" => $nid); //generació cnml $classXML0 = $CNML->addChild('aggregate_networks'); $nreg = 0; if (count($subnets)) { foreach ($subnets as $key => $subnet) { $nreg++; $reg = $classXML0->addChild('subnet'); $reg->addAttribute('address', $subnet["netid"]); $reg->addAttribute('maskbits', $subnet["maskbits"]); } } $classXML0->addAttribute('total_aggregate_networks', $nreg); $classXML = $CNML->addChild('networks'); $nreg = 0; if (count($networks)) { foreach ($networks as $key => $network) { $nreg++; $reg = $classXML->addChild('subnet'); $reg->addAttribute('num', $key); $reg->addAttribute('address', $network["netid"]); $reg->addAttribute('maskbits', $network["maskbits"]); $reg->addAttribute('node', $network["nid"]); $reg->addAttribute('nick', $nodesid[$network["nid"]]["nnick"]); } } $classXML->addAttribute('total_networks', $nreg); $classXML2 = $CNML->addChild('area_nodes'); $nreg = 0; if (count($nodesid)) { foreach ($nodesid as $key => $nodeid) { $nreg++; $reg = $classXML2->addChild('node'); $reg->addAttribute('node', $key); $reg->addAttribute('nick', $nodeid["nnick"]); $reg->addAttribute('zone', $azones[$nodeid["zid"]]); } } $classXML2->addAttribute('total_nodes', $nreg); $classXML3 = $CNML->addChild('zone_networks'); $nreg = 0; if (count($aznets)) { foreach ($aznets as $key => $aznet) { $nreg++; $reg = $classXML3->addChild('subnet'); //$reg->addAttribute('num',$key); $reg->addAttribute('address', $aznet["netid"]); $reg->addAttribute('maskbits', $aznet["maskbits"]); $reg->addAttribute('broadcast', $aznet["broadcast"]); $reg->addAttribute('zone', $azones[$aznet["zid"]]); } } $classXML3->addAttribute('total_zone_networks', $nreg); $CNML->addAttribute('elapsed', round(microtime(TRUE) - $tbegin, 4)); return $CNML; }
function guifi_ipcalc_get_subnet_by_nid($nid, $mask_allocate = '255.255.255.224', $network_type = 'public', $ips_allocated = NULL, $allocate = 'No', $verbose = FALSE) { if (empty($nid)) { drupal_set_message(t('Error: trying to search for a network for unknown node or zone'), 'error'); return; } if (empty($mask_allocate)) { drupal_set_message(t('Error: trying to search for a network of unknown size'), 'error'); return; } if (empty($network_type)) { drupal_set_message(t('Error: trying to search for a network for unknown type'), 'error'); return; } // print "Going to allocate network ".$mask_allocate."-".$network_type; global $user; $tbegin = microtime(TRUE); $zone = node_load(array('nid' => $nid)); if ($zone->type == 'guifi_node') { $zone = guifi_zone_load($zone->zone_id); } $rzone = $zone; $depth = 0; $root_zone = $zone->id; $lbegin = microtime(TRUE); $search_mask = $mask_allocate; do { // while next is not the master, check within the already allocated ranges $result = db_query('SELECT n.id, n.base, n.mask ' . 'FROM {guifi_networks} n ' . 'WHERE n.zone = "%s" ' . ' AND network_type="%s" ' . 'ORDER BY n.id', $zone->id, $network_type); if ($verbose) { drupal_set_message(t('Searching if %mask is available at %zone, elapsed: %secs', array('%mask' => $mask_allocate, '%zone' => $zone->title, '%secs' => round(microtime(TRUE) - $lbegin, 4)))); } // if there are already networks defined, increase network mask, up to /20 level // here, getting the total # of nets defined $tnets = 0; while ($net = db_fetch_object($result)) { $tnets++; $item = _ipcalc($net->base, $net->mask); // if looking for mesh ip (255.255.255.255) base address & broadcast // should be considered as used if ($search_mask == '255.255.255.255') { $ips_allocated[ip2long($net->base)] = 32; $ips_allocated[ip2long($item['netend'])] = 32; } if ($ip = guifi_ipcalc_find_subnet($net->base, $net->mask, $mask_allocate, $ips_allocated)) { if ($verbose) { drupal_set_message(t('Found %ip/%rmask available at %netbase/%amask, got from %zone, elapsed: %secs', array('%amask' => $net->mask, '%netbase' => $net->base, '%ip' => $ip, '%rmask' => guifi_ipcalc_get_maskbits($mask_allocate), '%zone' => $zone->title, '%secs' => round(microtime(TRUE) - $lbegin, 4)))); } // reserve the available range fount into database? if ($depth and ($allocate == 'Yes' and $network_type == 'public' and $mask_allocate != '255.255.255.255')) { $msg = strip_tags(t('A new network (%base / %mask) has been allocated for zone %name, got from %name2 by %user.', array('%base' => $ip, '%mask' => $mask_allocate, '%name' => $rzone->title, '%name2' => $zone->title, '%user' => $user->name))); $to_mail = explode(',', $rzone->notification); $to_mail = explode(',', $zone->notification); $nnet = array('new' => TRUE, 'base' => $ip, 'mask' => $mask_allocate, 'zone' => $root_zone, 'newtwork_type' => $network_type); $nnet = _guifi_db_sql('guifi_networks', NULL, $nnet, $log, $to_mail); guifi_notify($to_mail, $msg, $log); drupal_set_message($msg); if ($search_mask == '255.255.255.255') { $ip = long2ip(ip2long($ip) + 1); } } return $ip; } } // while there is a network defined at the zone // Network was not allocated if ($verbose) { drupal_set_message(t('Unable to find space at %zone, will look at parents, elapsed: %secs', array('%zone' => $zone->title, '%secs' => round(microtime(TRUE) - $lbegin, 4)))); } // Need for an unused range, // already allocated networks from others than parents should be considered // as allocated ips (skipped) // This have to be done once, so do if is the zone being asked for if ($root_zone == $zone->id) { $parents = guifi_zone_get_parents($root_zone); $query = db_query('SELECT base ipv4, mask ' . 'FROM {guifi_networks} ' . 'WHERE zone NOT IN (' . implode(',', guifi_zone_get_parents($root_zone)) . ')'); while ($nip = db_fetch_array($query)) { $ips_allocated[ip2long($nip['ipv4']) + 1] = guifi_ipcalc_get_maskbits($nip['mask']); } // once merged, sort ksort($ips_allocated); // calculating the needed mask if ($network_type == 'public') { $depth++; if ($tnets > 0 and $tnets < 5) { // between 1 and 4, 24 - nets defined $maskbits = 24 - $tnets; } else { if ($tnets >= 5) { // greater than 4, /20 - 255.255.240.0 $maskbits = 20; } else { // first net, /24 - 255.255.255.0 $maskbits = 24; } } $mitem = _ipcalc_by_netbits($net->base, $maskbits); $mbits_allocate = guifi_ipcalc_get_maskbits($mask_allocate); if ($mbits_allocate > $maskbits or $mask_allocate == '255.255.255.255') { $mask_allocate = $mitem['netmask']; } } } // Take a look at the parent network zones $master = $zone->master; if ($zone->master > 0) { $zone = guifi_zone_load($zone->master); } } while ($master > 0); return FALSE; }
function guifi_traceroute_dataexport($route, $nRoute, &$linkslist, &$nodeslist) { $oGC = new GeoCalc(); $tDist = 0; $nLink = 0; $nReg = 0; $output = ''; foreach ($route as $did => $hop) { if (isset($hop['to'])) { $linkslist[$nReg]['todevicename'] = guifi_get_devicename($did, 'nick'); $linkslist[$nReg]['todevicelink'] = 'guifi/device/' . $did; $linkslist[$nReg]['tonode'] = $hop['to'][0]; $ip = db_fetch_object(db_query('SELECT ipv4, netmask FROM {guifi_ipv4} WHERE id=%d AND interface_id=%d', $hop['to'][2], $hop['to'][1])); $linkslist[$nReg]['toipv4'] = $ip->ipv4 . '/' . guifi_ipcalc_get_maskbits($ip->netmask); if (!isset($nodeslist[$hop['to'][0]])) { $nodeslist[$hop["to"][0]] = guifi_get_location($hop["to"][0]); $nodeslist[$hop["to"][0]][nodename] = guifi_get_nodename($hop['to'][0]); $nodeslist[$hop["to"][0]][nodelink] = $hop['to'][0]; } } if (isset($hop['from'])) { $nLink++; $nReg = $nRoute * 100 + $nLink; $linkslist[$nReg]['route'] = $nRoute; $linkslist[$nReg]['nlink'] = $nLink; $linkslist[$nReg]['idlink'] = $hop['from'][0]; $linkslist[$nReg]['fromdevicename'] = guifi_get_devicename($did, 'nick'); $linkslist[$nReg]['fromdevicelink'] = 'guifi/device/' . $did; $linkslist[$nReg]['fromnode'] = $hop['from'][5]; $ip = db_fetch_object(db_query('SELECT ipv4, netmask FROM {guifi_ipv4} WHERE id=%d AND interface_id=%d', $hop['from'][4], $hop['from'][3])); $linkslist[$nReg]['fromipv4'] = $ip->ipv4 . '/' . guifi_ipcalc_get_maskbits($ip->netmask); $linkslist[$nReg]['type'] = $hop['from'][1]; $linkslist[$nReg]['status'] = $hop['from'][2]; if (!isset($nodeslist[$hop['from'][5]])) { $nodeslist[$hop["from"][5]] = guifi_get_location($hop["from"][5]); $nodeslist[$hop["from"][5]][nodename] = guifi_get_nodename($hop['from'][5]); $nodeslist[$hop["from"][5]][nodelink] = $hop['from'][5]; } } // if not same location, give the distance if ($hop['from'][1] != 'cable') { $qry = db_query('SELECT n.id nid, lat, lon FROM {guifi_location} n, {guifi_links} l WHERE l.id=%d AND l.nid=n.id', $hop['from'][0]); $loc1 = db_fetch_object($qry); $loc2 = db_fetch_object($qry); $gDist = round($oGC->EllipsoidDistance($loc1->lat, $loc1->lon, $loc2->lat, $loc2->lon), 3); if ($gDist) { $linkslist[$nReg]['distance'] = $gDist; } } } return $output; }