12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058 |
- MODULE InitNetwork; (** AUTHOR "mvt"; PURPOSE "IP interface initialization and configuration"; *)
- IMPORT Files, KernelLog, Modules, Plugins, Strings, XML, XMLObjects, XMLScanner,
- XMLParser,
- Network, IP, ICMP, DNSMod := DNS, DHCP, IPv4, IPv6; (* load all *)
- CONST
- (** Error Codes *)
- Ok* = 0;
- NotFound* = 4001;
- NoConfigFile* = 4002;
- ConfigFileNotValid* = 4003;
- MaxNofInterfaces* = 10; (** Interface numbers vom 0 to 9 are accepted in Machine config *)
- TYPE
- (* Interface and router config *)
- 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;
- (* A configuraton of a interface *)
- 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
- (* Active object that runs DHCP on the specified interface. *)
- RunnerDHCP = OBJECT
- VAR
- int: IP.Interface;
- res: WORD;
- 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;
- (* temporary variables used in module body *)
- res: WORD;
- (* Error output for XML parser *)
- 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;
- (**Get interface configurations from NetInit.XML for the specified device. *)
- PROCEDURE GetConfig(CONST devName: ARRAY OF CHAR; VAR res:WORD): 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;
- (** Get a section with a specific name *)
- 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();
- (* Search for elements equal "childName" *)
- 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;
- (** Sets a Boolean value from Setting of a section.
- If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
- 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();
- (* Search for settings *)
- 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;
- (** Sets a integer value from Setting of a section.
- If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
- 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();
- (* Search for settings *)
- 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;
- (** Sets a character array from Setting of a section.
- If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
- 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();
- (* Search for settings *)
- 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;
- (** Sets a string from Setting of a section.
- If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
- 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();
- (* Search for settings *)
- 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;
- (** Sets an address from Setting of a section.
- If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
- 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();
- (* Search for settings *)
- 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;
- (** Get a list of settings with specific name*)
- 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();
- (* Search for settings equal "childName" *)
- 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;
- (** Get a section with a specific name *)
- 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();
- (* Search for sections equal "childName" *)
- 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;
- (* Read a IPv4 Interface *)
- 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);
- (* init config *)
- NEW(interfaceConfig);
- (*init config *)
- 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;
- (* Device *)
- GetSettingChars(intElem, "Device", TRUE, interfaceConfig.Device);
- (* Name *)
- GetSettingChars(intElem, "Name", TRUE, interfaceConfig.Name);
- (* Domain *)
- GetSettingString(intElem, "Domain", FALSE, interfaceConfig.Domain);
- (* DHCP *)
- GetSettingBool(intElem, "DHCP", FALSE, interfaceConfig.DHCP);
- (* LocalAdr *)
- GetSettingAdr(intElem, "LocalAdr", FALSE, interfaceConfig.LocalAdr);
- (* Gateway *)
- GetSettingAdr(intElem, "Gateway", FALSE, interfaceConfig.Gateway);
- (* Netmask *)
- GetSettingAdr(intElem, "Netmask", FALSE, interfaceConfig.Netmask);
- (* DNS *)
- 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 configuration for right device save it *)
- IF (interfaceConfig # NIL) & (interfaceConfig.Device = devName) THEN
- interfaceConfig.next := config.interfaceConfigs;
- config.interfaceConfigs := interfaceConfig;
- END;
- END;
- END;
- END Readv4Interface;
- (* Read a IPv6 interface *)
- 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);
- (* init config *)
- NEW(interfaceConfig);
- (*init config *)
- 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;
- (* Device *)
- GetSettingChars(intElem, "Device", TRUE, interfaceConfig.Device);
- (* Name *)
- GetSettingChars(intElem, "Name", TRUE, interfaceConfig.Name);
- (* Domain *)
- GetSettingString(intElem, "Domain", FALSE, interfaceConfig.Domain);
- (* DHCP *)
- GetSettingBool(intElem, "DHCP", FALSE, interfaceConfig.DHCP);
- (* LocalAdr *)
- GetSettingAdr(intElem, "LocalAdr", FALSE, interfaceConfig.LocalAdr);
- (*Prefix *)
- GetSettingAdr(intElem, "Prefix", FALSE, interfaceConfig.Prefix);
- (* DNS *)
- 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 configuration for right device save it *)
- IF (interfaceConfig # NIL) & (interfaceConfig.Device = devName) THEN
- interfaceConfig.next := config.interfaceConfigs;
- config.interfaceConfigs := interfaceConfig;
- END;
- END;
- END;
- END Readv6Interface;
- (* Read router configurations *)
- 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);
- (* init router config *)
- NEW(routerConfig);
- (* Set defaults *)
- routerConfig.Device := "";
- routerConfig.SendRouterAdvertisements := FALSE;
- routerConfig.ManagedAddressConfig := FALSE;
- routerConfig.OtherStatefulConfig := FALSE;
- routerConfig.LinkMTU := 0; (* zero means don't send MTU option *)
- routerConfig.ReachableTime := 0;
- routerConfig.RetransTimer := 0;
- routerConfig.CurrentHopLimit := 0; (* unspecified *)
- routerConfig.Lifetime := 3 * 600; (* seconds *)
- routerConfig.Prefixes := NIL;
- (* Device *)
- GetSettingChars(routerElem, "Device", TRUE, routerConfig.Device);
- (* SendRouterAdvertisement *)
- GetSettingBool(routerElem, "SendRouterAdvertisements", FALSE, routerConfig.SendRouterAdvertisements);
- (* ManagedAddressConfig *)
- GetSettingBool(routerElem, "ManagedAddressConfig", FALSE, routerConfig.ManagedAddressConfig);
- (* OtherStatefulConfig *)
- GetSettingBool(routerElem, "OtherStatefulConfig", FALSE, routerConfig.OtherStatefulConfig);
- (* LinkMTU *)
- GetSettingInt(routerElem, "LinkMTU", FALSE, routerConfig.LinkMTU);
- (* ReachableTime *)
- GetSettingInt(routerElem, "ReachableTime", FALSE, routerConfig.ReachableTime);
- (* RetransTimer *)
- GetSettingInt(routerElem, "RetransTimer", FALSE, routerConfig.RetransTimer);
- (* Current Hop Limit *)
- GetSettingInt(routerElem, "CurrentHopLimit", FALSE, routerConfig.CurrentHopLimit);
- (* Lifetime *)
- GetSettingInt(routerElem, "Lifetime", FALSE, routerConfig.Lifetime);
- (* Parse prefixes *)
- 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);
- (* init prefix config *)
- NEW(prefixConfig);
- (* Set defaults *)
- prefixConfig.Prefix := IP.NilAdr;
- prefixConfig.IsSitePrefix := FALSE;
- prefixConfig.ValidLifetime := 2592000; (* in seconds is 30 days *)
- prefixConfig.OnLink := TRUE;
- prefixConfig.PreferredLifetime := 604800; (* in seconds is 7 days *)
- prefixConfig.Autonomous := TRUE;
- (* Prefix *)
- GetSettingAdr(prefixElem, "Prefix", TRUE, prefixConfig.Prefix);
- (* IsSitePrefix *)
- GetSettingBool(prefixElem, "IsSitePrefix", FALSE, prefixConfig.IsSitePrefix);
- (* ValidLifetime *)
- GetSettingInt(prefixElem, "ValidLifetime", FALSE, prefixConfig.ValidLifetime);
- (* OnLink *)
- GetSettingBool(prefixElem, "OnLink", FALSE, prefixConfig.OnLink);
- (* PreferredLifetime *)
- GetSettingInt(prefixElem, "PreferredLifetime", FALSE, prefixConfig.PreferredLifetime);
- (* Autonomous *)
- GetSettingBool(prefixElem, "Autonomous", FALSE, prefixConfig.Autonomous);
- prefixConfig.next := routerConfig.Prefixes;
- routerConfig.Prefixes := prefixConfig;
- END;
- END;
- (* IF configuration for right device save it *)
- IF (routerConfig # NIL) & (routerConfig.Device = devName) THEN
- routerConfig.next := config.routerConfigs;
- config.routerConfigs := routerConfig;
- END;
- END;
- END;
- END ReadRouter;
- BEGIN
- (* init *)
- hasXMLErrors := FALSE;
- res := Ok;
- NEW(config);
- config.IPForwarding:= FALSE; (* defaults *)
- config.EchoReply := TRUE;
- config.AutoNetConfigV4 := TRUE;
- config.AutoNetConfigV6 := TRUE;
- config.PreferredProtocol := IP.IPv4;
- (* Load NetInit.XML *)
- 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
- (* Make two loopback configuration (IPv4, IPv6) *)
- NEW(interfaceConfig);
- (*init config for IPv4 *)
- 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;
- (* init config for IPv6 *)
- 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
- (* IPForwarding *)
- GetSettingBool(netConfigElem, "IPForwarding", FALSE, config.IPForwarding);
- (* EchoReply *)
- GetSettingBool(netConfigElem, "EchoReply", FALSE, config.EchoReply);
- (* Preferred protocol *)
- GetSettingInt(netConfigElem, "PreferredProtocol", FALSE, config.PreferredProtocol);
- (* IPv4 *)
- ipv4Elem := GetSection(netConfigElem, "IPv4");
- IF ipv4Elem # NIL THEN
- (* AutoNetConfig *)
- elem := GetSection(ipv4Elem, "AutoNetConfig");
- IF elem # NIL THEN
- GetSettingBool(elem, "Enabled", TRUE, config.AutoNetConfigV4);
- ELSE
- hasXMLErrors := TRUE;
- END;
- Readv4Interface;
- ELSE
- hasXMLErrors := TRUE;
- END;
- (* IPv6 *)
- ipv6Elem := GetSection(netConfigElem, "IPv6");
- IF ipv6Elem # NIL THEN
- (* AutoNetConfig *)
- elem := GetSection(ipv6Elem, "AutoNetConfig");
- IF elem # NIL THEN
- (* Enabled *)
- GetSettingBool(elem, "Enabled", TRUE, config.AutoNetConfigV6);
- (* DNS *)
- 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
- (* No configuration for this device, deliver config with only IPForwarding, EchoReplay, AutoNetConfig *)
- NEW(interfaceConfig);
- (*init config *)
- 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; (* if autoconf = true; there are two ip interfaces (v4 & v6) *)
- intv4: IPv4.Interface;
- intv6: IPv6.Interface;
- intName: IP.Name; (* if autoconf = true; there are two ip interfaces (v4 & v6) *)
- 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
- (* auto configuration: an IPv4 interface per device *)
- ipv4IntFound := FALSE;
- IP.preferredProtocol := config.PreferredProtocol;
- IP.IPForwarding := config.IPForwarding;
- IP.EchoReply := config.EchoReply;
- interfaceConfigItem := config.interfaceConfigs;
- WHILE interfaceConfigItem # NIL DO
- (* IPv4 or IPv6 interface? *)
- 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
- (* create a link-local IPv6 interface *)
- 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);
- (* write link local prefix and prefix *)
- 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);
- (* initiate Routers Solicitation for auto-address-configuration *)
- int(IPv6.Interface).createStatelessInterface := TRUE;
- int(IPv6.Interface).RouterSolicitation;
- (* Is this device a router? *)
- routerConfigItem := config.routerConfigs;
- (* search for current device *)
- WHILE (routerConfigItem # NIL) & (routerConfigItem.Device # dev.name) DO
- routerConfigItem := routerConfigItem.next;
- END;
- IF routerConfigItem # NIL THEN
- (* found a router configuration *)
- int(IPv6.Interface).ConfigAsRouter(routerConfigItem);
- END;
- END;
- END;
- END;
- IF config.AutoNetConfigV4 & (dev.name # "Loopback") THEN
- (* create automatic IPv4 interface if there is none *)
- IF ~ipv4IntFound THEN
- (* create an ipv4 interface (DHCP on) *)
- 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;
- (* Called for each LinkDevice that was removed from the registry. Remove the according interfaces. *)
- 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;
- (* Handle events of installed/removed devices *)
- PROCEDURE EventHandler(event: WORD; plugin: Plugins.Plugin);
- BEGIN
- IF event = Plugins.EventAdd THEN
- Added(plugin(Network.LinkDevice));
- ELSIF event = Plugins.EventRemove THEN
- Removed(plugin(Network.LinkDevice));
- ELSE
- (* unknown event *)
- END;
- END EventHandler;
- (* Handler for Enumerate() *)
- PROCEDURE PluginHandler(plugin: Plugins.Plugin);
- BEGIN
- Added(plugin(Network.LinkDevice));
- END PluginHandler;
- (** Initialize the IP stack and configure all IP interfaces. *)
- 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);
- (* Handle all previously installed devices *)
- 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
- *)
|