MODULE InitNetwork;
IMPORT Files, KernelLog, Modules, Plugins, Strings, XML, XMLObjects, XMLScanner,
XMLParser,
Network, IP, ICMP, DNSMod := DNS, DHCP, IPv4, IPv6;
CONST
Ok* = 0;
NotFound* = 4001;
NoConfigFile* = 4002;
ConfigFileNotValid* = 4003;
MaxNofInterfaces* = 10;
TYPE
Config = POINTER TO RECORD
interfaceConfigs: InterfaceConfig;
routerConfigs: IPv6.RouterConfig;
IPForwarding: BOOLEAN;
EchoReply: BOOLEAN;
PreferredProtocol: LONGINT;
AutoNetConfigV4: BOOLEAN;
AutoNetConfigV6: BOOLEAN;
AutoNetConfigV6DNS: ARRAY DNSMod.MaxNofServer OF IP.Adr;
END;
InterfaceConfig = POINTER TO RECORD
Device: Plugins.Name;
Protocol: LONGINT;
Name: IP.Name;
Domain: Strings.String;
DHCP: BOOLEAN;
LocalAdr: IP.Adr;
Gateway: IP.Adr;
Netmask: IP.Adr;
Prefix: IP.Adr;
DNS: ARRAY DNSMod.MaxNofServer OF IP.Adr;
next: InterfaceConfig;
END;
TYPE
RunnerDHCP = OBJECT
VAR
int: IP.Interface;
res: LONGINT;
PROCEDURE &Constr*(int: IP.Interface);
BEGIN
ASSERT(int # NIL);
SELF.int := int;
END Constr;
BEGIN {ACTIVE}
DHCP.RunDHCP(int, res);
IF res = 0 THEN
IP.OutInterface(int);
END;
END RunnerDHCP;
VAR
hasXMLErrors: BOOLEAN;
res: LONGINT;
PROCEDURE Error(pos, line, row: LONGINT; CONST msg: ARRAY OF CHAR);
BEGIN
KernelLog.String("Parse error in NetInit.XML at pos "); KernelLog.Int(pos, 5); KernelLog.String(" in line "); KernelLog.Int(line, 5);
KernelLog.String(" row "); KernelLog.Int(row, 5); KernelLog.String(" - "); KernelLog.String(msg); KernelLog.Ln;
hasXMLErrors := TRUE
END Error;
PROCEDURE GetConfig(CONST devName: ARRAY OF CHAR; VAR res:LONGINT): Config;
VAR
netConfigElem: XML.Element;
elem: XML.Element;
elemStr: Strings.String;
config: Config;
interfaceConfig: InterfaceConfig;
routerConfig: IPv6.RouterConfig;
prefixConfig: IPv6.PrefixConfig;
file: Files.File;
reader: Files.Reader;
scanner: XMLScanner.Scanner;
parser: XMLParser.Parser;
doc: XML.Document;
ipv4Elem: XML.Element;
ipv6Elem: XML.Element;
i: LONGINT;
interfaceElems: XMLObjects.ArrayCollection;
routerElems: XMLObjects.ArrayCollection;
prefixElems: XMLObjects.ArrayCollection;
dnsElems: XMLObjects.ArrayCollection;
intElem: XML.Element;
routerElem: XML.Element;
prefixElem: XML.Element;
interfaceNbr: LONGINT;
routerNbr: LONGINT;
prefixNbr: LONGINT;
attribute: XML.Attribute;
p: ANY;
PROCEDURE GetSection(elem: XML.Element; CONST sectionName: ARRAY OF CHAR): XML.Element;
VAR
enum: XMLObjects.Enumerator;
attribute: XML.Attribute;
section: XML.Element;
p: ANY;
elemStr: Strings.String;
BEGIN
IF elem # NIL THEN
enum := elem.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS XML.Element THEN
elemStr := p(XML.Element).GetName();
IF (elemStr^ = "Section") THEN
attribute := p(XML.Element). GetAttribute("name");
elemStr := attribute.GetValue();
IF elemStr^ = sectionName THEN
section := p(XML.Element);
END;
END;
END;
END;
END;
RETURN section;
END GetSection;
PROCEDURE GetSettingBool(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR bool: BOOLEAN);
VAR
nameAttr: XML.Attribute;
valueAttr: XML.Attribute;
nameStr: Strings.String;
valueStr: Strings.String;
elemStr: Strings.String;
settingFound: BOOLEAN;
enum: XMLObjects.Enumerator;
p: ANY;
BEGIN
settingFound := FALSE;
IF section # NIL THEN
enum := section.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS (XML.Element) THEN
elemStr := p(XML.Element).GetName();
IF (elemStr^ = "Setting") THEN
nameAttr := p(XML.Element).GetAttribute("name");
valueAttr := p(XML.Element).GetAttribute("value");
IF (nameAttr # NIL) & (valueAttr # NIL) THEN
nameStr := nameAttr.GetValue();
valueStr := valueAttr.GetValue();
IF nameStr^ = settingName THEN
Strings.StrToBool(valueStr^, bool);
settingFound := TRUE;
END;
END;
END;
END;
END;
ELSIF error THEN
hasXMLErrors := TRUE;
END;
IF ~settingFound & error THEN
hasXMLErrors := TRUE;
END;
END GetSettingBool;
PROCEDURE GetSettingInt(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR int : LONGINT);
VAR
nameAttr: XML.Attribute;
valueAttr: XML.Attribute;
nameStr: Strings.String;
valueStr: Strings.String;
elemStr: Strings.String;
settingFound: BOOLEAN;
enum: XMLObjects.Enumerator;
p: ANY;
BEGIN
settingFound := FALSE;
IF section # NIL THEN
enum := section.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS (XML.Element) THEN
elemStr := p(XML.Element).GetName();
IF (elemStr^ = "Setting") THEN
nameAttr := p(XML.Element).GetAttribute("name");
valueAttr := p(XML.Element).GetAttribute("value");
IF (nameAttr # NIL) & (valueAttr # NIL) THEN
nameStr := nameAttr.GetValue();
valueStr := valueAttr.GetValue();
IF nameStr^ = settingName THEN
Strings.StrToInt(valueStr^, int);
settingFound := TRUE;
END;
END;
END;
END;
END;
ELSIF error THEN
hasXMLErrors := TRUE;
END;
IF ~settingFound & error THEN
hasXMLErrors := TRUE;
END;
END GetSettingInt;
PROCEDURE GetSettingChars(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR chars: ARRAY OF CHAR);
VAR
nameAttr: XML.Attribute;
valueAttr: XML.Attribute;
nameStr: Strings.String;
valueStr: Strings.String;
elemStr: Strings.String;
settingFound: BOOLEAN;
enum: XMLObjects.Enumerator;
p: ANY;
BEGIN
settingFound := FALSE;
IF section # NIL THEN
enum := section.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS (XML.Element) THEN
elemStr := p(XML.Element).GetName();
IF (elemStr^ = "Setting") THEN
nameAttr := p(XML.Element).GetAttribute("name");
valueAttr := p(XML.Element).GetAttribute("value");
IF (nameAttr # NIL) & (valueAttr # NIL) THEN
nameStr := nameAttr.GetValue();
valueStr := valueAttr.GetValue();
IF nameStr^ = settingName THEN
COPY(valueStr^, chars);
settingFound := TRUE;
END;
END;
END;
END;
END;
ELSIF error THEN
hasXMLErrors := TRUE;
END;
IF ~settingFound & error THEN
hasXMLErrors := TRUE;
END;
END GetSettingChars;
PROCEDURE GetSettingString(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR string: Strings.String);
VAR
nameAttr: XML.Attribute;
valueAttr: XML.Attribute;
nameStr: Strings.String;
valueStr: Strings.String;
elemStr: Strings.String;
settingFound: BOOLEAN;
enum: XMLObjects.Enumerator;
p: ANY;
BEGIN
settingFound := FALSE;
IF section # NIL THEN
enum := section.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS (XML.Element) THEN
elemStr := p(XML.Element).GetName();
IF (elemStr^ = "Setting") THEN
nameAttr := p(XML.Element).GetAttribute("name");
valueAttr := p(XML.Element).GetAttribute("value");
IF (nameAttr # NIL) & (valueAttr # NIL) THEN
nameStr := nameAttr.GetValue();
valueStr := valueAttr.GetValue();
IF nameStr^ = settingName THEN
string := valueStr;
settingFound := TRUE;
END;
END;
END;
END;
END;
ELSIF error THEN
hasXMLErrors := TRUE;
END;
IF ~settingFound & error THEN
hasXMLErrors := TRUE;
END;
END GetSettingString;
PROCEDURE GetSettingAdr(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR adr: IP.Adr);
VAR
nameAttr: XML.Attribute;
valueAttr: XML.Attribute;
nameStr: Strings.String;
valueStr: Strings.String;
elemStr: Strings.String;
settingFound: BOOLEAN;
enum: XMLObjects.Enumerator;
p: ANY;
BEGIN
settingFound := FALSE;
IF section # NIL THEN
enum := section.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS (XML.Element) THEN
elemStr := p(XML.Element).GetName();
IF (elemStr^ = "Setting") THEN
nameAttr := p(XML.Element).GetAttribute("name");
valueAttr := p(XML.Element).GetAttribute("value");
IF (nameAttr # NIL) & (valueAttr # NIL) THEN
nameStr := nameAttr.GetValue();
valueStr := valueAttr.GetValue();
IF nameStr^ = settingName THEN
adr := IP.StrToAdr(valueStr^);
settingFound := TRUE;
END;
END;
END;
END;
END;
ELSIF error THEN
hasXMLErrors := TRUE;
END;
IF ~settingFound & error THEN
hasXMLErrors := TRUE;
END;
END GetSettingAdr;
PROCEDURE GetSettings(elem: XML.Element; CONST settingName: ARRAY OF CHAR): XMLObjects.ArrayCollection;
VAR
settingCol: XMLObjects.ArrayCollection;
enum: XMLObjects.Enumerator;
p: ANY;
elemName: Strings.String;
nameAttr: XML.Attribute;
nameStr: Strings.String;
BEGIN
IF elem # NIL THEN
NEW(settingCol);
enum := elem.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS XML.Element THEN
elemName := p(XML.Element).GetName();
IF elemName^ = "Setting" THEN
nameAttr := p(XML.Element).GetAttribute("name");
IF nameAttr # NIL THEN
nameStr := nameAttr.GetValue();
IF nameStr^ = settingName THEN
settingCol.Add(p(XML.Element));
END;
END;
END;
END;
END;
END;
RETURN settingCol;
END GetSettings;
PROCEDURE GetSections(elem: XML.Element; CONST sectionName: ARRAY OF CHAR): XMLObjects.ArrayCollection;
VAR
sectionCol: XMLObjects.ArrayCollection;
enum: XMLObjects.Enumerator;
p: ANY;
elemName: Strings.String;
nameAttr: XML.Attribute;
nameStr: Strings.String;
BEGIN
IF elem # NIL THEN
NEW(sectionCol);
enum := elem.GetContents();
WHILE enum.HasMoreElements() DO
p := enum.GetNext();
IF p IS XML.Element THEN
elemName := p(XML.Element).GetName();
IF elemName^ = "Section" THEN
nameAttr := p(XML.Element).GetAttribute("name");
IF nameAttr # NIL THEN
nameStr := nameAttr.GetValue();
IF nameStr^ = sectionName THEN
sectionCol.Add(p(XML.Element));
END;
END;
END;
END;
END;
END;
RETURN sectionCol;
END GetSections;
PROCEDURE Readv4Interface;
BEGIN
interfaceElems := GetSections(ipv4Elem, "Interface");
IF interfaceElems.GetNumberOfElements() # 0 THEN
FOR interfaceNbr := 0 TO interfaceElems.GetNumberOfElements() - 1 DO
p := interfaceElems.GetElement(interfaceNbr);
intElem :=p (XML.Element);
NEW(interfaceConfig);
FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
interfaceConfig.DNS[i] := IP.NilAdr;
END;
interfaceConfig.Device[0] := 0X;
interfaceConfig.Protocol := IP.IPv4;
interfaceConfig.Name := "";
interfaceConfig.Domain := NIL;
interfaceConfig.DHCP := TRUE;
interfaceConfig.LocalAdr := IP.NilAdr;
interfaceConfig.Gateway := IP.NilAdr;
interfaceConfig.Netmask := IP.NilAdr;
interfaceConfig.Prefix := IP.NilAdr;
GetSettingChars(intElem, "Device", TRUE, interfaceConfig.Device);
GetSettingChars(intElem, "Name", TRUE, interfaceConfig.Name);
GetSettingString(intElem, "Domain", FALSE, interfaceConfig.Domain);
GetSettingBool(intElem, "DHCP", FALSE, interfaceConfig.DHCP);
GetSettingAdr(intElem, "LocalAdr", FALSE, interfaceConfig.LocalAdr);
GetSettingAdr(intElem, "Gateway", FALSE, interfaceConfig.Gateway);
GetSettingAdr(intElem, "Netmask", FALSE, interfaceConfig.Netmask);
dnsElems := GetSettings(intElem, "DNS");
FOR i := 0 TO Strings.Min(dnsElems.GetNumberOfElements(), DNSMod.MaxNofServer) - 1 DO
p := dnsElems.GetElement(i);
elem := p(XML.Element);
attribute := elem.GetAttribute("value");
IF attribute # NIL THEN
elemStr := attribute.GetValue();
IF elemStr # NIL THEN
interfaceConfig.DNS[i] := IP.StrToAdr(elemStr^);
END;
END;
END;
IF (interfaceConfig # NIL) & (interfaceConfig.Device = devName) THEN
interfaceConfig.next := config.interfaceConfigs;
config.interfaceConfigs := interfaceConfig;
END;
END;
END;
END Readv4Interface;
PROCEDURE Readv6Interface;
BEGIN
interfaceElems := GetSections(ipv6Elem, "Interface");
IF interfaceElems.GetNumberOfElements() # 0 THEN
FOR interfaceNbr := 0 TO interfaceElems.GetNumberOfElements() - 1 DO
p := interfaceElems.GetElement(interfaceNbr);
intElem :=p (XML.Element);
NEW(interfaceConfig);
FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
interfaceConfig.DNS[i] := IP.NilAdr;
END;
interfaceConfig.Device[0] := 0X;
interfaceConfig.Protocol := IP.IPv6;
interfaceConfig.Name := "";
interfaceConfig.Domain := NIL;
interfaceConfig.DHCP := TRUE;
interfaceConfig.LocalAdr := IP.NilAdr;
interfaceConfig.Gateway := IP.NilAdr;
interfaceConfig.Netmask := IP.NilAdr;
interfaceConfig.Prefix := IP.NilAdr;
GetSettingChars(intElem, "Device", TRUE, interfaceConfig.Device);
GetSettingChars(intElem, "Name", TRUE, interfaceConfig.Name);
GetSettingString(intElem, "Domain", FALSE, interfaceConfig.Domain);
GetSettingBool(intElem, "DHCP", FALSE, interfaceConfig.DHCP);
GetSettingAdr(intElem, "LocalAdr", FALSE, interfaceConfig.LocalAdr);
GetSettingAdr(intElem, "Prefix", FALSE, interfaceConfig.Prefix);
dnsElems := GetSettings(intElem, "DNS");
FOR i := 0 TO Strings.Min(dnsElems.GetNumberOfElements(), DNSMod.MaxNofServer) - 1 DO
p := dnsElems.GetElement(i);
elem := p(XML.Element);
attribute := elem.GetAttribute("value");
IF attribute # NIL THEN
elemStr := attribute.GetValue();
IF elemStr # NIL THEN
interfaceConfig.DNS[i] := IP.StrToAdr(elemStr^);
END;
END;
END;
IF (interfaceConfig # NIL) & (interfaceConfig.Device = devName) THEN
interfaceConfig.next := config.interfaceConfigs;
config.interfaceConfigs := interfaceConfig;
END;
END;
END;
END Readv6Interface;
PROCEDURE ReadRouter;
BEGIN
routerElems := GetSections(ipv6Elem, "Router");
IF routerElems.GetNumberOfElements() # 0 THEN
FOR routerNbr := 0 TO routerElems.GetNumberOfElements() - 1 DO
p := routerElems.GetElement(routerNbr);
routerElem :=p (XML.Element);
NEW(routerConfig);
routerConfig.Device := "";
routerConfig.SendRouterAdvertisements := FALSE;
routerConfig.ManagedAddressConfig := FALSE;
routerConfig.OtherStatefulConfig := FALSE;
routerConfig.LinkMTU := 0;
routerConfig.ReachableTime := 0;
routerConfig.RetransTimer := 0;
routerConfig.CurrentHopLimit := 0;
routerConfig.Lifetime := 3 * 600;
routerConfig.Prefixes := NIL;
GetSettingChars(routerElem, "Device", TRUE, routerConfig.Device);
GetSettingBool(routerElem, "SendRouterAdvertisements", FALSE, routerConfig.SendRouterAdvertisements);
GetSettingBool(routerElem, "ManagedAddressConfig", FALSE, routerConfig.ManagedAddressConfig);
GetSettingBool(routerElem, "OtherStatefulConfig", FALSE, routerConfig.OtherStatefulConfig);
GetSettingInt(routerElem, "LinkMTU", FALSE, routerConfig.LinkMTU);
GetSettingInt(routerElem, "ReachableTime", FALSE, routerConfig.ReachableTime);
GetSettingInt(routerElem, "RetransTimer", FALSE, routerConfig.RetransTimer);
GetSettingInt(routerElem, "CurrentHopLimit", FALSE, routerConfig.CurrentHopLimit);
GetSettingInt(routerElem, "Lifetime", FALSE, routerConfig.Lifetime);
prefixElems := GetSections(routerElem, "Prefix");
IF prefixElems.GetNumberOfElements() # 0 THEN
FOR prefixNbr := 0 TO prefixElems.GetNumberOfElements() - 1 DO
p := prefixElems.GetElement(prefixNbr);
prefixElem :=p (XML.Element);
NEW(prefixConfig);
prefixConfig.Prefix := IP.NilAdr;
prefixConfig.IsSitePrefix := FALSE;
prefixConfig.ValidLifetime := 2592000;
prefixConfig.OnLink := TRUE;
prefixConfig.PreferredLifetime := 604800;
prefixConfig.Autonomous := TRUE;
GetSettingAdr(prefixElem, "Prefix", TRUE, prefixConfig.Prefix);
GetSettingBool(prefixElem, "IsSitePrefix", FALSE, prefixConfig.IsSitePrefix);
GetSettingInt(prefixElem, "ValidLifetime", FALSE, prefixConfig.ValidLifetime);
GetSettingBool(prefixElem, "OnLink", FALSE, prefixConfig.OnLink);
GetSettingInt(prefixElem, "PreferredLifetime", FALSE, prefixConfig.PreferredLifetime);
GetSettingBool(prefixElem, "Autonomous", FALSE, prefixConfig.Autonomous);
prefixConfig.next := routerConfig.Prefixes;
routerConfig.Prefixes := prefixConfig;
END;
END;
IF (routerConfig # NIL) & (routerConfig.Device = devName) THEN
routerConfig.next := config.routerConfigs;
config.routerConfigs := routerConfig;
END;
END;
END;
END ReadRouter;
BEGIN
hasXMLErrors := FALSE;
res := Ok;
NEW(config);
config.IPForwarding:= FALSE;
config.EchoReply := TRUE;
config.AutoNetConfigV4 := TRUE;
config.AutoNetConfigV6 := TRUE;
config.PreferredProtocol := IP.IPv4;
file := Files.Old("Configuration.XML");
IF file # NIL THEN
Files.OpenReader(reader, file, 0);
NEW(scanner, reader);
scanner.reportError := Error;
NEW(parser, scanner);
parser.reportError := Error;
doc := parser.Parse();
netConfigElem := doc.GetRoot();
netConfigElem := GetSection(netConfigElem, "NetConfig");
IF hasXMLErrors THEN
KernelLog.String("Net configuration not loaded"); KernelLog.Ln;
res := ConfigFileNotValid;
RETURN NIL;
END;
IF devName = "Loopback" THEN
NEW(interfaceConfig);
FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
interfaceConfig.DNS[i] := IP.NilAdr;
END;
COPY(devName, interfaceConfig.Device);
interfaceConfig.Protocol := IP.IPv4;
interfaceConfig.Name := "Loopbackv4";
interfaceConfig.Domain := NIL;
interfaceConfig.DHCP := FALSE;
interfaceConfig.LocalAdr := IP.StrToAdr("127.0.0.1");
interfaceConfig.Gateway := IP.NilAdr;
interfaceConfig.Netmask := IP.StrToAdr("255.255.0.0");
interfaceConfig.Prefix := IP.NilAdr;
interfaceConfig.next := config.interfaceConfigs;
config.interfaceConfigs := interfaceConfig;
NEW (interfaceConfig);
FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
interfaceConfig.DNS[i] := IP.NilAdr;
END;
COPY(devName, interfaceConfig.Device);
interfaceConfig.Protocol := IP.IPv6;
interfaceConfig.Name := "Loopbackv6";
interfaceConfig.Domain := NIL;
interfaceConfig.DHCP := FALSE;
interfaceConfig.LocalAdr := IP.StrToAdr("::1");
interfaceConfig.Gateway := IP.NilAdr;
interfaceConfig.Netmask := IP.NilAdr;
interfaceConfig.Prefix := IP.NilAdr;
interfaceConfig.Prefix.data := 64;
interfaceConfig.Prefix.usedProtocol := IP.IPv6;
interfaceConfig.next := config.interfaceConfigs;
config.interfaceConfigs := interfaceConfig;
END;
IF netConfigElem # NIL THEN
GetSettingBool(netConfigElem, "IPForwarding", FALSE, config.IPForwarding);
GetSettingBool(netConfigElem, "EchoReply", FALSE, config.EchoReply);
GetSettingInt(netConfigElem, "PreferredProtocol", FALSE, config.PreferredProtocol);
ipv4Elem := GetSection(netConfigElem, "IPv4");
IF ipv4Elem # NIL THEN
elem := GetSection(ipv4Elem, "AutoNetConfig");
IF elem # NIL THEN
GetSettingBool(elem, "Enabled", TRUE, config.AutoNetConfigV4);
ELSE
hasXMLErrors := TRUE;
END;
Readv4Interface;
ELSE
hasXMLErrors := TRUE;
END;
ipv6Elem := GetSection(netConfigElem, "IPv6");
IF ipv6Elem # NIL THEN
elem := GetSection(ipv6Elem, "AutoNetConfig");
IF elem # NIL THEN
GetSettingBool(elem, "Enabled", TRUE, config.AutoNetConfigV6);
dnsElems := GetSettings(elem, "DNS");
FOR i := 0 TO Strings.Min(dnsElems.GetNumberOfElements(), DNSMod.MaxNofServer) - 1 DO
p := dnsElems.GetElement(i);
elem := p(XML.Element);
attribute := elem.GetAttribute("value");
IF attribute # NIL THEN
elemStr := attribute.GetValue();
IF elemStr # NIL THEN
config.AutoNetConfigV6DNS[i] := IP.StrToAdr(elemStr^);
END;
END;
END;
ELSE
hasXMLErrors := TRUE;
END;
Readv6Interface;
ReadRouter;
ELSE
hasXMLErrors := TRUE;
END;
ELSE
hasXMLErrors := TRUE;
END;
IF config.interfaceConfigs = NIL THEN
NEW(interfaceConfig);
FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
interfaceConfig.DNS[i] := IP.NilAdr;
END;
interfaceConfig.Device[0] := 0X;
interfaceConfig.Protocol := 0;
interfaceConfig.Name := "";
interfaceConfig.Domain := NIL;
interfaceConfig.DHCP := TRUE;
interfaceConfig.LocalAdr := IP.NilAdr;
interfaceConfig.Gateway := IP.NilAdr;
interfaceConfig.Netmask := IP.NilAdr;
interfaceConfig.Prefix := IP.NilAdr;
interfaceConfig.next := NIL;
config.interfaceConfigs := interfaceConfig;
END;
RETURN config;
ELSE
KernelLog.String("Network configuration file (NetInit.XML) not found"); KernelLog.Ln;
res := NoConfigFile;
RETURN NIL;
END;
RETURN NIL;
END GetConfig;
PROCEDURE Added(dev: Network.LinkDevice);
VAR
config: Config;
interfaceConfigItem: InterfaceConfig;
ipv4IntFound: BOOLEAN;
runnerDHCP: RunnerDHCP;
int: IP.Interface;
intv4: IPv4.Interface;
intv6: IPv6.Interface;
intName: IP.Name;
i, res: LONGINT;
linkLocalAdr: IP.Adr;
linkLocalPrefix: IP.Adr;
routerConfigItem: IPv6.RouterConfig;
BEGIN
KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name); KernelLog.String("' found."); KernelLog.Ln;
config := GetConfig(dev.name, res);
KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name);
KernelLog.String("': Get interface configuration. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
IF res = Ok THEN
ipv4IntFound := FALSE;
IP.preferredProtocol := config.PreferredProtocol;
IP.IPForwarding := config.IPForwarding;
IP.EchoReply := config.EchoReply;
interfaceConfigItem := config.interfaceConfigs;
WHILE interfaceConfigItem # NIL DO
CASE interfaceConfigItem.Protocol OF
IP.IPv4:
NEW(intv4, interfaceConfigItem.Name, dev, res);
int := intv4;
|IP.IPv6:
NEW(intv6, interfaceConfigItem.Name, dev, res);
int := intv6;
ELSE
END;
IF (int # NIL) & (res = IP.Ok) THEN
IF int IS IPv4.Interface THEN
ipv4IntFound := TRUE;
int.SetAdrs(interfaceConfigItem.LocalAdr, interfaceConfigItem.Netmask, interfaceConfigItem.Gateway, res);
END;
IF int IS IPv6.Interface THEN
int.SetAdrs(interfaceConfigItem.LocalAdr, interfaceConfigItem.Prefix, interfaceConfigItem.Gateway, res);
END;
IF res = IP.Ok THEN
FOR i := 0 TO DNSMod.MaxNofServer - 1 DO
IF ~IP.IsNilAdr(interfaceConfigItem.DNS[i]) THEN
int.DNSAdd(interfaceConfigItem.DNS[i]);
END;
END;
i := 0;
IF interfaceConfigItem.DHCP THEN
NEW(runnerDHCP, int);
END;
KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
IF (res = Ok) & ~interfaceConfigItem.DHCP THEN
IP.OutInterface(int);
END;
END;
END;
interfaceConfigItem := interfaceConfigItem.next;
END;
IF config.AutoNetConfigV6 & (dev.name # "Loopback") THEN
Strings.Concat("v6link-local", dev.name, intName);
NEW (intv6, intName, dev, res);
int := intv6;
IF res = IP.Ok THEN
int(IPv6.Interface).autoconfigurated := TRUE;
linkLocalAdr := IP.NilAdr;
linkLocalPrefix := IP.NilAdr;
linkLocalPrefix.usedProtocol := IP.IPv6;
int(IPv6.Interface).SetInterfaceID(linkLocalAdr);
linkLocalAdr.ipv6Adr[0] := 0FEX;
linkLocalAdr.ipv6Adr[1] := 80X;
linkLocalPrefix.ipv6Adr[0] := 0FEX;
linkLocalPrefix.ipv6Adr[1] := 80X;
linkLocalPrefix.data := 64;
int.SetAdrs(linkLocalAdr, linkLocalPrefix, IP.NilAdr, res);
IF res = IP.Ok THEN
FOR i := 0 TO DNSMod.MaxNofServer - 1 DO
IF ~IP.IsNilAdr(config.AutoNetConfigV6DNS[i]) THEN
int.DNSAdd(config.AutoNetConfigV6DNS[i]);
END;
END;
KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
IP.OutInterface(int);
int(IPv6.Interface).createStatelessInterface := TRUE;
int(IPv6.Interface).RouterSolicitation;
routerConfigItem := config.routerConfigs;
WHILE (routerConfigItem # NIL) & (routerConfigItem.Device # dev.name) DO
routerConfigItem := routerConfigItem.next;
END;
IF routerConfigItem # NIL THEN
int(IPv6.Interface).ConfigAsRouter(routerConfigItem);
END;
END;
END;
END;
IF config.AutoNetConfigV4 & (dev.name # "Loopback") THEN
IF ~ipv4IntFound THEN
Strings.Concat("v4auto", dev.name, intName);
NEW(intv4, intName, dev, res);
int := intv4;
IF res = IP.Ok THEN
NEW(runnerDHCP, int);
KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
END;
END;
END;
END;
END Added;
PROCEDURE Removed(dev: Network.LinkDevice);
VAR int: IP.Interface;
BEGIN
KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name); KernelLog.String("' removed."); KernelLog.Ln;
int := IP.InterfaceByDevice(dev);
WHILE int # NIL DO
int.Close();
KernelLog.String("InitNetwork: IP Interface '"); KernelLog.String(int.name); KernelLog.String("' removed."); KernelLog.Ln;
int := IP.InterfaceByDevice(dev);
END;
END Removed;
PROCEDURE EventHandler(event: LONGINT; plugin: Plugins.Plugin);
BEGIN
IF event = Plugins.EventAdd THEN
Added(plugin(Network.LinkDevice));
ELSIF event = Plugins.EventRemove THEN
Removed(plugin(Network.LinkDevice));
ELSE
END;
END EventHandler;
PROCEDURE PluginHandler(plugin: Plugins.Plugin);
BEGIN
Added(plugin(Network.LinkDevice));
END PluginHandler;
PROCEDURE Init*;
END Init;
PROCEDURE Cleanup;
BEGIN
Network.registry.RemoveEventHandler(EventHandler, res);
ASSERT(res = Plugins.Ok);
END Cleanup;
BEGIN
ICMP.InitDelegates();
Network.registry.AddEventHandler(EventHandler, res);
ASSERT(res = Plugins.Ok);
Modules.InstallTermHandler(Cleanup);
KernelLog.String("InitNetwork: Module initialized. Searching for installed devices..."); KernelLog.Ln;
Network.registry.Enumerate(PluginHandler);
KernelLog.String("InitNetwork: Finished searching for installed devices."); KernelLog.Ln;
END InitNetwork.
(*
History:
01.11.2003 mvt Created
02.05.2005 eb Uses Configuration.XML
06.03.2006 sst Procedure Removed: remove all interfaces that belong to the device that is removed, not just one
*)