ACC SHELL

Path : /usr/share/YaST2/modules/
File Upload :
Current File : //usr/share/YaST2/modules/NetHwDetection.ycp

/**
 * File:	modules/NetHwDetection.ycp
 * Package:	Network configuration
 * Summary:	Network detection
 * Authors:	Michal Svec <msvec@suse.cz>
 *
 * $Id: NetHwDetection.ycp 62071 2010-05-27 12:00:38Z mzugec $
 *
 * <p>Detects network settings, using dhcp or sniffing network traffic</p>
 *
 * <h3>Detection process:</h3>
 * <h4>Initial stage:</h4><ul>
 *   <li>hardware detection
 *   <li>load kernel modules (if not already active *1)
 *   <li>set up interface (if not already set up *2)
 *   <li>run detection
 * </ul>
 * <h4>Final stage:</h4><ul>
 *   <li>read detection data
 *   <li>shut down interfaces (if set up before, see *2)
 *   <li>remove kernel modules (if loaded before, see *1)
 * </ul>
 *
 * <p>
 * <h4>Used software:</h4><ul>
 *   <li>dhcpcd(8)
 *   <li>netprobe(8) (currently not, originally by Caldera, license unclear)
 * </ul>
 *
 * <p>
 * <h4>Usage:</h4><ul>
 *   <li>Detection::Start() somewhere at the start of installation
 * </ul><p>Later at the module:<ul>
 *   <li>if(Detection::running) Detection::Stop();
 *   <li>string gw = Detection::result["GATEWAY"]:"";
 * </ul>
 *
 */

