InitNetwork.Mod 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  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 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 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 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: LONGINT;
  744. res: WORD;
  745. linkLocalAdr: IP.Adr;
  746. linkLocalPrefix: IP.Adr;
  747. routerConfigItem: IPv6.RouterConfig;
  748. BEGIN
  749. KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name); KernelLog.String("' found."); KernelLog.Ln;
  750. config := GetConfig(dev.name, res);
  751. KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name);
  752. KernelLog.String("': Get interface configuration. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  753. IF res = Ok THEN
  754. (* auto configuration: an IPv4 interface per device *)
  755. ipv4IntFound := FALSE;
  756. IP.preferredProtocol := config.PreferredProtocol;
  757. IP.IPForwarding := config.IPForwarding;
  758. IP.EchoReply := config.EchoReply;
  759. interfaceConfigItem := config.interfaceConfigs;
  760. WHILE interfaceConfigItem # NIL DO
  761. (* IPv4 or IPv6 interface? *)
  762. CASE interfaceConfigItem.Protocol OF
  763. IP.IPv4:
  764. NEW(intv4, interfaceConfigItem.Name, dev, res);
  765. int := intv4;
  766. |IP.IPv6:
  767. NEW(intv6, interfaceConfigItem.Name, dev, res);
  768. int := intv6;
  769. ELSE
  770. END;
  771. IF (int # NIL) & (res = IP.Ok) THEN
  772. IF int IS IPv4.Interface THEN
  773. ipv4IntFound := TRUE;
  774. int.SetAdrs(interfaceConfigItem.LocalAdr, interfaceConfigItem.Netmask, interfaceConfigItem.Gateway, res);
  775. END;
  776. IF int IS IPv6.Interface THEN
  777. int.SetAdrs(interfaceConfigItem.LocalAdr, interfaceConfigItem.Prefix, interfaceConfigItem.Gateway, res);
  778. END;
  779. IF res = IP.Ok THEN
  780. FOR i := 0 TO DNSMod.MaxNofServer - 1 DO
  781. IF ~IP.IsNilAdr(interfaceConfigItem.DNS[i]) THEN
  782. int.DNSAdd(interfaceConfigItem.DNS[i]);
  783. END;
  784. END;
  785. i := 0;
  786. IF interfaceConfigItem.DHCP THEN
  787. NEW(runnerDHCP, int);
  788. END;
  789. KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  790. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  791. IF (res = Ok) & ~interfaceConfigItem.DHCP THEN
  792. IP.OutInterface(int);
  793. END;
  794. END;
  795. END;
  796. interfaceConfigItem := interfaceConfigItem.next;
  797. END;
  798. IF config.AutoNetConfigV6 & (dev.name # "Loopback") THEN
  799. (* create a link-local IPv6 interface *)
  800. Strings.Concat("v6link-local", dev.name, intName);
  801. NEW (intv6, intName, dev, res);
  802. int := intv6;
  803. IF res = IP.Ok THEN
  804. int(IPv6.Interface).autoconfigurated := TRUE;
  805. linkLocalAdr := IP.NilAdr;
  806. linkLocalPrefix := IP.NilAdr;
  807. linkLocalPrefix.usedProtocol := IP.IPv6;
  808. int(IPv6.Interface).SetInterfaceID(linkLocalAdr);
  809. (* write link local prefix and prefix *)
  810. linkLocalAdr.ipv6Adr[0] := 0FEX;
  811. linkLocalAdr.ipv6Adr[1] := 80X;
  812. linkLocalPrefix.ipv6Adr[0] := 0FEX;
  813. linkLocalPrefix.ipv6Adr[1] := 80X;
  814. linkLocalPrefix.data := 64;
  815. int.SetAdrs(linkLocalAdr, linkLocalPrefix, IP.NilAdr, res);
  816. IF res = IP.Ok THEN
  817. FOR i := 0 TO DNSMod.MaxNofServer - 1 DO
  818. IF ~IP.IsNilAdr(config.AutoNetConfigV6DNS[i]) THEN
  819. int.DNSAdd(config.AutoNetConfigV6DNS[i]);
  820. END;
  821. END;
  822. KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  823. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  824. IP.OutInterface(int);
  825. (* initiate Routers Solicitation for auto-address-configuration *)
  826. int(IPv6.Interface).createStatelessInterface := TRUE;
  827. int(IPv6.Interface).RouterSolicitation;
  828. (* Is this device a router? *)
  829. routerConfigItem := config.routerConfigs;
  830. (* search for current device *)
  831. WHILE (routerConfigItem # NIL) & (routerConfigItem.Device # dev.name) DO
  832. routerConfigItem := routerConfigItem.next;
  833. END;
  834. IF routerConfigItem # NIL THEN
  835. (* found a router configuration *)
  836. int(IPv6.Interface).ConfigAsRouter(routerConfigItem);
  837. END;
  838. END;
  839. END;
  840. END;
  841. IF config.AutoNetConfigV4 & (dev.name # "Loopback") THEN
  842. (* create automatic IPv4 interface if there is none *)
  843. IF ~ipv4IntFound THEN
  844. (* create an ipv4 interface (DHCP on) *)
  845. Strings.Concat("v4auto", dev.name, intName);
  846. NEW(intv4, intName, dev, res);
  847. int := intv4;
  848. IF res = IP.Ok THEN
  849. NEW(runnerDHCP, int);
  850. KernelLog.String("InitNetwork: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  851. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  852. END;
  853. END;
  854. END;
  855. END;
  856. END Added;
  857. (* Called for each LinkDevice that was removed from the registry. Remove the according interfaces. *)
  858. PROCEDURE Removed(dev: Network.LinkDevice);
  859. VAR int: IP.Interface;
  860. BEGIN
  861. KernelLog.String("InitNetwork: LinkDevice '"); KernelLog.String(dev.name); KernelLog.String("' removed."); KernelLog.Ln;
  862. int := IP.InterfaceByDevice(dev);
  863. WHILE int # NIL DO
  864. int.Close();
  865. KernelLog.String("InitNetwork: IP Interface '"); KernelLog.String(int.name); KernelLog.String("' removed."); KernelLog.Ln;
  866. int := IP.InterfaceByDevice(dev);
  867. END;
  868. END Removed;
  869. (* Handle events of installed/removed devices *)
  870. PROCEDURE EventHandler(event: WORD; plugin: Plugins.Plugin);
  871. BEGIN
  872. IF event = Plugins.EventAdd THEN
  873. Added(plugin(Network.LinkDevice));
  874. ELSIF event = Plugins.EventRemove THEN
  875. Removed(plugin(Network.LinkDevice));
  876. ELSE
  877. (* unknown event *)
  878. END;
  879. END EventHandler;
  880. (* Handler for Enumerate() *)
  881. PROCEDURE PluginHandler(plugin: Plugins.Plugin);
  882. BEGIN
  883. Added(plugin(Network.LinkDevice));
  884. END PluginHandler;
  885. (** Initialize the IP stack and configure all IP interfaces. *)
  886. PROCEDURE Init*;
  887. END Init;
  888. PROCEDURE Cleanup;
  889. BEGIN
  890. Network.registry.RemoveEventHandler(EventHandler, res);
  891. ASSERT(res = Plugins.Ok);
  892. END Cleanup;
  893. BEGIN
  894. ICMP.InitDelegates();
  895. Network.registry.AddEventHandler(EventHandler, res);
  896. ASSERT(res = Plugins.Ok);
  897. Modules.InstallTermHandler(Cleanup);
  898. (* Handle all previously installed devices *)
  899. KernelLog.String("InitNetwork: Module initialized. Searching for installed devices..."); KernelLog.Ln;
  900. Network.registry.Enumerate(PluginHandler);
  901. KernelLog.String("InitNetwork: Finished searching for installed devices."); KernelLog.Ln;
  902. END InitNetwork.
  903. (*
  904. History:
  905. 01.11.2003 mvt Created
  906. 02.05.2005 eb Uses Configuration.XML
  907. 06.03.2006 sst Procedure Removed: remove all interfaces that belong to the device that is removed, not just one
  908. *)