123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059 |
- 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 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 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 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: LONGINT;
- res: WORD;
- 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
- *)
|