{

module "NetHwDetection";
textdomain "network";

import "Directory";
import "Package";
import "String";

// yuck, FIXME
// this is here just because network/hardware.ycp references it
// because of detection and module loading (StartEthInterface)
/* general stuff */
global string description = "";
global string type = "";
global string unique = "";
global string hotplug = "";
global list<string> Requires = [];

include "network/hardware.ycp";

/**
 * Detection result
 * (in dhcpcd-<i>interface</i>.info format)
 */
global map result = $[];

/**
 * True, if detection is running
 */
global boolean running = false;

string tmpdir = Directory::tmpdir;

list<string> detection_modules = [];

/**
 * Set up the first eth interface, if not already running
 * WATCH OUT, this is the place where modules are loaded
 * @return true if success
 */
define boolean StartEthInterface() {

    y2milestone("Network detection prepare");

    list<map> Hardware = ReadHardware("netcard");

    y2debug("Hardware=%1", Hardware);
    if(size(Hardware) < 1) return false;

    map <string, boolean> needed_modules = listmap (map h, Hardware, {
	// Formerly we simply modprobed the first module of the first
	// driver, if it was not already loaded.  But if the user
	// configured the card to use the second driver and unloads it
	// and wants to load the first, it will not work because the
	// first driver is already loaded but not bound to the device
	// (the second one took it). N#59794#c31
	// We will only load a driver if there's no driver for the card active.
	map active_driver = find (map d, (list<map>)h["drivers"]:[],
				  ``( d["active"]:false ));
	return $[ (h["module"]:"") : (active_driver == nil) ];

	// TODO 1: choose which driver to load
	// (2: load all its modules: no cards use multiple modules)
	// (3: either modprobe or insmod: ISA history)
    });
    needed_modules = filter (string m, boolean load, needed_modules, {
	return load && m != nil && m != "" &&
	  SCR::Execute (.target.bash, sformat ("grep ^%1 /proc/modules", m)) != 0;
    });
    detection_modules = maplist (string m, boolean a, needed_modules, ``( m ));
    Package::InstallKernel (maplist (string m, detection_modules, ``(m+".ko")));
    foreach (string mod, detection_modules, {
	y2milestone("Loading module: %1", mod);
	SCR::Execute (.target.bash, sformat ("/sbin/modprobe --use-blacklist %1 2>&1", mod));
    });


 string command =  "ls /sys/class/net|grep -v \"^lo$\"";
 map<string, any> output = (map<string, any>)SCR::Execute(.target.bash_output, command);
 if (output["exit"]:-1==0){
  list<string> interfaces = filter(string s, splitstring(output["stdout"]:"", "\n"), {return (size(s)>0);});
  y2milestone("interfaces %1", interfaces);
  foreach(string ifc, interfaces, {
// TODO: do some tests before uncomment block bellow
//   if ((integer)SCR::Execute(.target.bash, sformat("ip link show %1|head -n1|grep -q \"[^[:alpha:]]UP[^[:alpha:]]\"", ifc))!=0)
//    {
     y2milestone("Setting link up for interface %1", ifc);
     SCR::Execute(.target.bash, sformat("ip link set %1 up", ifc));
//    } else y2milestone("Link for %1 interface is already up, nothing to do", ifc);
  });
 } else y2error("Error while execute %1 : %2", command, output);

    y2milestone("Network detection prepare (end)");
    return true;
}




/**
 * Start the detection
 * @return true on success
 */
global define boolean Start() {
    if(running == true) {
	y2error("Detection already running");
	return false;
    }

y2milestone("IFCONFIG1: %1", SCR::Execute(.target.bash_output, "/sbin/ifconfig"));
    boolean ret = false;
    if(StartEthInterface()) {
	running = true;
	ret = true;
    }

y2milestone("IFCONFIG2: %1", SCR::Execute(.target.bash_output, "/sbin/ifconfig"));
    y2milestone("Detection start result: %1", ret);
    return ret;
}

/**
 * Stop the detection
 * @return true on success
 */
global define boolean Stop() {
    if(running != true) {
	y2error("Detection not running");
	return false;
    }
    running = false;

y2milestone("IFCONFIG3: %1", SCR::Execute(.target.bash_output, "/sbin/ifconfig"));

    y2milestone("Detection stop ");
    return true;
}

/**
 * Duplicate IP detection
 * @param ip tested IP address
 * @return true if duplicate found
 * @see arping(8), ip(8)
 */
global boolean DuplicateIP (string ip) {
    string command = "LC_ALL=C ip link show|grep BROADCAST|grep -v NOARP|cut -d: -f2";
    map exe = (map) SCR::Execute (.target.bash_output, command);
    string ifs = exe["stdout"]:"";
    list<string> ifsl = filter (string i, splitstring (ifs, " \t\n"), ``( i != ""));

    // #45169: must only probe the interface being set up
    // but I don't know which one it is :-(
    // so pretend there are no dups if we have more interfaces
    if (size (ifsl) > 1)
    {
	return false;
    }

    // find the interface that detects the dup
    string ifc = find (string ifname, ifsl, {
	// no need to be quiet, diagnostics is good
	command = "arping  -D -c2 -w3 -I" + ifname + " " + ip;
	// 0 no dup, 1 dup, 2 other error (eg. ifc not up, #182473)
	return SCR::Execute(.target.bash, command) == 1;
    });

    return ifc != nil;
}

// this function is moved here just to kee it out of the tangle of
// includes which will be torn apart in the next release. dependency
// hell.
/**
 * Resolve IP to hostname
 * @param ip given IP address
 * @return resolved host
 */
global string ResolveIP(string ip) {
    // quick check to avoid timeout
    if ( size(ip)==0 || (integer)SCR::Execute(.target.bash, sformat("grep -q %1 /etc/hosts", ip))!=0 ) return "";

    string command = "/usr/bin/getent hosts \"%1\" | sed \"s/^[0-9.: \t]\\+//g\"";
    map getent = (map) SCR::Execute(.target.bash_output, sformat(command, ip));
    string hnent = getent["stdout"]:"";
    y2debug("%1", hnent);
    hnent = String::FirstChunk (hnent, " \t\n");
    if(hnent == nil) hnent = "";
    y2debug("'%1'", hnent);
    return String::CutBlanks(hnent);
}

/* EOF */
}

ACC SHELL 2018