Example #1
0
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;
}