InitNetwork.Mod 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  1. MODULE InitNetwork; (** AUTHOR "mvt"; PURPOSE "IP interface initialization and configuration"; *)
  2. IMPORT Files, KernelLog, Modules, Plugins, Strings, XML, XMLObjects, XMLScanner,
  3. XMLParser,
  4. Network, IP, ICMP, DNSMod := DNS, DHCP, IPv4, IPv6; (* load all *)
  5. CONST
  6. (** Error Codes *)
  7. Ok* = 0;
  8. NotFound* = 4001;
  9. NoConfigFile* = 4002;
  10. ConfigFileNotValid* = 4003;
  11. MaxNofInterfaces* = 10; (** Interface numbers vom 0 to 9 are accepted in Machine config *)
  12. TYPE
  13. (* Interface and router config *)
  14. Config = POINTER TO RECORD
  15. interfaceConfigs: InterfaceConfig;
  16. routerConfigs: IPv6.RouterConfig;
  17. IPForwarding: BOOLEAN;
  18. EchoReply: BOOLEAN;
  19. PreferredProtocol: LONGINT;
  20. AutoNetConfigV4: BOOLEAN;
  21. AutoNetConfigV6: BOOLEAN;
  22. AutoNetConfigV6DNS: ARRAY DNSMod.MaxNofServer OF IP.Adr;
  23. END;
  24. (* A configuraton of a interface *)
  25. InterfaceConfig = POINTER TO RECORD
  26. Device: Plugins.Name;
  27. Protocol: LONGINT;
  28. Name: IP.Name;
  29. Domain: Strings.String;
  30. DHCP: BOOLEAN;
  31. LocalAdr: IP.Adr;
  32. Gateway: IP.Adr;
  33. Netmask: IP.Adr;
  34. Prefix: IP.Adr;
  35. DNS: ARRAY DNSMod.MaxNofServer OF IP.Adr;
  36. next: InterfaceConfig;
  37. END;
  38. TYPE
  39. (* Active object that runs DHCP on the specified interface. *)
  40. RunnerDHCP = OBJECT
  41. VAR
  42. int: IP.Interface;
  43. res: WORD;
  44. PROCEDURE &Constr*(int: IP.Interface);
  45. BEGIN
  46. ASSERT(int # NIL);
  47. SELF.int := int;
  48. END Constr;
  49. BEGIN {ACTIVE}
  50. DHCP.RunDHCP(int, res);
  51. IF res = 0 THEN
  52. IP.OutInterface(int);
  53. END;
  54. END RunnerDHCP;
  55. VAR
  56. hasXMLErrors: BOOLEAN;
  57. (* temporary variables used in module body *)
  58. res: WORD;
  59. (* Error output for XML parser *)
  60. PROCEDURE Error(pos, line, row: LONGINT; CONST msg: ARRAY OF CHAR);
  61. BEGIN
  62. KernelLog.String("Parse error in NetInit.XML at pos "); KernelLog.Int(pos, 5); KernelLog.String(" in line "); KernelLog.Int(line, 5);
  63. KernelLog.String(" row "); KernelLog.Int(row, 5); KernelLog.String(" - "); KernelLog.String(msg); KernelLog.Ln;
  64. hasXMLErrors := TRUE
  65. END Error;
  66. (**Get interface configurations from NetInit.XML for the specified device. *)
  67. PROCEDURE GetConfig(CONST devName: ARRAY OF CHAR; VAR res:WORD): Config;
  68. VAR
  69. netConfigElem: XML.Element;
  70. elem: XML.Element;
  71. elemStr: Strings.String;
  72. config: Config;
  73. interfaceConfig: InterfaceConfig;
  74. routerConfig: IPv6.RouterConfig;
  75. prefixConfig: IPv6.PrefixConfig;
  76. file: Files.File;
  77. reader: Files.Reader;
  78. scanner: XMLScanner.Scanner;
  79. parser: XMLParser.Parser;
  80. doc: XML.Document;
  81. ipv4Elem: XML.Element;
  82. ipv6Elem: XML.Element;
  83. i: LONGINT;
  84. interfaceElems: XMLObjects.ArrayCollection;
  85. routerElems: XMLObjects.ArrayCollection;
  86. prefixElems: XMLObjects.ArrayCollection;
  87. dnsElems: XMLObjects.ArrayCollection;
  88. intElem: XML.Element;
  89. routerElem: XML.Element;
  90. prefixElem: XML.Element;
  91. interfaceNbr: LONGINT;
  92. routerNbr: LONGINT;
  93. prefixNbr: LONGINT;
  94. attribute: XML.Attribute;
  95. p: ANY;
  96. (** Get a section with a specific name *)
  97. PROCEDURE GetSection(elem: XML.Element; CONST sectionName: ARRAY OF CHAR): XML.Element;
  98. VAR
  99. enum: XMLObjects.Enumerator;
  100. attribute: XML.Attribute;
  101. section: XML.Element;
  102. p: ANY;
  103. elemStr: Strings.String;
  104. BEGIN
  105. IF elem # NIL THEN
  106. enum := elem.GetContents();
  107. (* Search for elements equal "childName" *)
  108. WHILE enum.HasMoreElements() DO
  109. p := enum.GetNext();
  110. IF p IS XML.Element THEN
  111. elemStr := p(XML.Element).GetName();
  112. IF (elemStr^ = "Section") THEN
  113. attribute := p(XML.Element). GetAttribute("name");
  114. elemStr := attribute.GetValue();
  115. IF elemStr^ = sectionName THEN
  116. section := p(XML.Element);
  117. END;
  118. END;
  119. END;
  120. END;
  121. END;
  122. RETURN section;
  123. END GetSection;
  124. (** Sets a Boolean value from Setting of a section.
  125. If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
  126. PROCEDURE GetSettingBool(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR bool: BOOLEAN);
  127. VAR
  128. nameAttr: XML.Attribute;
  129. valueAttr: XML.Attribute;
  130. nameStr: Strings.String;
  131. valueStr: Strings.String;
  132. elemStr: Strings.String;
  133. settingFound: BOOLEAN;
  134. enum: XMLObjects.Enumerator;
  135. p: ANY;
  136. BEGIN
  137. settingFound := FALSE;
  138. IF section # NIL THEN
  139. enum := section.GetContents();
  140. (* Search for settings *)
  141. WHILE enum.HasMoreElements() DO
  142. p := enum.GetNext();
  143. IF p IS (XML.Element) THEN
  144. elemStr := p(XML.Element).GetName();
  145. IF (elemStr^ = "Setting") THEN
  146. nameAttr := p(XML.Element).GetAttribute("name");
  147. valueAttr := p(XML.Element).GetAttribute("value");
  148. IF (nameAttr # NIL) & (valueAttr # NIL) THEN
  149. nameStr := nameAttr.GetValue();
  150. valueStr := valueAttr.GetValue();
  151. IF nameStr^ = settingName THEN
  152. Strings.StrToBool(valueStr^, bool);
  153. settingFound := TRUE;
  154. END;
  155. END;
  156. END;
  157. END;
  158. END;
  159. ELSIF error THEN
  160. hasXMLErrors := TRUE;
  161. END;
  162. IF ~settingFound & error THEN
  163. hasXMLErrors := TRUE;
  164. END;
  165. END GetSettingBool;
  166. (** Sets a integer value from Setting of a section.
  167. If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
  168. PROCEDURE GetSettingInt(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR int : LONGINT);
  169. VAR
  170. nameAttr: XML.Attribute;
  171. valueAttr: XML.Attribute;
  172. nameStr: Strings.String;
  173. valueStr: Strings.String;
  174. elemStr: Strings.String;
  175. settingFound: BOOLEAN;
  176. enum: XMLObjects.Enumerator;
  177. p: ANY;
  178. BEGIN
  179. settingFound := FALSE;
  180. IF section # NIL THEN
  181. enum := section.GetContents();
  182. (* Search for settings *)
  183. WHILE enum.HasMoreElements() DO
  184. p := enum.GetNext();
  185. IF p IS (XML.Element) THEN
  186. elemStr := p(XML.Element).GetName();
  187. IF (elemStr^ = "Setting") THEN
  188. nameAttr := p(XML.Element).GetAttribute("name");
  189. valueAttr := p(XML.Element).GetAttribute("value");
  190. IF (nameAttr # NIL) & (valueAttr # NIL) THEN
  191. nameStr := nameAttr.GetValue();
  192. valueStr := valueAttr.GetValue();
  193. IF nameStr^ = settingName THEN
  194. Strings.StrToInt(valueStr^, int);
  195. settingFound := TRUE;
  196. END;
  197. END;
  198. END;
  199. END;
  200. END;
  201. ELSIF error THEN
  202. hasXMLErrors := TRUE;
  203. END;
  204. IF ~settingFound & error THEN
  205. hasXMLErrors := TRUE;
  206. END;
  207. END GetSettingInt;
  208. (** Sets a character array from Setting of a section.
  209. If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
  210. PROCEDURE GetSettingChars(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR chars: ARRAY OF CHAR);
  211. VAR
  212. nameAttr: XML.Attribute;
  213. valueAttr: XML.Attribute;
  214. nameStr: Strings.String;
  215. valueStr: Strings.String;
  216. elemStr: Strings.String;
  217. settingFound: BOOLEAN;
  218. enum: XMLObjects.Enumerator;
  219. p: ANY;
  220. BEGIN
  221. settingFound := FALSE;
  222. IF section # NIL THEN
  223. enum := section.GetContents();
  224. (* Search for settings *)
  225. WHILE enum.HasMoreElements() DO
  226. p := enum.GetNext();
  227. IF p IS (XML.Element) THEN
  228. elemStr := p(XML.Element).GetName();
  229. IF (elemStr^ = "Setting") THEN
  230. nameAttr := p(XML.Element).GetAttribute("name");
  231. valueAttr := p(XML.Element).GetAttribute("value");
  232. IF (nameAttr # NIL) & (valueAttr # NIL) THEN
  233. nameStr := nameAttr.GetValue();
  234. valueStr := valueAttr.GetValue();
  235. IF nameStr^ = settingName THEN
  236. COPY(valueStr^, chars);
  237. settingFound := TRUE;
  238. END;
  239. END;
  240. END;
  241. END;
  242. END;
  243. ELSIF error THEN
  244. hasXMLErrors := TRUE;
  245. END;
  246. IF ~settingFound & error THEN
  247. hasXMLErrors := TRUE;
  248. END;
  249. END GetSettingChars;
  250. (** Sets a string from Setting of a section.
  251. If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
  252. PROCEDURE GetSettingString(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR string: Strings.String);
  253. VAR
  254. nameAttr: XML.Attribute;
  255. valueAttr: XML.Attribute;
  256. nameStr: Strings.String;
  257. valueStr: Strings.String;
  258. elemStr: Strings.String;
  259. settingFound: BOOLEAN;
  260. enum: XMLObjects.Enumerator;
  261. p: ANY;
  262. BEGIN
  263. settingFound := FALSE;
  264. IF section # NIL THEN
  265. enum := section.GetContents();
  266. (* Search for settings *)
  267. WHILE enum.HasMoreElements() DO
  268. p := enum.GetNext();
  269. IF p IS (XML.Element) THEN
  270. elemStr := p(XML.Element).GetName();
  271. IF (elemStr^ = "Setting") THEN
  272. nameAttr := p(XML.Element).GetAttribute("name");
  273. valueAttr := p(XML.Element).GetAttribute("value");
  274. IF (nameAttr # NIL) & (valueAttr # NIL) THEN
  275. nameStr := nameAttr.GetValue();
  276. valueStr := valueAttr.GetValue();
  277. IF nameStr^ = settingName THEN
  278. string := valueStr;
  279. settingFound := TRUE;
  280. END;
  281. END;
  282. END;
  283. END;
  284. END;
  285. ELSIF error THEN
  286. hasXMLErrors := TRUE;
  287. END;
  288. IF ~settingFound & error THEN
  289. hasXMLErrors := TRUE;
  290. END;
  291. END GetSettingString;
  292. (** Sets an address from Setting of a section.
  293. If error is TRUE then hasXMLErrors is set to TRUE if child does not exist. *)
  294. PROCEDURE GetSettingAdr(section: XML.Element; CONST settingName: ARRAY OF CHAR; error: BOOLEAN; VAR adr: IP.Adr);
  295. VAR
  296. nameAttr: XML.Attribute;
  297. valueAttr: XML.Attribute;
  298. nameStr: Strings.String;
  299. valueStr: Strings.String;
  300. elemStr: Strings.String;
  301. settingFound: BOOLEAN;
  302. enum: XMLObjects.Enumerator;
  303. p: ANY;
  304. BEGIN
  305. settingFound := FALSE;
  306. IF section # NIL THEN
  307. enum := section.GetContents();
  308. (* Search for settings *)
  309. WHILE enum.HasMoreElements() DO
  310. p := enum.GetNext();
  311. IF p IS (XML.Element) THEN
  312. elemStr := p(XML.Element).GetName();
  313. IF (elemStr^ = "Setting") THEN
  314. nameAttr := p(XML.Element).GetAttribute("name");
  315. valueAttr := p(XML.Element).GetAttribute("value");
  316. IF (nameAttr # NIL) & (valueAttr # NIL) THEN
  317. nameStr := nameAttr.GetValue();
  318. valueStr := valueAttr.GetValue();
  319. IF nameStr^ = settingName THEN
  320. adr := IP.StrToAdr(valueStr^);
  321. settingFound := TRUE;
  322. END;
  323. END;
  324. END;
  325. END;
  326. END;
  327. ELSIF error THEN
  328. hasXMLErrors := TRUE;
  329. END;
  330. IF ~settingFound & error THEN
  331. hasXMLErrors := TRUE;
  332. END;
  333. END GetSettingAdr;
  334. (** Get a list of settings with specific name*)
  335. PROCEDURE GetSettings(elem: XML.Element; CONST settingName: ARRAY OF CHAR): XMLObjects.ArrayCollection;
  336. VAR
  337. settingCol: XMLObjects.ArrayCollection;
  338. enum: XMLObjects.Enumerator;
  339. p: ANY;
  340. elemName: Strings.String;
  341. nameAttr: XML.Attribute;
  342. nameStr: Strings.String;
  343. BEGIN
  344. IF elem # NIL THEN
  345. NEW(settingCol);
  346. enum := elem.GetContents();
  347. (* Search for settings equal "childName" *)
  348. WHILE enum.HasMoreElements() DO
  349. p := enum.GetNext();
  350. IF p IS XML.Element THEN
  351. elemName := p(XML.Element).GetName();
  352. IF elemName^ = "Setting" THEN
  353. nameAttr := p(XML.Element).GetAttribute("name");
  354. IF nameAttr # NIL THEN
  355. nameStr := nameAttr.GetValue();
  356. IF nameStr^ = settingName THEN
  357. settingCol.Add(p(XML.Element));
  358. END;
  359. END;
  360. END;
  361. END;
  362. END;
  363. END;
  364. RETURN settingCol;
  365. END GetSettings;
  366. (** Get a section with a specific name *)
  367. PROCEDURE GetSections(elem: XML.Element; CONST sectionName: ARRAY OF CHAR): XMLObjects.ArrayCollection;
  368. VAR
  369. sectionCol: XMLObjects.ArrayCollection;
  370. enum: XMLObjects.Enumerator;
  371. p: ANY;
  372. elemName: Strings.String;
  373. nameAttr: XML.Attribute;
  374. nameStr: Strings.String;
  375. BEGIN
  376. IF elem # NIL THEN
  377. NEW(sectionCol);
  378. enum := elem.GetContents();
  379. (* Search for sections equal "childName" *)
  380. WHILE enum.HasMoreElements() DO
  381. p := enum.GetNext();
  382. IF p IS XML.Element THEN
  383. elemName := p(XML.Element).GetName();
  384. IF elemName^ = "Section" THEN
  385. nameAttr := p(XML.Element).GetAttribute("name");
  386. IF nameAttr # NIL THEN
  387. nameStr := nameAttr.GetValue();
  388. IF nameStr^ = sectionName THEN
  389. sectionCol.Add(p(XML.Element));
  390. END;
  391. END;
  392. END;
  393. END;
  394. END;
  395. END;
  396. RETURN sectionCol;
  397. END GetSections;
  398. (* Read a IPv4 Interface *)
  399. PROCEDURE Readv4Interface;
  400. BEGIN
  401. interfaceElems := GetSections(ipv4Elem, "Interface");
  402. IF interfaceElems.GetNumberOfElements() # 0 THEN
  403. FOR interfaceNbr := 0 TO interfaceElems.GetNumberOfElements() - 1 DO
  404. p := interfaceElems.GetElement(interfaceNbr);
  405. intElem :=p (XML.Element);
  406. (* init config *)
  407. NEW(interfaceConfig);
  408. (*init config *)
  409. FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
  410. interfaceConfig.DNS[i] := IP.NilAdr;
  411. END;
  412. interfaceConfig.Device[0] := 0X;
  413. interfaceConfig.Protocol := IP.IPv4;
  414. interfaceConfig.Name := "";
  415. interfaceConfig.Domain := NIL;
  416. interfaceConfig.DHCP := TRUE;
  417. interfaceConfig.LocalAdr := IP.NilAdr;
  418. interfaceConfig.Gateway := IP.NilAdr;
  419. interfaceConfig.Netmask := IP.NilAdr;
  420. interfaceConfig.Prefix := IP.NilAdr;
  421. (* Device *)
  422. GetSettingChars(intElem, "Device", TRUE, interfaceConfig.Device);
  423. (* Name *)
  424. GetSettingChars(intElem, "Name", TRUE, interfaceConfig.Name);
  425. (* Domain *)
  426. GetSettingString(intElem, "Domain", FALSE, interfaceConfig.Domain);
  427. (* DHCP *)
  428. GetSettingBool(intElem, "DHCP", FALSE, interfaceConfig.DHCP);
  429. (* LocalAdr *)
  430. GetSettingAdr(intElem, "LocalAdr", FALSE, interfaceConfig.LocalAdr);
  431. (* Gateway *)
  432. GetSettingAdr(intElem, "Gateway", FALSE, interfaceConfig.Gateway);
  433. (* Netmask *)
  434. GetSettingAdr(intElem, "Netmask", FALSE, interfaceConfig.Netmask);
  435. (* DNS *)
  436. dnsElems := GetSettings(intElem, "DNS");
  437. FOR i := 0 TO Strings.Min(dnsElems.GetNumberOfElements(), DNSMod.MaxNofServer) - 1 DO
  438. p := dnsElems.GetElement(i);
  439. elem := p(XML.Element);
  440. attribute := elem.GetAttribute("value");
  441. IF attribute # NIL THEN
  442. elemStr := attribute.GetValue();
  443. IF elemStr # NIL THEN
  444. interfaceConfig.DNS[i] := IP.StrToAdr(elemStr^);
  445. END;
  446. END;
  447. END;
  448. (* IF configuration for right device save it *)
  449. IF (interfaceConfig # NIL) & (interfaceConfig.Device = devName) THEN
  450. interfaceConfig.next := config.interfaceConfigs;
  451. config.interfaceConfigs := interfaceConfig;
  452. END;
  453. END;
  454. END;
  455. END Readv4Interface;
  456. (* Read a IPv6 interface *)
  457. PROCEDURE Readv6Interface;
  458. BEGIN
  459. interfaceElems := GetSections(ipv6Elem, "Interface");
  460. IF interfaceElems.GetNumberOfElements() # 0 THEN
  461. FOR interfaceNbr := 0 TO interfaceElems.GetNumberOfElements() - 1 DO
  462. p := interfaceElems.GetElement(interfaceNbr);
  463. intElem :=p (XML.Element);
  464. (* init config *)
  465. NEW(interfaceConfig);
  466. (*init config *)
  467. FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
  468. interfaceConfig.DNS[i] := IP.NilAdr;
  469. END;
  470. interfaceConfig.Device[0] := 0X;
  471. interfaceConfig.Protocol := IP.IPv6;
  472. interfaceConfig.Name := "";
  473. interfaceConfig.Domain := NIL;
  474. interfaceConfig.DHCP := TRUE;
  475. interfaceConfig.LocalAdr := IP.NilAdr;
  476. interfaceConfig.Gateway := IP.NilAdr;
  477. interfaceConfig.Netmask := IP.NilAdr;
  478. interfaceConfig.Prefix := IP.NilAdr;
  479. (* Device *)
  480. GetSettingChars(intElem, "Device", TRUE, interfaceConfig.Device);
  481. (* Name *)
  482. GetSettingChars(intElem, "Name", TRUE, interfaceConfig.Name);
  483. (* Domain *)
  484. GetSettingString(intElem, "Domain", FALSE, interfaceConfig.Domain);
  485. (* DHCP *)
  486. GetSettingBool(intElem, "DHCP", FALSE, interfaceConfig.DHCP);
  487. (* LocalAdr *)
  488. GetSettingAdr(intElem, "LocalAdr", FALSE, interfaceConfig.LocalAdr);
  489. (*Prefix *)
  490. GetSettingAdr(intElem, "Prefix", FALSE, interfaceConfig.Prefix);
  491. (* DNS *)
  492. dnsElems := GetSettings(intElem, "DNS");
  493. FOR i := 0 TO Strings.Min(dnsElems.GetNumberOfElements(), DNSMod.MaxNofServer) - 1 DO
  494. p := dnsElems.GetElement(i);
  495. elem := p(XML.Element);
  496. attribute := elem.GetAttribute("value");
  497. IF attribute # NIL THEN
  498. elemStr := attribute.GetValue();
  499. IF elemStr # NIL THEN
  500. interfaceConfig.DNS[i] := IP.StrToAdr(elemStr^);
  501. END;
  502. END;
  503. END;
  504. (* IF configuration for right device save it *)
  505. IF (interfaceConfig # NIL) & (interfaceConfig.Device = devName) THEN
  506. interfaceConfig.next := config.interfaceConfigs;
  507. config.interfaceConfigs := interfaceConfig;
  508. END;
  509. END;
  510. END;
  511. END Readv6Interface;
  512. (* Read router configurations *)
  513. PROCEDURE ReadRouter;
  514. BEGIN
  515. routerElems := GetSections(ipv6Elem, "Router");
  516. IF routerElems.GetNumberOfElements() # 0 THEN
  517. FOR routerNbr := 0 TO routerElems.GetNumberOfElements() - 1 DO
  518. p := routerElems.GetElement(routerNbr);
  519. routerElem :=p (XML.Element);
  520. (* init router config *)
  521. NEW(routerConfig);
  522. (* Set defaults *)
  523. routerConfig.Device := "";
  524. routerConfig.SendRouterAdvertisements := FALSE;
  525. routerConfig.ManagedAddressConfig := FALSE;
  526. routerConfig.OtherStatefulConfig := FALSE;
  527. routerConfig.LinkMTU := 0; (* zero means don't send MTU option *)
  528. routerConfig.ReachableTime := 0;
  529. routerConfig.RetransTimer := 0;
  530. routerConfig.CurrentHopLimit := 0; (* unspecified *)
  531. routerConfig.Lifetime := 3 * 600; (* seconds *)
  532. routerConfig.Prefixes := NIL;
  533. (* Device *)
  534. GetSettingChars(routerElem, "Device", TRUE, routerConfig.Device);
  535. (* SendRouterAdvertisement *)
  536. GetSettingBool(routerElem, "SendRouterAdvertisements", FALSE, routerConfig.SendRouterAdvertisements);
  537. (* ManagedAddressConfig *)
  538. GetSettingBool(routerElem, "ManagedAddressConfig", FALSE, routerConfig.ManagedAddressConfig);
  539. (* OtherStatefulConfig *)
  540. GetSettingBool(routerElem, "OtherStatefulConfig", FALSE, routerConfig.OtherStatefulConfig);
  541. (* LinkMTU *)
  542. GetSettingInt(routerElem, "LinkMTU", FALSE, routerConfig.LinkMTU);
  543. (* ReachableTime *)
  544. GetSettingInt(routerElem, "ReachableTime", FALSE, routerConfig.ReachableTime);
  545. (* RetransTimer *)
  546. GetSettingInt(routerElem, "RetransTimer", FALSE, routerConfig.RetransTimer);
  547. (* Current Hop Limit *)
  548. GetSettingInt(routerElem, "CurrentHopLimit", FALSE, routerConfig.CurrentHopLimit);
  549. (* Lifetime *)
  550. GetSettingInt(routerElem, "Lifetime", FALSE, routerConfig.Lifetime);
  551. (* Parse prefixes *)
  552. prefixElems := GetSections(routerElem, "Prefix");
  553. IF prefixElems.GetNumberOfElements() # 0 THEN
  554. FOR prefixNbr := 0 TO prefixElems.GetNumberOfElements() - 1 DO
  555. p := prefixElems.GetElement(prefixNbr);
  556. prefixElem :=p (XML.Element);
  557. (* init prefix config *)
  558. NEW(prefixConfig);
  559. (* Set defaults *)
  560. prefixConfig.Prefix := IP.NilAdr;
  561. prefixConfig.IsSitePrefix := FALSE;
  562. prefixConfig.ValidLifetime := 2592000; (* in seconds is 30 days *)
  563. prefixConfig.OnLink := TRUE;
  564. prefixConfig.PreferredLifetime := 604800; (* in seconds is 7 days *)
  565. prefixConfig.Autonomous := TRUE;
  566. (* Prefix *)
  567. GetSettingAdr(prefixElem, "Prefix", TRUE, prefixConfig.Prefix);
  568. (* IsSitePrefix *)
  569. GetSettingBool(prefixElem, "IsSitePrefix", FALSE, prefixConfig.IsSitePrefix);
  570. (* ValidLifetime *)
  571. GetSettingInt(prefixElem, "ValidLifetime", FALSE, prefixConfig.ValidLifetime);
  572. (* OnLink *)
  573. GetSettingBool(prefixElem, "OnLink", FALSE, prefixConfig.OnLink);
  574. (* PreferredLifetime *)
  575. GetSettingInt(prefixElem, "PreferredLifetime", FALSE, prefixConfig.PreferredLifetime);
  576. (* Autonomous *)
  577. GetSettingBool(prefixElem, "Autonomous", FALSE, prefixConfig.Autonomous);
  578. prefixConfig.next := routerConfig.Prefixes;
  579. routerConfig.Prefixes := prefixConfig;
  580. END;
  581. END;
  582. (* IF configuration for right device save it *)
  583. IF (routerConfig # NIL) & (routerConfig.Device = devName) THEN
  584. routerConfig.next := config.routerConfigs;
  585. config.routerConfigs := routerConfig;
  586. END;
  587. END;
  588. END;
  589. END ReadRouter;
  590. BEGIN
  591. (* init *)
  592. hasXMLErrors := FALSE;
  593. res := Ok;
  594. NEW(config);
  595. config.IPForwarding:= FALSE; (* defaults *)
  596. config.EchoReply := TRUE;
  597. config.AutoNetConfigV4 := TRUE;
  598. config.AutoNetConfigV6 := TRUE;
  599. config.PreferredProtocol := IP.IPv4;
  600. (* Load NetInit.XML *)
  601. file := Files.Old("Configuration.XML");
  602. IF file # NIL THEN
  603. Files.OpenReader(reader, file, 0);
  604. NEW(scanner, reader);
  605. scanner.reportError := Error;
  606. NEW(parser, scanner);
  607. parser.reportError := Error;
  608. doc := parser.Parse();
  609. netConfigElem := doc.GetRoot();
  610. netConfigElem := GetSection(netConfigElem, "NetConfig");
  611. IF hasXMLErrors THEN
  612. KernelLog.String("Net configuration not loaded"); KernelLog.Ln;
  613. res := ConfigFileNotValid;
  614. RETURN NIL;
  615. END;
  616. IF devName = "Loopback" THEN
  617. (* Make two loopback configuration (IPv4, IPv6) *)
  618. NEW(interfaceConfig);
  619. (*init config for IPv4 *)
  620. FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
  621. interfaceConfig.DNS[i] := IP.NilAdr;
  622. END;
  623. COPY(devName, interfaceConfig.Device);
  624. interfaceConfig.Protocol := IP.IPv4;
  625. interfaceConfig.Name := "Loopbackv4";
  626. interfaceConfig.Domain := NIL;
  627. interfaceConfig.DHCP := FALSE;
  628. interfaceConfig.LocalAdr := IP.StrToAdr("127.0.0.1");
  629. interfaceConfig.Gateway := IP.NilAdr;
  630. interfaceConfig.Netmask := IP.StrToAdr("255.255.0.0");
  631. interfaceConfig.Prefix := IP.NilAdr;
  632. interfaceConfig.next := config.interfaceConfigs;
  633. config.interfaceConfigs := interfaceConfig;
  634. (* init config for IPv6 *)
  635. NEW (interfaceConfig);
  636. FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
  637. interfaceConfig.DNS[i] := IP.NilAdr;
  638. END;
  639. COPY(devName, interfaceConfig.Device);
  640. interfaceConfig.Protocol := IP.IPv6;
  641. interfaceConfig.Name := "Loopbackv6";
  642. interfaceConfig.Domain := NIL;
  643. interfaceConfig.DHCP := FALSE;
  644. interfaceConfig.LocalAdr := IP.StrToAdr("::1");
  645. interfaceConfig.Gateway := IP.NilAdr;
  646. interfaceConfig.Netmask := IP.NilAdr;
  647. interfaceConfig.Prefix := IP.NilAdr;
  648. interfaceConfig.Prefix.data := 64;
  649. interfaceConfig.Prefix.usedProtocol := IP.IPv6;
  650. interfaceConfig.next := config.interfaceConfigs;
  651. config.interfaceConfigs := interfaceConfig;
  652. END;
  653. IF netConfigElem # NIL THEN
  654. (* IPForwarding *)
  655. GetSettingBool(netConfigElem, "IPForwarding", FALSE, config.IPForwarding);
  656. (* EchoReply *)
  657. GetSettingBool(netConfigElem, "EchoReply", FALSE, config.EchoReply);
  658. (* Preferred protocol *)
  659. GetSettingInt(netConfigElem, "PreferredProtocol", FALSE, config.PreferredProtocol);
  660. (* IPv4 *)
  661. ipv4Elem := GetSection(netConfigElem, "IPv4");
  662. IF ipv4Elem # NIL THEN
  663. (* AutoNetConfig *)
  664. elem := GetSection(ipv4Elem, "AutoNetConfig");
  665. IF elem # NIL THEN
  666. GetSettingBool(elem, "Enabled", TRUE, config.AutoNetConfigV4);
  667. ELSE
  668. hasXMLErrors := TRUE;
  669. END;
  670. Readv4Interface;
  671. ELSE
  672. hasXMLErrors := TRUE;
  673. END;
  674. (* IPv6 *)
  675. ipv6Elem := GetSection(netConfigElem, "IPv6");
  676. IF ipv6Elem # NIL THEN
  677. (* AutoNetConfig *)
  678. elem := GetSection(ipv6Elem, "AutoNetConfig");
  679. IF elem # NIL THEN
  680. (* Enabled *)
  681. GetSettingBool(elem, "Enabled", TRUE, config.AutoNetConfigV6);
  682. (* DNS *)
  683. dnsElems := GetSettings(elem, "DNS");
  684. FOR i := 0 TO Strings.Min(dnsElems.GetNumberOfElements(), DNSMod.MaxNofServer) - 1 DO
  685. p := dnsElems.GetElement(i);
  686. elem := p(XML.Element);
  687. attribute := elem.GetAttribute("value");
  688. IF attribute # NIL THEN
  689. elemStr := attribute.GetValue();
  690. IF elemStr # NIL THEN
  691. config.AutoNetConfigV6DNS[i] := IP.StrToAdr(elemStr^);
  692. END;
  693. END;
  694. END;
  695. ELSE
  696. hasXMLErrors := TRUE;
  697. END;
  698. Readv6Interface;
  699. ReadRouter;
  700. ELSE
  701. hasXMLErrors := TRUE;
  702. END;
  703. ELSE
  704. hasXMLErrors := TRUE;
  705. END;
  706. IF config.interfaceConfigs = NIL THEN
  707. (* No configuration for this device, deliver config with only IPForwarding, EchoReplay, AutoNetConfig *)
  708. NEW(interfaceConfig);
  709. (*init config *)
  710. FOR i := 0 TO LEN(interfaceConfig.DNS) - 1 DO
  711. interfaceConfig.DNS[i] := IP.NilAdr;
  712. END;
  713. interfaceConfig.Device[0] := 0X;
  714. interfaceConfig.Protocol := 0;
  715. interfaceConfig.Name := "";
  716. interfaceConfig.Domain := NIL;
  717. interfaceConfig.DHCP := TRUE;
  718. interfaceConfig.LocalAdr := IP.NilAdr;
  719. interfaceConfig.Gateway := IP.NilAdr;
  720. interfaceConfig.Netmask := IP.NilAdr;
  721. interfaceConfig.Prefix := IP.NilAdr;
  722. interfaceConfig.next := NIL;
  723. config.interfaceConfigs := interfaceConfig;
  724. END;
  725. RETURN config;
  726. ELSE
  727. KernelLog.String("Network configuration file (NetInit.XML) not found"); KernelLog.Ln;
  728. res := NoConfigFile;
  729. RETURN NIL;
  730. END;
  731. RETURN NIL;
  732. END GetConfig;
  733. PROCEDURE Added(dev: Network.LinkDevice);
  734. VAR
  735. config: Config;
  736. interfaceConfigItem: InterfaceConfig;
  737. ipv4IntFound: BOOLEAN;
  738. runnerDHCP: RunnerDHCP;
  739. int: IP.Interface; (* if autoconf = true; there are two ip interfaces (v4 & v6) *)
  740. intv4: IPv4.Interface;
  741. intv6: IPv6.Interface;
  742. intName: IP.Name; (* if autoconf = true; there are two ip interfaces (v4 & v6) *)
  743. i, res: LONGINT;
  744. linkLocalAdr: IP.Adr;
  745. linkLocalPrefix: IP.Adr;
  746. routerConfigItem: IPv6.RouterConfig;
  747. BEGIN
  748. KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name); KernelLog.String("' found."); KernelLog.Ln;
  749. config := GetConfig(dev.name, res);
  750. KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name);
  751. KernelLog.String("': Get interface configuration. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  752. IF res = Ok THEN
  753. (* auto configuration: an IPv4 interface per device *)
  754. ipv4IntFound := FALSE;
  755. IP.preferredProtocol := config.PreferredProtocol;
  756. IP.IPForwarding := config.IPForwarding;
  757. IP.EchoReply := config.EchoReply;
  758. interfaceConfigItem := config.interfaceConfigs;
  759. WHILE interfaceConfigItem # NIL DO
  760. (* IPv4 or IPv6 interface? *)
  761. CASE interfaceConfigItem.Protocol OF
  762. IP.IPv4:
  763. NEW(intv4, interfaceConfigItem.Name, dev, res);
  764. int := intv4;
  765. |IP.IPv6:
  766. NEW(intv6, interfaceConfigItem.Name, dev, res);
  767. int := intv6;
  768. ELSE
  769. END;
  770. IF (int # NIL) & (res = IP.Ok) THEN
  771. IF int IS IPv4.Interface THEN
  772. ipv4IntFound := TRUE;
  773. int.SetAdrs(interfaceConfigItem.LocalAdr, interfaceConfigItem.Netmask, interfaceConfigItem.Gateway, res);
  774. END;
  775. IF int IS IPv6.Interface THEN
  776. int.SetAdrs(interfaceConfigItem.LocalAdr, interfaceConfigItem.Prefix, interfaceConfigItem.Gateway, res);
  777. END;
  778. IF res = IP.Ok THEN
  779. FOR i := 0 TO DNSMod.MaxNofServer - 1 DO
  780. IF ~IP.IsNilAdr(interfaceConfigItem.DNS[i]) THEN
  781. int.DNSAdd(interfaceConfigItem.DNS[i]);
  782. END;
  783. END;
  784. i := 0;
  785. IF interfaceConfigItem.DHCP THEN
  786. NEW(runnerDHCP, int);
  787. END;
  788. KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  789. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  790. IF (res = Ok) & ~interfaceConfigItem.DHCP THEN
  791. IP.OutInterface(int);
  792. END;
  793. END;
  794. END;
  795. interfaceConfigItem := interfaceConfigItem.next;
  796. END;
  797. IF config.AutoNetConfigV6 & (dev.name # "Loopback") THEN
  798. (* create a link-local IPv6 interface *)
  799. Strings.Concat("v6link-local", dev.name, intName);
  800. NEW (intv6, intName, dev, res);
  801. int := intv6;
  802. IF res = IP.Ok THEN
  803. int(IPv6.Interface).autoconfigurated := TRUE;
  804. linkLocalAdr := IP.NilAdr;
  805. linkLocalPrefix := IP.NilAdr;
  806. linkLocalPrefix.usedProtocol := IP.IPv6;
  807. int(IPv6.Interface).SetInterfaceID(linkLocalAdr);
  808. (* write link local prefix and prefix *)
  809. linkLocalAdr.ipv6Adr[0] := 0FEX;
  810. linkLocalAdr.ipv6Adr[1] := 80X;
  811. linkLocalPrefix.ipv6Adr[0] := 0FEX;
  812. linkLocalPrefix.ipv6Adr[1] := 80X;
  813. linkLocalPrefix.data := 64;
  814. int.SetAdrs(linkLocalAdr, linkLocalPrefix, IP.NilAdr, res);
  815. IF res = IP.Ok THEN
  816. FOR i := 0 TO DNSMod.MaxNofServer - 1 DO
  817. IF ~IP.IsNilAdr(config.AutoNetConfigV6DNS[i]) THEN
  818. int.DNSAdd(config.AutoNetConfigV6DNS[i]);
  819. END;
  820. END;
  821. KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  822. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  823. IP.OutInterface(int);
  824. (* initiate Routers Solicitation for auto-address-configuration *)
  825. int(IPv6.Interface).createStatelessInterface := TRUE;
  826. int(IPv6.Interface).RouterSolicitation;
  827. (* Is this device a router? *)
  828. routerConfigItem := config.routerConfigs;
  829. (* search for current device *)
  830. WHILE (routerConfigItem # NIL) & (routerConfigItem.Device # dev.name) DO
  831. routerConfigItem := routerConfigItem.next;
  832. END;
  833. IF routerConfigItem # NIL THEN
  834. (* found a router configuration *)
  835. int(IPv6.Interface).ConfigAsRouter(routerConfigItem);
  836. END;
  837. END;
  838. END;
  839. END;
  840. IF config.AutoNetConfigV4 & (dev.name # "Loopback") THEN
  841. (* create automatic IPv4 interface if there is none *)
  842. IF ~ipv4IntFound THEN
  843. (* create an ipv4 interface (DHCP on) *)
  844. Strings.Concat("v4auto", dev.name, intName);
  845. NEW(intv4, intName, dev, res);
  846. int := intv4;
  847. IF res = IP.Ok THEN
  848. NEW(runnerDHCP, int);
  849. KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  850. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  851. END;
  852. END;
  853. END;
  854. END;
  855. END Added;
  856. (* Called for each LinkDevice that was removed from the registry. Remove the according interfaces. *)
  857. PROCEDURE Removed(dev: Network.LinkDevice);
  858. VAR int: IP.Interface;
  859. BEGIN
  860. KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name); KernelLog.String("' removed."); KernelLog.Ln;
  861. int := IP.InterfaceByDevice(dev);
  862. WHILE int # NIL DO
  863. int.Close();
  864. KernelLog.String("InitNetwork: IP Interface '"); KernelLog.String(int.name); KernelLog.String("' removed."); KernelLog.Ln;
  865. int := IP.InterfaceByDevice(dev);
  866. END;
  867. END Removed;
  868. (* Handle events of installed/removed devices *)
  869. PROCEDURE EventHandler(event: WORD; plugin: Plugins.Plugin);
  870. BEGIN
  871. IF event = Plugins.EventAdd THEN
  872. Added(plugin(Network.LinkDevice));
  873. ELSIF event = Plugins.EventRemove THEN
  874. Removed(plugin(Network.LinkDevice));
  875. ELSE
  876. (* unknown event *)
  877. END;
  878. END EventHandler;
  879. (* Handler for Enumerate() *)
  880. PROCEDURE PluginHandler(plugin: Plugins.Plugin);
  881. BEGIN
  882. Added(plugin(Network.LinkDevice));
  883. END PluginHandler;
  884. (** Initialize the IP stack and configure all IP interfaces. *)
  885. PROCEDURE Init*;
  886. END Init;
  887. PROCEDURE Cleanup;
  888. BEGIN
  889. Network.registry.RemoveEventHandler(EventHandler, res);
  890. ASSERT(res = Plugins.Ok);
  891. END Cleanup;
  892. BEGIN
  893. ICMP.InitDelegates();
  894. Network.registry.AddEventHandler(EventHandler, res);
  895. ASSERT(res = Plugins.Ok);
  896. Modules.InstallTermHandler(Cleanup);
  897. (* Handle all previously installed devices *)
  898. KernelLog.String("InitNetwork: Module initialized. Searching for installed devices..."); KernelLog.Ln;
  899. Network.registry.Enumerate(PluginHandler);
  900. KernelLog.String("InitNetwork: Finished searching for installed devices."); KernelLog.Ln;
  901. END InitNetwork.
  902. (*
  903. History:
  904. 01.11.2003 mvt Created
  905. 02.05.2005 eb Uses Configuration.XML
  906. 06.03.2006 sst Procedure Removed: remove all interfaces that belong to the device that is removed, not just one
  907. *)