IPv6.Mod 94 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404
  1. MODULE IPv6; (** AUTHOR "Erwin Betschart"; PURPOSE "IP protocol version 6"; *)
  2. IMPORT SYSTEM, Machine, Kernel, Objects, Modules, Strings, KernelLog, Network, IP, Plugins;
  3. CONST
  4. (* DEBUG *)
  5. DEBUG = TRUE;
  6. (* IP *)
  7. EtherTypeIP* = 86DDH;
  8. MinIPHdrLen*= 40;
  9. MaxIPHdrLen* = 40;
  10. MaxFragPacketSize* = 65536; (* Maximal size of a packet, which can be fragmented *)
  11. (* Interface *)
  12. V6RouterIntName = "v6Router";
  13. V6OwnRouterIntName = "v6OwnRouter";
  14. V6DHCPIntName = "v6DHCP";
  15. (* Neighbor etc. cache *)
  16. CacheSize = 256;
  17. (* Neighbor cache reachablility states *)
  18. Incomplete = 0;
  19. Reachable = 1;
  20. Stale = 2;
  21. Delay = 3;
  22. Probe = 4;
  23. ReachableTime = 30000;
  24. (* autoconfig states *)
  25. TentativeInterface = 0;
  26. PreferredInterface = 1;
  27. DepricatedInterface = 2;
  28. InvalidInterface = 3;
  29. (* Next header types *)
  30. IPv6FragmentType = 44;
  31. IPv6RoutingHdrType = 43;
  32. IPv6HopByHopHdrType = 0;
  33. IPv6DestinationHdrType = 60;
  34. ICMPv6Type = 58;
  35. (* Header / Options Lengths *)
  36. NeighborHdrLen* = 20;
  37. RouterSolHdrLen* = 4;
  38. RouterAdvHdrLen = 12;
  39. LLAdrOptionLen* = 8; (* Source or Target Link-Layer address option len *)
  40. FragmentHdrLen = 8; (* Fragmentation header length *)
  41. RoutingHdrLen = 8; (* Routing header length *)
  42. HopByHopHdrLen = 8; (* Hop-by-hop header length *)
  43. DestinationHdrLen = 8; (* Destination header length *)
  44. MaxPrefixOptions = 10;
  45. (* Timers *)
  46. ShortTimerTimeout = 3000; (* 3 sec *)
  47. LongTimerTimeout = 600000; (* 10 min *)
  48. (* ICMP codes *)
  49. ICMPv6CodeHopLimitExc* = 0;
  50. ICMPv6FragmentReassemblyExc* = 3;
  51. (* router *)
  52. MaxRtrAdvInterval = 600000; (* milliseconds; default from RFC 2461*)
  53. MinRtrAdvInterval = 198000; (* milliseconds; default 0.33 * MaxRtrAdvInterval *)
  54. RouterPrefHigh = 1;
  55. RouterPrefMedium = 0;
  56. RouterPrefLow = 3;
  57. TYPE
  58. (* List of incoming fragmented packets which should be reassembled *)
  59. FragmentList = POINTER TO RECORD
  60. fragmentID: LONGINT;
  61. nextHeader: LONGINT;
  62. srcAdr: IP.Adr;
  63. dstAdr: IP.Adr;
  64. packets: PacketFragment;
  65. startedAt: Kernel.MilliTimer;
  66. fragmentCount: LONGINT;
  67. next: FragmentList;
  68. END;
  69. (* List of a packet which was fragmented *)
  70. PacketFragment = POINTER TO RECORD
  71. buffer: Network.Buffer;
  72. fragmentOffset: LONGINT;
  73. moreFragments: BOOLEAN;
  74. next: PacketFragment;
  75. prev: PacketFragment;
  76. END;
  77. (* List of devices *)
  78. DeviceList = POINTER TO RECORD
  79. device: Network.LinkDevice;
  80. linkLocalInterface: Interface;
  81. next: DeviceList;
  82. END;
  83. (* Router config *)
  84. RouterConfig* = POINTER TO RECORD
  85. Device*: Plugins.Name;
  86. SendRouterAdvertisements*: BOOLEAN;
  87. ManagedAddressConfig*: BOOLEAN;
  88. OtherStatefulConfig*: BOOLEAN;
  89. LinkMTU*: LONGINT;
  90. ReachableTime*: LONGINT; (* in seconds *)
  91. RetransTimer*: LONGINT; (* in seconds *)
  92. CurrentHopLimit*: LONGINT;
  93. Lifetime*: LONGINT; (* in seconds *)
  94. Prefixes*: PrefixConfig;
  95. next*: RouterConfig;
  96. END;
  97. (* Prefix config for router config *)
  98. PrefixConfig* = POINTER TO RECORD
  99. Prefix*: IP.Adr;
  100. IsSitePrefix*: BOOLEAN;
  101. ValidLifetime*: LONGINT; (* in seconds *)
  102. OnLink*: BOOLEAN;
  103. PreferredLifetime*: LONGINT;(* in seconds *)
  104. Autonomous*: BOOLEAN;
  105. next*: PrefixConfig;
  106. END;
  107. (* A queue of packets used in neighbor cache to store pending packets *)
  108. PacketQueue = POINTER TO RECORD
  109. l3hdr: POINTER TO ARRAY OF CHAR;
  110. l4hdr: POINTER TO ARRAY OF CHAR;
  111. data: POINTER TO ARRAY OF CHAR;
  112. h3len: LONGINT;
  113. h4len: LONGINT;
  114. dofs: LONGINT;
  115. dlen: LONGINT;
  116. next: PacketQueue;
  117. END;
  118. (* Entry in the neighbor cache *)
  119. NeighborCacheEntry* = POINTER TO RECORD
  120. next: NeighborCacheEntry;
  121. neighborIP: IP.Adr;
  122. linkAdr: Network.LinkAdr;
  123. reachability: LONGINT; (* either Incomplete, Reachable, Stale, Delay or Probe *)
  124. isRouter: BOOLEAN;
  125. queuedPackets: PacketQueue;
  126. probes: LONGINT; (* number of unanswered probes *)
  127. lastConfirmation: Kernel.MilliTimer;
  128. END;
  129. (* Entry in the destination cache *)
  130. DestCacheEntry = POINTER TO RECORD
  131. next: DestCacheEntry;
  132. dest: IP.Adr;
  133. nextHop: IP.Adr;
  134. pmtu: LONGINT;
  135. END;
  136. (* Entry in the prefix list *)
  137. PrefixesEntry = POINTER TO RECORD
  138. next: PrefixesEntry;
  139. prefix: IP.Adr;
  140. lifetime: Kernel.MilliTimer; (* time, when a prefix becomes invalid *)
  141. END;
  142. (* Entry in the default router list *)
  143. RoutersEntry = POINTER TO RECORD
  144. next: RoutersEntry;
  145. router: NeighborCacheEntry;
  146. routerLifetime: Kernel.MilliTimer;
  147. END;
  148. (* Entry in the local address cache *)
  149. LocalAdrCacheEntry = POINTER TO RECORD
  150. next: LocalAdrCacheEntry;
  151. localAdr: IP.Adr;
  152. interface: Interface;
  153. created: Kernel.MilliTimer;
  154. END;
  155. TYPE
  156. (** Destination cache *)
  157. DestCache = OBJECT
  158. VAR
  159. (* Array which holds linked lists of destination cache entries. The last byte of the destination address
  160. is the key to find a entry in this array *)
  161. destArray: ARRAY CacheSize OF DestCacheEntry;
  162. interface: Interface; (* Interface on which this cache operates *)
  163. (** Constructor: Initializes destinations array.*)
  164. PROCEDURE &Constr*(int: Interface; prefixes: Prefixes);
  165. VAR
  166. i: LONGINT;
  167. BEGIN
  168. FOR i := 0 TO 255 DO
  169. destArray[i] := NIL;
  170. END;
  171. interface := int;
  172. END Constr;
  173. (** Add a new dest entry *)
  174. PROCEDURE Add(destAdr, nextHop: IP.Adr);
  175. VAR
  176. newDestItem: DestCacheEntry;
  177. destItem: DestCacheEntry;
  178. BEGIN {EXCLUSIVE}
  179. (* look if entry already exists *)
  180. destItem := destArray[ORD(destAdr.ipv6Adr[15])];
  181. WHILE (destItem # NIL) & (~IP.AdrsEqual(destItem.dest, destAdr)) DO
  182. destItem := destItem.next;
  183. END;
  184. IF destItem = NIL THEN
  185. (* Add new entry *)
  186. NEW(newDestItem);
  187. newDestItem.next := NIL;
  188. newDestItem.dest := destAdr;
  189. newDestItem.nextHop := nextHop;
  190. newDestItem.pmtu := interface.linkMTU;
  191. (* put in array *)
  192. destItem := destArray[ORD(destAdr.ipv6Adr[15])];
  193. IF destItem = NIL THEN
  194. (* first element *)
  195. destArray[ORD(destAdr.ipv6Adr[15])] := newDestItem;
  196. ELSE
  197. WHILE destItem.next # NIL DO
  198. destItem := destItem.next;
  199. END;
  200. destItem.next := newDestItem;
  201. END;
  202. END;
  203. END Add;
  204. (** Remove a destination entry *)
  205. PROCEDURE Remove(destAdr: IP.Adr);
  206. VAR
  207. destItem: DestCacheEntry;
  208. BEGIN {EXCLUSIVE}
  209. destItem := destArray[ORD(destAdr.ipv6Adr[15])];
  210. IF destItem # NIL THEN
  211. IF IP.AdrsEqual(destItem.dest, destAdr) THEN
  212. (* remove first element *)
  213. destArray[ORD(destAdr.ipv6Adr[15])] := destItem.next;
  214. ELSIF destItem.next # NIL THEN
  215. (* search for elem *)
  216. WHILE (destItem.next.next # NIL) & (~IP.AdrsEqual(destItem.next.dest, destAdr)) DO
  217. destItem := destItem.next;
  218. END;
  219. IF destItem.next # NIL THEN
  220. (* found the right elem *)
  221. destItem.next := destItem.next.next;
  222. END;
  223. END;
  224. END;
  225. END Remove;
  226. (* Changes a PMTU of a cache entry *)
  227. PROCEDURE ChangePMTU(adr: IP.Adr; newPMTU: LONGINT);
  228. VAR
  229. destItem: DestCacheEntry;
  230. BEGIN
  231. destItem := destArray[ORD(adr.ipv6Adr[15])];
  232. IF destItem # NIL THEN
  233. (* search for right element *)
  234. WHILE (destItem # NIL) & (~IP.AdrsEqual(destItem.dest, adr)) DO
  235. destItem := destItem.next;
  236. END;
  237. IF destItem # NIL THEN
  238. destItem.pmtu := newPMTU;
  239. END;
  240. END;
  241. END ChangePMTU;
  242. (** Get next hop address *)
  243. PROCEDURE GetNextHop(destAdr: IP.Adr): IP.Adr;
  244. VAR
  245. nextHop: IP.Adr;
  246. destItem: DestCacheEntry;
  247. BEGIN
  248. IF interface.IsMulticast(destAdr) THEN
  249. (* Multicast packets are considered to be on-link *)
  250. nextHop := destAdr;
  251. ELSE
  252. nextHop := IP.NilAdr;
  253. destItem := destArray[ORD(destAdr.ipv6Adr[15])];
  254. WHILE (destItem # NIL) & (~IP.AdrsEqual(destAdr, destItem.dest)) DO
  255. destItem := destItem.next;
  256. END;
  257. IF destItem # NIL THEN
  258. nextHop := destItem.nextHop;
  259. ELSE
  260. nextHop := NextHopDetermination(destAdr);
  261. IF IP.IsNilAdr(nextHop) THEN
  262. (* assume destination is link-local *)
  263. nextHop := destAdr;
  264. END;
  265. (* Save results of NextHopDetermination *)
  266. Add(destAdr, nextHop);
  267. END;
  268. END;
  269. RETURN nextHop;
  270. END GetNextHop;
  271. (** Get PMTU of a address *)
  272. PROCEDURE GetPMTU(adr: IP.Adr): LONGINT;
  273. VAR
  274. destItem: DestCacheEntry;
  275. pmtu: LONGINT;
  276. BEGIN
  277. destItem := destArray[ORD(adr.ipv6Adr[15])];
  278. WHILE (destItem # NIL) & (~IP.AdrsEqual(adr, destItem.dest)) DO
  279. destItem := destItem.next;
  280. END;
  281. IF destItem # NIL THEN
  282. pmtu := destItem.pmtu;
  283. ELSE
  284. pmtu := interface.linkMTU;
  285. END;
  286. RETURN pmtu;
  287. END GetPMTU;
  288. (** Next hop determination *)
  289. PROCEDURE NextHopDetermination(destAdr: IP.Adr): IP.Adr;
  290. VAR
  291. longestPrefix: PrefixesEntry;
  292. nextHop: IP.Adr;
  293. BEGIN
  294. (* perform longest prefix match against prefix list *)
  295. longestPrefix := interface.prefixes.FindLongestMatch(destAdr);
  296. IF longestPrefix = NIL THEN
  297. (* select a router from the Default Router list *)
  298. nextHop := interface.routers.GetRouter();
  299. IF IP.IsNilAdr(nextHop) THEN
  300. (* no default router is found assume destAdr is on-link, therefore
  301. next hop = destination address *)
  302. nextHop := destAdr;
  303. END;
  304. ELSE
  305. (* destination is on-link: nextHop is same as destination *)
  306. nextHop := destAdr;
  307. END;
  308. RETURN nextHop;
  309. END NextHopDetermination;
  310. (** When a router become invalid update all affected entries *)
  311. PROCEDURE ChangeDests(fromAdr: IP.Adr; toAdr: IP.Adr);
  312. VAR
  313. destItem: DestCacheEntry;
  314. i: LONGINT;
  315. BEGIN
  316. FOR i := 0 TO CacheSize DO
  317. destItem := destArray[i];
  318. WHILE destItem # NIL DO
  319. IF IP.AdrsEqual(fromAdr, destItem.dest) THEN
  320. destItem.dest := toAdr;
  321. END;
  322. destItem := destItem.next;
  323. END;
  324. END;
  325. END ChangeDests;
  326. (** Clears the destination cache *)
  327. PROCEDURE Clear;
  328. VAR
  329. i: LONGINT;
  330. BEGIN
  331. FOR i := 0 TO CacheSize - 1 DO
  332. destArray[i] := NIL;
  333. END;
  334. END Clear;
  335. END DestCache;
  336. TYPE
  337. (** Neighbor cache. *)
  338. NeighborCache = OBJECT
  339. VAR
  340. neighbors: ARRAY CacheSize OF NeighborCacheEntry;
  341. (* Array which holds all neighbor entries. The last byte of the neighbor IP is the index
  342. of the array *)
  343. interface: Interface; (* Interface the neighbor cache operates on *)
  344. (** Constructor: Initializes neighbor array.*)
  345. PROCEDURE &Constr *(int: Interface);
  346. VAR
  347. i: LONGINT;
  348. BEGIN
  349. interface := int;
  350. FOR i := 0 TO (CacheSize - 1) DO
  351. neighbors[i] := NIL;
  352. END;
  353. END Constr;
  354. (** Add an IP to the neighbor cache *)
  355. PROCEDURE Add(neighborIP: IP.Adr);
  356. VAR
  357. newNeighborEntry: NeighborCacheEntry;
  358. neighborItem: NeighborCacheEntry;
  359. BEGIN {EXCLUSIVE}
  360. (* look if already an entry exists *)
  361. newNeighborEntry := Get(neighborIP);
  362. IF newNeighborEntry = NIL THEN
  363. NEW(newNeighborEntry);
  364. (* initialize neighbor cache entry to incomplete*)
  365. newNeighborEntry.next := NIL;
  366. newNeighborEntry.neighborIP := neighborIP;
  367. newNeighborEntry.reachability := Incomplete;
  368. newNeighborEntry.isRouter := FALSE;
  369. newNeighborEntry.queuedPackets := NIL;
  370. newNeighborEntry.probes := 0;
  371. Kernel.SetTimer(newNeighborEntry.lastConfirmation, 0);
  372. (* put into neighbor cache *)
  373. neighborItem := neighbors[ORD(neighborIP.ipv6Adr[15])];
  374. IF neighborItem = NIL THEN
  375. neighbors[ORD(neighborIP.ipv6Adr[15])] := newNeighborEntry;
  376. ELSE
  377. WHILE (neighborItem.next # NIL) DO
  378. neighborItem := neighborItem.next
  379. END;
  380. neighborItem.next := newNeighborEntry;
  381. END;
  382. END;
  383. END Add;
  384. (* Remove *)
  385. PROCEDURE Remove(neighborIP: IP.Adr);
  386. VAR
  387. neighborItem: NeighborCacheEntry;
  388. BEGIN {EXCLUSIVE}
  389. neighborItem := neighbors[ORD(neighborIP.ipv6Adr[15])];
  390. (* first element *)
  391. IF IP.AdrsEqual(neighborItem.neighborIP, neighborIP) THEN
  392. neighbors[ORD(neighborIP.ipv6Adr[15])] := neighborItem.next;
  393. ELSE
  394. WHILE (neighborItem.next # NIL) & (~IP.AdrsEqual(neighborItem.neighborIP, neighborIP)) DO
  395. neighborItem := neighborItem.next;
  396. END;
  397. IF neighborItem.next # NIL THEN
  398. (* found *)
  399. neighborItem.next := neighborItem.next.next;
  400. END;
  401. END;
  402. END Remove;
  403. (** Delete expired neighbor entries *)
  404. PROCEDURE ClearExpired;
  405. VAR
  406. neighborItem: NeighborCacheEntry;
  407. neighborItemPrev: NeighborCacheEntry;
  408. i: LONGINT;
  409. BEGIN {EXCLUSIVE}
  410. FOR i := 0 TO CacheSize - 1 DO
  411. neighborItem := neighbors[i];
  412. WHILE neighborItem # NIL DO
  413. IF Kernel.Expired(neighborItem.lastConfirmation) THEN
  414. IF neighborItemPrev = NIL THEN
  415. (* first item *)
  416. neighbors[i] := neighborItem.next;
  417. ELSE
  418. neighborItemPrev.next := neighborItem.next;
  419. END;
  420. END;
  421. IF (neighborItem.next # NIL) & (neighborItem.next # neighbors[i]) THEN
  422. neighborItemPrev := neighborItem;
  423. ELSE
  424. neighborItemPrev := NIL;
  425. END;
  426. neighborItem := neighborItem.next;
  427. END;
  428. END;
  429. END ClearExpired;
  430. (* Deliver a neighbor cache entry *)
  431. PROCEDURE Get*(adr: IP.Adr): NeighborCacheEntry;
  432. VAR
  433. neighborItem: NeighborCacheEntry;
  434. BEGIN
  435. neighborItem := neighbors[ORD(adr.ipv6Adr[15])];
  436. WHILE (neighborItem # NIL) & (~IP.AdrsEqual(neighborItem.neighborIP, adr)) DO
  437. neighborItem := neighborItem.next;
  438. END;
  439. RETURN neighborItem;
  440. END Get;
  441. (* Return link-layer address of a IP address *)
  442. PROCEDURE GetLinkLayerAdr(adr: IP.Adr; VAR linkAdr: Network.LinkAdr): BOOLEAN;
  443. VAR
  444. neighborItem: NeighborCacheEntry;
  445. found: BOOLEAN;
  446. BEGIN
  447. neighborItem := neighbors[ORD(adr.ipv6Adr[15])];
  448. WHILE (neighborItem # NIL) & (~IP.AdrsEqual(neighborItem.neighborIP, adr)) DO
  449. neighborItem := neighborItem.next;
  450. END;
  451. IF (neighborItem # NIL) & (neighborItem.reachability # Incomplete) THEN
  452. (* check timers *)
  453. IF Kernel.Expired(neighborItem.lastConfirmation) THEN
  454. (* Send a Neighbor Solicitation message *)
  455. sendNeighborSolicitation(interface, neighborItem.linkAdr, adr, FALSE);
  456. END;
  457. linkAdr := neighborItem.linkAdr;
  458. found := TRUE;
  459. ELSE
  460. found := FALSE;
  461. END;
  462. RETURN found;
  463. END GetLinkLayerAdr;
  464. (* Initiate address resolution *)
  465. PROCEDURE AddressResolution(neighborIP: IP.Adr; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT);
  466. VAR
  467. neighborEntry: NeighborCacheEntry;
  468. packetQueue: PacketQueue;
  469. packetQueueItem: PacketQueue;
  470. linkDst: Network.LinkAdr;
  471. i: LONGINT;
  472. BEGIN
  473. (* create a new neighbor cache entry *)
  474. Add(neighborIP);
  475. neighborEntry := Get(neighborIP);
  476. IF neighborEntry # NIL THEN
  477. (* Queue packet *)
  478. NEW(packetQueueItem);
  479. NEW(packetQueueItem.l3hdr, LEN(l3hdr));
  480. FOR i := 0 TO LEN(l3hdr) - 1 DO
  481. packetQueueItem.l3hdr[i] := l3hdr[i];
  482. END;
  483. NEW(packetQueueItem.l4hdr, LEN(l4hdr));
  484. FOR i := 0 TO LEN(l4hdr) - 1 DO
  485. packetQueueItem.l4hdr[i] := l4hdr[i];
  486. END;
  487. NEW(packetQueueItem.data, LEN(data));
  488. FOR i := 0 TO LEN(data) - 1 DO
  489. packetQueueItem.data[i] := data[i];
  490. END;
  491. packetQueueItem.h3len := h3len;
  492. packetQueueItem.h4len := h4len;
  493. packetQueueItem.dofs := dofs;
  494. packetQueueItem.dlen := dlen;
  495. packetQueue := neighborEntry.queuedPackets;
  496. packetQueueItem.next := packetQueue;
  497. neighborEntry.queuedPackets := packetQueueItem;
  498. (* link and IP destination addresses are the solicited node addresses *)
  499. linkDst := linkMulticastAllNodesAdr;
  500. linkDst[2] := 0FFX;
  501. linkDst[3] := neighborIP.ipv6Adr[13];
  502. linkDst[4] := neighborIP.ipv6Adr[14];
  503. linkDst[5] := neighborIP.ipv6Adr[15];
  504. (* Send a Neighbor Solicitation message *)
  505. sendNeighborSolicitation(interface, linkDst, neighborIP, TRUE);
  506. END;
  507. END AddressResolution;
  508. (* Send queued Packets *)
  509. PROCEDURE SendQueuedPackets(neighborCacheEntry: NeighborCacheEntry);
  510. VAR
  511. queuedPacket: PacketQueue;
  512. pmtu: LONGINT;
  513. toFragment: BOOLEAN;
  514. BEGIN {EXCLUSIVE}
  515. toFragment := FALSE;
  516. queuedPacket := neighborCacheEntry.queuedPackets;
  517. WHILE queuedPacket # NIL DO
  518. pmtu := interface.destCache.GetPMTU(neighborCacheEntry.neighborIP);
  519. IF queuedPacket.h3len+queuedPacket.h4len+queuedPacket.dlen > pmtu THEN
  520. (* fragment packet *)
  521. toFragment := TRUE;
  522. END;
  523. IF ~toFragment THEN
  524. interface.dev.Send(neighborCacheEntry.linkAdr,
  525. EtherTypeIP,
  526. queuedPacket.l3hdr^,
  527. queuedPacket.l4hdr^,
  528. queuedPacket.data^,
  529. queuedPacket.h3len,
  530. queuedPacket.h4len,
  531. queuedPacket.dofs,
  532. queuedPacket.dlen,
  533. FALSE);
  534. ELSE
  535. interface.DoFragAndSend(pmtu,
  536. neighborCacheEntry.linkAdr,
  537. queuedPacket.l3hdr^,
  538. queuedPacket.l4hdr^,
  539. queuedPacket.data^,
  540. queuedPacket.h3len,
  541. queuedPacket.h4len,
  542. queuedPacket.dofs,
  543. queuedPacket.dlen);
  544. END;
  545. queuedPacket := queuedPacket.next;
  546. END;
  547. neighborCacheEntry.queuedPackets := NIL;
  548. END SendQueuedPackets;
  549. END NeighborCache;
  550. TYPE
  551. (* Prefix list *)
  552. Prefixes = OBJECT
  553. VAR
  554. prefixes: PrefixesEntry;
  555. (* Constructor: Initializes prefixes.*)
  556. PROCEDURE &Constr*;
  557. BEGIN
  558. prefixes := NIL;
  559. END Constr;
  560. (* Add a prefix. Lifetime in seconds *)
  561. PROCEDURE Add(prefix: IP.Adr; lifetime: LONGINT);
  562. VAR
  563. prefixItem: PrefixesEntry;
  564. BEGIN {EXCLUSIVE}
  565. NEW(prefixItem);
  566. prefixItem.prefix := prefix;
  567. Kernel.SetTimer(prefixItem.lifetime, lifetime * 1000); (* Milliseconds *)
  568. prefixItem.next := prefixes;
  569. prefixes := prefixItem;
  570. END Add;
  571. (* Remove a prefix *)
  572. PROCEDURE Remove(prefix: IP.Adr);
  573. VAR
  574. prefixItem: PrefixesEntry;
  575. BEGIN {EXCLUSIVE}
  576. prefixItem := prefixes;
  577. IF prefixItem # NIL THEN
  578. (* first element? *)
  579. IF IP.AdrsEqual(prefix, prefixItem.prefix) THEN
  580. prefixes := prefixItem.next;
  581. ELSE
  582. WHILE (prefixItem.next # NIL) & (~IP.AdrsEqual(prefix, prefixItem.next.prefix)) DO
  583. prefixItem := prefixItem.next;
  584. END;
  585. IF prefixItem # NIL THEN
  586. (* remove item from list *)
  587. prefixItem.next := prefixItem.next.next;
  588. END;
  589. END;
  590. END;
  591. END Remove;
  592. (** Delete expired prefixes *)
  593. PROCEDURE ClearExpired;
  594. VAR
  595. prefixItem: PrefixesEntry;
  596. prefixItemPrev: PrefixesEntry;
  597. BEGIN {EXCLUSIVE}
  598. prefixItem := prefixes;
  599. WHILE prefixItem # NIL DO
  600. IF Kernel.Expired(prefixItem.lifetime) THEN
  601. IF prefixItemPrev = NIL THEN
  602. (* first item *)
  603. prefixes := prefixItem.next;
  604. ELSE
  605. prefixItemPrev.next := prefixItem.next;
  606. END;
  607. END;
  608. IF (prefixItem.next # NIL) & (prefixItem.next # prefixes) THEN
  609. prefixItemPrev := prefixItem;
  610. ELSE
  611. prefixItemPrev := NIL;
  612. END;
  613. prefixItem := prefixItem.next;
  614. END;
  615. END ClearExpired;
  616. (* Deliver a specific prefix entry *)
  617. PROCEDURE Get(prefix: IP.Adr): PrefixesEntry;
  618. VAR
  619. prefixItem: PrefixesEntry;
  620. BEGIN
  621. prefixItem := prefixes;
  622. WHILE ((prefixItem # NIL) & (~IP.AdrsEqual(prefix, prefixItem.prefix)) & (~(prefix.data = prefixItem.prefix.data))) DO
  623. prefixItem := prefixItem.next;
  624. END;
  625. RETURN prefixItem;
  626. END Get;
  627. (* Is there a prefix which matches adr *)
  628. PROCEDURE FindLongestMatch(adr: IP.Adr): PrefixesEntry;
  629. VAR
  630. prefixItem: PrefixesEntry;
  631. longestPrefixItem: PrefixesEntry;
  632. longestPrefix: LONGINT;
  633. BEGIN
  634. prefixItem := prefixes;
  635. longestPrefixItem := NIL;
  636. longestPrefix := 0;
  637. WHILE (prefixItem # NIL) DO
  638. IF IP.MatchPrefix (adr, prefixItem.prefix) THEN
  639. IF prefixItem.prefix.data > longestPrefix THEN
  640. longestPrefix := prefixItem.prefix.data;
  641. longestPrefixItem := prefixItem;
  642. END;
  643. END;
  644. prefixItem := prefixItem.next;
  645. END;
  646. IF longestPrefixItem # NIL THEN
  647. RETURN longestPrefixItem;
  648. END;
  649. RETURN NIL;
  650. END FindLongestMatch;
  651. END Prefixes;
  652. TYPE
  653. (* Default Router List *)
  654. Routers = OBJECT
  655. VAR
  656. routers: RoutersEntry;
  657. lastRobinRouter: RoutersEntry; (* last choosen Router with round robin *)
  658. interface: Interface;
  659. (* Constructor: Initializes routers.*)
  660. PROCEDURE &Constr*(int: Interface);
  661. BEGIN
  662. routers := NIL;
  663. lastRobinRouter := routers;
  664. interface := int;
  665. END Constr;
  666. (* Add a default router *)
  667. PROCEDURE Add(routerIP: IP.Adr; routerLinkAdr: Network.LinkAdr; lifetime: LONGINT): RoutersEntry;
  668. VAR
  669. router: RoutersEntry;
  670. neighbor: NeighborCacheEntry;
  671. BEGIN {EXCLUSIVE}
  672. lifetime := lifetime * 1000; (* lifetime in milliseconds *)
  673. router := Get(routerIP);
  674. IF router = NIL THEN
  675. (* default routers does not exist *)
  676. NEW(router);
  677. router.next := routers;
  678. routers := router;
  679. END;
  680. Kernel.SetTimer(router.routerLifetime, lifetime);
  681. neighbor := interface.neighborCache.Get(routerIP);
  682. IF neighbor = NIL THEN
  683. interface.neighborCache.Add(routerIP);
  684. neighbor := interface.neighborCache.Get(routerIP);
  685. neighbor.linkAdr := routerLinkAdr;
  686. neighbor.reachability := Stale;
  687. neighbor.isRouter := TRUE;
  688. neighbor.probes := 0;
  689. Kernel.SetTimer(neighbor.lastConfirmation, lifetime);
  690. ELSE
  691. Kernel.SetTimer(neighbor.lastConfirmation, lifetime);
  692. END;
  693. router.router := neighbor;
  694. RETURN router;
  695. END Add;
  696. (* Remove a default router *)
  697. PROCEDURE Remove(router: IP.Adr);
  698. VAR
  699. routerItem: RoutersEntry;
  700. routerItemPrev: RoutersEntry;
  701. BEGIN {EXCLUSIVE}
  702. routerItem := routers;
  703. WHILE (routerItem # NIL) & (~IP.AdrsEqual(routerItem.router.neighborIP, router)) DO
  704. routerItemPrev := routerItem;
  705. routerItem := routerItem.next;
  706. END;
  707. IF routerItem # NIL THEN
  708. IF routerItemPrev = NIL THEN
  709. (* first element *)
  710. routers := routerItem.next;
  711. ELSE
  712. routerItemPrev.next := routerItem.next;
  713. END;
  714. END;
  715. END Remove;
  716. (* Deliver a specific router *)
  717. PROCEDURE Get(routerIP: IP.Adr): RoutersEntry;
  718. VAR
  719. item: RoutersEntry;
  720. BEGIN
  721. item := routers;
  722. WHILE (item # NIL) & (~IP.AdrsEqual(item.router.neighborIP, routerIP)) DO
  723. item := item.next;
  724. END;
  725. RETURN item;
  726. END Get;
  727. (* Deliver a default router *)
  728. PROCEDURE GetRouter(): IP.Adr;
  729. VAR
  730. routersItem: RoutersEntry;
  731. routerAdr: IP.Adr;
  732. searchReachable: BOOLEAN;
  733. BEGIN
  734. (* deliver router: first searched for REACHABLES then other in round robin fashion *)
  735. routerAdr := IP.NilAdr;
  736. IF routers # NIL THEN
  737. IF lastRobinRouter = NIL THEN
  738. lastRobinRouter := routers;
  739. END;
  740. routersItem := lastRobinRouter.next;
  741. IF routersItem = NIL THEN
  742. (* start from begin *)
  743. routersItem := routers.next;
  744. END;
  745. searchReachable := TRUE;
  746. LOOP
  747. IF routersItem = NIL THEN
  748. (* start from begin *)
  749. routersItem := routers;
  750. END;
  751. IF (routersItem = lastRobinRouter) & ~searchReachable THEN
  752. IF routersItem.router.reachability # Incomplete THEN
  753. routerAdr := routersItem.router.neighborIP;
  754. ELSE
  755. (* searched for reachable and other found nothing *)
  756. lastRobinRouter := NIL;
  757. routerAdr := IP.NilAdr;
  758. EXIT;
  759. END;
  760. END;
  761. IF (routersItem = lastRobinRouter) & searchReachable THEN
  762. (* searched for reachable found nothing *)
  763. searchReachable := FALSE;
  764. IF routersItem.router.reachability = Reachable THEN
  765. (* only a single reachable router *)
  766. EXIT;
  767. END;
  768. routersItem := routersItem.next;
  769. IF routersItem = NIL THEN
  770. routersItem := routers;
  771. END;
  772. END;
  773. IF searchReachable & (routersItem.router.reachability = Reachable) THEN
  774. (* found a reachable router *)
  775. routerAdr := routersItem.router.neighborIP;
  776. lastRobinRouter := routersItem;
  777. EXIT;
  778. END;
  779. IF ~searchReachable & (routersItem.router.reachability # Incomplete) THEN
  780. (* found a stale, delay or probe router *)
  781. routerAdr := routersItem.router.neighborIP;
  782. lastRobinRouter := routersItem;
  783. EXIT;
  784. END;
  785. routersItem := routersItem.next;
  786. END;
  787. END;
  788. RETURN routerAdr;
  789. END GetRouter;
  790. (** Delete expired routers *)
  791. PROCEDURE ClearExpired;
  792. VAR
  793. routerItem: RoutersEntry;
  794. routerItemPrev: RoutersEntry;
  795. BEGIN {EXCLUSIVE}
  796. routerItem := routers;
  797. WHILE routerItem # NIL DO
  798. IF Kernel.Expired(routerItem.routerLifetime) THEN
  799. IF routerItemPrev = NIL THEN
  800. (* first item *)
  801. routers := routerItem.next;
  802. ELSE
  803. routerItemPrev.next := routerItem.next;
  804. END;
  805. END;
  806. IF (routerItem.next # NIL) & (routerItem.next # routers) THEN
  807. routerItemPrev := routerItem;
  808. ELSE
  809. routerItemPrev := NIL;
  810. END;
  811. routerItem := routerItem.next;
  812. END;
  813. END ClearExpired;
  814. (** Writes all default routers *)
  815. PROCEDURE OutRouters;
  816. VAR
  817. item: RoutersEntry;
  818. BEGIN
  819. KernelLog.String("Default routers:"); KernelLog.Ln;
  820. item := routers;
  821. WHILE item # NIL DO
  822. IP.OutAdr(item.router.neighborIP); KernelLog.Ln;
  823. item := item.next;
  824. END;
  825. END OutRouters;
  826. END Routers;
  827. TYPE
  828. (** When multiple network devices are present the IPv6 implementation is unable to know on which interface
  829. a local address is reachable. To prevent sending a lot of neighbor discovery messages this cache is created. *)
  830. LocalAdrCache = OBJECT
  831. VAR
  832. localAdrs: ARRAY CacheSize OF LocalAdrCacheEntry;
  833. (* Array which holds all local address entries. The last byte of the neighbor IP is the index
  834. of the array *)
  835. PROCEDURE &Constr*;
  836. VAR
  837. i: LONGINT;
  838. BEGIN
  839. FOR i := 0 TO (CacheSize - 1) DO
  840. localAdrs[i] := NIL;
  841. END;
  842. END Constr;
  843. (** Add an IP to the neighbor cache *)
  844. PROCEDURE Add(localIP: IP.Adr; interface: Interface);
  845. VAR
  846. newLocalAdrEntry: LocalAdrCacheEntry;
  847. localAdrItem: LocalAdrCacheEntry;
  848. BEGIN {EXCLUSIVE}
  849. (* look if already an entry exists *)
  850. newLocalAdrEntry := Get(localIP);
  851. IF newLocalAdrEntry = NIL THEN
  852. NEW(newLocalAdrEntry);
  853. (* initialize local adr cache entry *)
  854. newLocalAdrEntry.next := NIL;
  855. newLocalAdrEntry.localAdr := localIP;
  856. newLocalAdrEntry.interface := interface;
  857. Kernel.SetTimer(newLocalAdrEntry.created, LongTimerTimeout);
  858. (* put into local address cache *)
  859. localAdrItem := localAdrs[ORD(localIP.ipv6Adr[15])];
  860. IF localAdrItem = NIL THEN
  861. localAdrs[ORD(localIP.ipv6Adr[15])] := newLocalAdrEntry;
  862. ELSE
  863. WHILE (localAdrItem.next # NIL) DO
  864. localAdrItem := localAdrItem.next
  865. END;
  866. localAdrItem.next := newLocalAdrEntry;
  867. END;
  868. END;
  869. END Add;
  870. (* Remove *)
  871. PROCEDURE Remove(localIP: IP.Adr);
  872. VAR
  873. localAdrItem: LocalAdrCacheEntry;
  874. BEGIN {EXCLUSIVE}
  875. localAdrItem := localAdrs[ORD(localIP.ipv6Adr[15])];
  876. (* first element *)
  877. IF IP.AdrsEqual(localAdrItem.localAdr, localIP) THEN
  878. localAdrs[ORD(localIP.ipv6Adr[15])] := localAdrItem.next;
  879. ELSE
  880. WHILE (localAdrItem.next # NIL) & (~IP.AdrsEqual(localAdrItem.localAdr, localIP)) DO
  881. localAdrItem := localAdrItem.next;
  882. END;
  883. IF localAdrItem.next # NIL THEN
  884. (* found *)
  885. localAdrItem.next := localAdrItem.next.next;
  886. END;
  887. END;
  888. END Remove;
  889. (** Delete expired local address entries *)
  890. PROCEDURE ClearExpired;
  891. VAR
  892. localAdrItem: LocalAdrCacheEntry;
  893. localAdrItemPrev: LocalAdrCacheEntry;
  894. i: LONGINT;
  895. BEGIN {EXCLUSIVE}
  896. FOR i := 0 TO CacheSize - 1 DO
  897. localAdrItem := localAdrs[i];
  898. WHILE localAdrItem # NIL DO
  899. IF Kernel.Expired(localAdrItem.created) THEN
  900. IF localAdrItemPrev = NIL THEN
  901. (* first item *)
  902. localAdrs[i] := localAdrItem.next;
  903. ELSE
  904. localAdrItemPrev.next := localAdrItem.next;
  905. END;
  906. END;
  907. IF (localAdrItem.next # NIL) & (localAdrItem.next # localAdrs[i]) THEN
  908. localAdrItemPrev := localAdrItem;
  909. ELSE
  910. localAdrItemPrev := NIL;
  911. END;
  912. localAdrItem := localAdrItem.next;
  913. END;
  914. END;
  915. END ClearExpired;
  916. (* Deliver a local address cache entry *)
  917. PROCEDURE Get*(localAdr: IP.Adr): LocalAdrCacheEntry;
  918. VAR
  919. localAdrItem: LocalAdrCacheEntry;
  920. BEGIN
  921. localAdrItem := localAdrs[ORD(localAdr.ipv6Adr[15])];
  922. WHILE (localAdrItem # NIL) & (~IP.AdrsEqual(localAdrItem.localAdr, localAdr)) DO
  923. localAdrItem := localAdrItem.next;
  924. END;
  925. RETURN localAdrItem;
  926. END Get;
  927. (* Deliver the interface according to a local address *)
  928. PROCEDURE GetInterface*(localAdr: IP.Adr): Interface;
  929. VAR
  930. localAdrItem: LocalAdrCacheEntry;
  931. BEGIN
  932. localAdrItem := localAdrs[ORD(localAdr.ipv6Adr[15])];
  933. WHILE (localAdrItem # NIL) & (~IP.AdrsEqual(localAdrItem.localAdr, localAdr)) DO
  934. localAdrItem := localAdrItem.next;
  935. END;
  936. IF localAdrItem # NIL THEN
  937. RETURN localAdrItem.interface;
  938. ELSE
  939. RETURN NIL;
  940. END;
  941. END GetInterface;
  942. END LocalAdrCache;
  943. TYPE
  944. Interface* = OBJECT (IP.Interface)
  945. VAR
  946. destCache: DestCache;
  947. neighborCache: NeighborCache;
  948. prefixes: Prefixes;
  949. routers: Routers;
  950. linkMTU: LONGINT;
  951. curHopLimit*: LONGINT;
  952. linkMulticastSolicited: Network.LinkAdr;
  953. linkLocalSolicitedNodeAdr: IP.Adr;
  954. (* Autoconfiguration *)
  955. autoconfigurated*: BOOLEAN;
  956. autoconfigState: LONGINT;
  957. createStatelessInterface*: BOOLEAN;
  958. createStatefulInterface: BOOLEAN;
  959. routerSolCount: LONGINT;
  960. (* Timers *)
  961. shortTimer: Kernel.Timer;
  962. longTimer: Kernel.MilliTimer;
  963. duplicateTimer: Kernel.MilliTimer;
  964. intName: IP.Name;
  965. intv6: Interface;
  966. int: IP.Interface;
  967. res: WORD;
  968. fragmentList: FragmentList;
  969. (* router *)
  970. isRouter*: BOOLEAN;
  971. routerConfig: RouterConfig;
  972. nextRtrAdvertisement: LONGINT; (* When should the next unsolicited router advertisement be sent; in numbers of shortTimer *)
  973. (** Constructor - Open an IPv6 interface and add it to the IP configuration.
  974. "name" must be a unique name for this interface (tested in "AddInterface").
  975. "dev" must be a Network.LinkDevice that can be used in other interfaces => multiple IP addresses on the
  976. same interface. *)
  977. PROCEDURE &Constr*(name: IP.Name; dev: Network.LinkDevice; VAR res: WORD);
  978. VAR
  979. devListItem: DeviceList;
  980. BEGIN
  981. ASSERT(dev # NIL);
  982. SELF.dev := dev;
  983. protocol := IP.IPv6;
  984. autoconfigurated := FALSE;
  985. autoconfigState := TentativeInterface;
  986. createStatelessInterface := FALSE;
  987. createStatefulInterface := FALSE;
  988. routerSolCount := 0;
  989. fragmentList := NIL;
  990. isRouter := FALSE;
  991. routerConfig:= NIL;
  992. nextRtrAdvertisement := 0;
  993. (* create caches *)
  994. NEW(prefixes);
  995. NEW(routers, SELF);
  996. NEW(destCache, SELF, prefixes);
  997. NEW(neighborCache, SELF);
  998. (* set name *)
  999. IF name = "" THEN
  1000. res := IP.NoInterfaceName;
  1001. RETURN;
  1002. END;
  1003. COPY(name, SELF.name);
  1004. (* init addresses *)
  1005. localAdr := IP.NilAdr;
  1006. maskAdr := IP.NilAdr;
  1007. gatewayAdr := IP.NilAdr;
  1008. subnetAdr := IP.NilAdr;
  1009. linkLocalSolicitedNodeAdr := IP.NilAdr;
  1010. (* broadAdr is Link-local multicast address *)
  1011. broadAdr := IP.NilAdr;
  1012. broadAdr.usedProtocol := IP.IPv6;
  1013. broadAdr.ipv6Adr[0] := 0FFX;
  1014. broadAdr.ipv6Adr[1] := 2X;
  1015. broadAdr.ipv6Adr[15] := 1X;
  1016. broadAdr.data := 0;
  1017. (* init DNS *)
  1018. DNScount := 0;
  1019. closed := FALSE;
  1020. IP.AddInterface(SELF, res);
  1021. IF res = IP.Ok THEN
  1022. (* install receivers *)
  1023. dev.InstallReceiver(SELF, EtherTypeIP, IPInput, IsPacketValid, IsPacketForSingleInt, IsPacketAccepted
  1024. , IP.IPForwarding); (* IPv6 *)
  1025. (* Update list of devices *)
  1026. devListItem := devList;
  1027. WHILE (devListItem # NIL) & (devListItem.device # dev) DO
  1028. devListItem := devListItem.next;
  1029. END;
  1030. IF devListItem = NIL THEN
  1031. NEW(devListItem);
  1032. devListItem.device := dev;
  1033. devListItem.next := devList;
  1034. devList := devListItem;
  1035. END;
  1036. ELSE
  1037. closed := TRUE;
  1038. END;
  1039. END Constr;
  1040. (** Close and deactivate the interface, i.e. remove it from the configuration. *)
  1041. PROCEDURE Close*;
  1042. VAR
  1043. i: LONGINT;
  1044. BEGIN {EXCLUSIVE}
  1045. ASSERT(~closed);
  1046. dev.RemoveReceiver(SELF, EtherTypeIP);
  1047. closed := TRUE;
  1048. shortTimer.Wakeup;
  1049. (* To be "sure" that the active body is terminated *)
  1050. FOR i := 0 TO 9999 DO
  1051. Objects.Yield;
  1052. END;
  1053. IP.RemoveInterface(SELF);
  1054. END Close;
  1055. (** Set addresses. Is normally called just after instanciation, but can also be called later, e.g. by DHCP.
  1056. If "gatewayAdr" is not "NilAdr", it will be added to the default router list. *)
  1057. PROCEDURE SetAdrs*(localAdr, prefixAdr, defaultRouterAdr: IP.Adr; VAR res: WORD);
  1058. VAR
  1059. devListItem: DeviceList;
  1060. BEGIN {EXCLUSIVE}
  1061. IF DEBUG THEN
  1062. ASSERT ((IP.IsNilAdr(localAdr)) OR (localAdr.usedProtocol = 6), 2345);
  1063. ASSERT ((IP.IsNilAdr(prefixAdr)) OR (prefixAdr.usedProtocol = 6), 2345);
  1064. END;
  1065. IF (~IP.IsNilAdr(localAdr)) THEN
  1066. IF IP.IsNilAdr(prefixAdr) & ~(dev.name = "Loopback") THEN
  1067. (* prefix has to be set! *)
  1068. res := IP.PrefixNotSet;
  1069. RETURN;
  1070. END;
  1071. (* Check if addresses are of same protocol as interface *)
  1072. IF dev.name = "Loopback" THEN
  1073. IF localAdr.usedProtocol # IP.IPv6 THEN
  1074. res := IP.IPv4AdrUsedOnIPv6Interface;
  1075. RETURN;
  1076. END;
  1077. ELSIF (localAdr.usedProtocol # IP.IPv6) OR (prefixAdr.usedProtocol # IP.IPv6) THEN
  1078. res := IP.IPv4AdrUsedOnIPv6Interface;
  1079. RETURN;
  1080. END;
  1081. (* set addresses *)
  1082. SELF.localAdr := localAdr;
  1083. SELF.maskAdr := prefixAdr;
  1084. linkLocalSolicitedNodeAdr := IP.NilAdr;
  1085. linkLocalSolicitedNodeAdr.usedProtocol := IP.IPv6;
  1086. linkLocalSolicitedNodeAdr.ipv6Adr[0] := 0FFX;
  1087. linkLocalSolicitedNodeAdr.ipv6Adr[1] := 2X;
  1088. linkLocalSolicitedNodeAdr.ipv6Adr[11] := 1X;
  1089. linkLocalSolicitedNodeAdr.ipv6Adr[12] := 0FFX;
  1090. linkLocalSolicitedNodeAdr.ipv6Adr[13] := localAdr.ipv6Adr[13];
  1091. linkLocalSolicitedNodeAdr.ipv6Adr[14] := localAdr.ipv6Adr[14];
  1092. linkLocalSolicitedNodeAdr.ipv6Adr[15] := localAdr.ipv6Adr[15];
  1093. IF name # "Loopbackv6" THEN
  1094. (* Duplicate Address Detection *)
  1095. Kernel.SetTimer(duplicateTimer, ShortTimerTimeout);
  1096. sendNeighborSolicitation(SELF, linkMulticastSolicited, linkLocalSolicitedNodeAdr, FALSE);
  1097. END;
  1098. res := IP.Ok;
  1099. (* When this interface a link-local interface is update devList *)
  1100. IF IsLinkLocalAdr(localAdr) THEN
  1101. devListItem := devList;
  1102. WHILE (devListItem # NIL) & (devListItem.device # dev) DO
  1103. devListItem := devListItem.next;
  1104. END;
  1105. devListItem.linkLocalInterface := SELF;
  1106. END;
  1107. ELSE
  1108. (* make nothing *)
  1109. END;
  1110. END SetAdrs;
  1111. (* Receive an IP packet *)
  1112. PROCEDURE IPInput*(dev: Network.LinkDevice; type: LONGINT; buffer: Network.Buffer);
  1113. VAR
  1114. payloadLength: LONGINT;
  1115. nextHeader: LONGINT;
  1116. srcAdr: IP.Adr;
  1117. dstAdr: IP.Adr;
  1118. forwardInt: IP.Interface;
  1119. receiver: IP.Receiver;
  1120. incomingFragment: BOOLEAN;
  1121. forwardBuffer: Network.Buffer;
  1122. BEGIN
  1123. IF DEBUG THEN
  1124. ASSERT(type = EtherTypeIP);
  1125. ASSERT(dev = SELF.dev);
  1126. END;
  1127. incomingFragment := FALSE;
  1128. IF buffer.nextFragment = NIL THEN
  1129. payloadLength := Network.GetNet2(buffer.data, buffer.ofs+4);
  1130. nextHeader := ORD(buffer.data[buffer.ofs+6]);
  1131. ELSE
  1132. nextHeader := ORD(buffer.data[buffer.ofs]);
  1133. payloadLength := buffer.len - MinIPHdrLen; (* not correct but otherwise fragmented packet are not accepted *)
  1134. END;
  1135. IF ((payloadLength + MinIPHdrLen) <= buffer.len) THEN
  1136. (* payloadLength = 0: Jumbo-Payload *)
  1137. srcAdr := ReadSrcAdr (buffer);
  1138. dstAdr := ReadDestAdr (buffer);
  1139. IF (nextHeader = IPv6FragmentType) & (buffer.nextFragment = NIL) THEN
  1140. (* a fragmented packet try to reassemble it *)
  1141. INC(buffer.ofs, MinIPHdrLen);
  1142. DEC(buffer.len, MinIPHdrLen);
  1143. AddToFragmentList(srcAdr, dstAdr, buffer);
  1144. incomingFragment := TRUE;
  1145. END;
  1146. IF ~IsMulticast(srcAdr) & ~incomingFragment THEN
  1147. IF ~IsMulticast(dstAdr) THEN
  1148. (* unicast *)
  1149. IF (IP.AdrsEqual(dstAdr, localAdr)) THEN
  1150. receiver := IP.receivers[nextHeader];
  1151. IF receiver # NIL THEN
  1152. (* do receiver upcall *)
  1153. buffer.l3ofs := buffer.ofs;
  1154. IF buffer.nextFragment # NIL THEN
  1155. (* adjust offset when a packet is fragmented*)
  1156. INC(buffer.ofs, FragmentHdrLen);
  1157. DEC(buffer.len, FragmentHdrLen);
  1158. ELSE
  1159. INC(buffer.ofs, MinIPHdrLen);
  1160. DEC(buffer.len, MinIPHdrLen);
  1161. END;
  1162. receiver(SELF, nextHeader, srcAdr, dstAdr, buffer);
  1163. Machine.AtomicInc(IP.NIPDelivered);
  1164. (* Exit here w/o returning buffer because it is passed to a receiver *)
  1165. RETURN;
  1166. ELSE
  1167. Machine.AtomicInc(IP.NIPNoReceiver);
  1168. END;
  1169. ELSIF IP.IPForwarding THEN
  1170. (* forward packet *)
  1171. (* look if there is a routing header *)
  1172. IF nextHeader = IPv6RoutingHdrType THEN
  1173. INC(buffer.ofs, MinIPHdrLen);
  1174. DEC(buffer.len, MinIPHdrLen);
  1175. dstAdr := ReadDestAdr (buffer);
  1176. END;
  1177. forwardInt := IP.InterfaceByDstIP(dstAdr);
  1178. IF forwardInt # NIL THEN
  1179. forwardBuffer := buffer;
  1180. WHILE forwardBuffer # NIL DO
  1181. (* only forward packets with hop limit > zero *)
  1182. IF ORD(forwardBuffer.data[7]) > 0 THEN
  1183. (* Decrement hop limit *)
  1184. forwardBuffer.data[7] := CHR(ORD(forwardBuffer.data[7]) - 1);
  1185. forwardInt.DoSend(dstAdr,
  1186. forwardBuffer.data,
  1187. forwardBuffer.data,
  1188. forwardBuffer.data,
  1189. 0,
  1190. 0,
  1191. forwardBuffer.ofs,
  1192. forwardBuffer.len);
  1193. Machine.AtomicInc(IP.NIPForwarded);
  1194. ELSE
  1195. sendICMPv6TimeExceeded(SELF, forwardBuffer, srcAdr, ICMPv6CodeHopLimitExc);
  1196. END;
  1197. forwardBuffer := forwardBuffer.nextFragment;
  1198. END;
  1199. ELSE
  1200. Machine.AtomicInc(IP.NIPNotForUs)
  1201. END;
  1202. ELSE
  1203. Machine.AtomicInc(IP.NIPNotForUs);
  1204. END
  1205. ELSIF IsSolicitedNodeAdr(dstAdr) THEN
  1206. receiver := IP.receivers[nextHeader];
  1207. IF receiver # NIL THEN
  1208. (* do receiver upcall *)
  1209. buffer.l3ofs := buffer.ofs;
  1210. IF (buffer.nextFragment # NIL) & (nextHeader = IPv6FragmentType) THEN
  1211. (* adjust offset when a packet is fragmented*)
  1212. INC(buffer.ofs, FragmentHdrLen + MinIPHdrLen);
  1213. DEC(buffer.len, FragmentHdrLen + MinIPHdrLen);
  1214. ELSE
  1215. INC(buffer.ofs, MinIPHdrLen);
  1216. DEC(buffer.len, MinIPHdrLen);
  1217. END;
  1218. receiver(SELF, nextHeader, srcAdr, dstAdr, buffer);
  1219. Machine.AtomicInc(IP.NIPDelivered);
  1220. (* Exit here w/o returning buffer because it is passed to a receiver *)
  1221. RETURN;
  1222. ELSE
  1223. Machine.AtomicInc(IP.NIPNoReceiver);
  1224. END;
  1225. ELSIF ORD(dstAdr.ipv6Adr[15]) = 1 THEN
  1226. (* multicast to node *)
  1227. receiver := IP.receivers[nextHeader];
  1228. IF receiver # NIL THEN
  1229. (* do receiver upcall *)
  1230. buffer.l3ofs := buffer.ofs;
  1231. IF (buffer.nextFragment # NIL) & (nextHeader = IPv6FragmentType) THEN
  1232. (* adjust offset when a packet is fragmented*)
  1233. INC(buffer.ofs, FragmentHdrLen + MinIPHdrLen);
  1234. DEC(buffer.len, FragmentHdrLen + MinIPHdrLen);
  1235. ELSE
  1236. INC(buffer.ofs, MinIPHdrLen);
  1237. DEC(buffer.len, MinIPHdrLen);
  1238. END;
  1239. receiver(SELF, nextHeader, srcAdr, dstAdr, buffer);
  1240. Machine.AtomicInc(IP.NIPDelivered);
  1241. (* Exit here w/o returning buffer because it is passed to a receiver *)
  1242. RETURN;
  1243. ELSE
  1244. Machine.AtomicInc(IP.NIPNoReceiver);
  1245. END;
  1246. ELSIF IsMulticast(dstAdr) & (isRouter) & (ORD(dstAdr.ipv6Adr[15]) = 2) THEN
  1247. (* multicast packet for router; to capture these packets IPForwarding must be
  1248. turned on *)
  1249. receiver := IP.receivers[nextHeader];
  1250. IF receiver # NIL THEN
  1251. (* do receiver upcall *)
  1252. buffer.l3ofs := buffer.ofs;
  1253. IF (buffer.nextFragment # NIL) & (nextHeader = IPv6FragmentType) THEN
  1254. (* adjust offset when a packet is fragmented*)
  1255. INC(buffer.ofs, FragmentHdrLen + MinIPHdrLen);
  1256. DEC(buffer.len, FragmentHdrLen + MinIPHdrLen);
  1257. ELSE
  1258. INC(buffer.ofs, MinIPHdrLen);
  1259. DEC(buffer.len, MinIPHdrLen);
  1260. END;
  1261. receiver(SELF, nextHeader, srcAdr, dstAdr, buffer);
  1262. Machine.AtomicInc(IP.NIPDelivered);
  1263. (* Exit here w/o returning buffer because it is passed to a receiver *)
  1264. RETURN;
  1265. ELSE
  1266. Machine.AtomicInc(IP.NIPNoReceiver);
  1267. END;
  1268. ELSE
  1269. Machine.AtomicInc(IP.NIPNotForUs)
  1270. END;
  1271. ELSE
  1272. IF ~incomingFragment THEN
  1273. Machine.AtomicInc(IP.NIPSrcIsBroadcast)
  1274. END;
  1275. END;
  1276. ELSE
  1277. Machine.AtomicInc(IP.NIPBadLength)
  1278. END;
  1279. (* Exit and return buffer here because it is no longer used *)
  1280. IF ~incomingFragment THEN
  1281. Network.ReturnBuffer(buffer);
  1282. END;
  1283. END IPInput;
  1284. (** Send an IP packet on this interface. Send it directly without lookup of destination cache, etc... *)
  1285. PROCEDURE SendDirectly*(linkDst: Network.LinkAdr;
  1286. nextHeader: LONGINT;
  1287. destAdr: IP.Adr;
  1288. VAR l4hdr, data: ARRAY OF CHAR;
  1289. h4len, dofs, dlen, hopLimit: LONGINT);
  1290. VAR
  1291. l3hdr: ARRAY MaxIPHdrLen OF CHAR;
  1292. i: LONGINT;
  1293. BEGIN
  1294. IF DEBUG THEN
  1295. ASSERT (destAdr.usedProtocol = 6, 2345 );
  1296. END;
  1297. IF closed THEN
  1298. RETURN;
  1299. END; (* just in case of concurrent Send/Close *)
  1300. (* set IP header *)
  1301. l3hdr[0] := CHR(IP.IPv6*10H); (* IP version and first part of traffic class *)
  1302. l3hdr[1] := 0X; (* second part of traffic class and first part of flow label *)
  1303. Network.Put2(l3hdr, 2, 0); (* second part of flow label *)
  1304. Network.PutNet2(l3hdr, 4, h4len+dlen); (* Payload length *)
  1305. l3hdr[6] := CHR(nextHeader); (* next header *)
  1306. l3hdr[7] := CHR(hopLimit); (* Hop limit *)
  1307. (* set local address *)
  1308. FOR i := 0 TO 15 DO
  1309. l3hdr[i+8] := localAdr.ipv6Adr[i];
  1310. END;
  1311. (* set foreign address *)
  1312. FOR i := 0 TO 15 DO
  1313. l3hdr[i+24] := destAdr.ipv6Adr[i];
  1314. END;
  1315. (* perform sending *)
  1316. DoSendDirectly(linkDst, destAdr, l3hdr, l4hdr, data, MinIPHdrLen, h4len, dofs, dlen);
  1317. END SendDirectly;
  1318. (* Internal procedure to perform the rest of the send operation. Without destination cache lookup etc...,
  1319. fragmentation is not supported! *)
  1320. PROCEDURE DoSendDirectly*(linkDst: Network.LinkAdr;
  1321. destAdr: IP.Adr;
  1322. VAR l3hdr, l4hdr, data: ARRAY OF CHAR;
  1323. h3len, h4len, dofs, dlen: LONGINT) ;
  1324. BEGIN
  1325. ASSERT (destAdr.usedProtocol = 6, 2345);
  1326. IF h3len+h4len+dlen <= dev.mtu THEN
  1327. IF dev.type = Network.TypeEthernet THEN
  1328. IF IsNodeLocalAdr(destAdr) THEN
  1329. (* send local loopback. If destAdr is a node local adr packet sould only be received from
  1330. the same interfaces as it was sent *)
  1331. Machine.AtomicInc(IP.NIPSentLocalLoopback);
  1332. dev.Send(linkDst, EtherTypeIP, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen, TRUE);
  1333. ELSE
  1334. dev.Send(linkDst, EtherTypeIP, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen, FALSE);
  1335. END;
  1336. ELSE
  1337. (* Network.TypePointToPoint *)
  1338. Machine.AtomicInc(IP.NIPSentPointToPoint);
  1339. dev.Send(linkDst,
  1340. EtherTypeIP,
  1341. l3hdr,
  1342. l4hdr,
  1343. data,
  1344. h3len,
  1345. h4len,
  1346. dofs,
  1347. dlen,
  1348. IP.AdrsEqual (destAdr, localAdr));
  1349. END;
  1350. END;
  1351. END DoSendDirectly;
  1352. (** Send an IP packet on this interface. *)
  1353. PROCEDURE Send*(nextHeader: LONGINT; destAdr: IP.Adr; CONST l4hdr, data: ARRAY OF CHAR; h4len, dofs, dlen, hopLimit: LONGINT);
  1354. VAR
  1355. l3hdr: ARRAY MaxIPHdrLen OF CHAR;
  1356. i: LONGINT;
  1357. BEGIN
  1358. IF DEBUG THEN
  1359. ASSERT (destAdr.usedProtocol = 6, 2345 );
  1360. END;
  1361. IF closed THEN RETURN END; (* just in case of concurrent Send/Close *)
  1362. (* set IP header *)
  1363. l3hdr[0] := CHR(IP.IPv6*10H); (* IP version and first part of traffic class *)
  1364. l3hdr[1] := 0X; (* second part of traffic class and first part of flow label *)
  1365. Network.Put2(l3hdr, 2, 0); (* second part of flow label *)
  1366. Network.PutNet2(l3hdr, 4, h4len+dlen); (* Payload length *)
  1367. l3hdr[6] := CHR(nextHeader); (* next header *)
  1368. l3hdr[7] := CHR(hopLimit); (* Hop limit *)
  1369. (* set local address *)
  1370. FOR i := 0 TO 15 DO
  1371. l3hdr[i+8] := localAdr.ipv6Adr[i];
  1372. END;
  1373. (* set foreign address *)
  1374. FOR i := 0 TO 15 DO
  1375. l3hdr[i+24] := destAdr.ipv6Adr[i];
  1376. END;
  1377. (* perform sending *)
  1378. DoSend(destAdr, l3hdr, l4hdr, data, MinIPHdrLen, h4len, dofs, dlen);
  1379. END Send;
  1380. (* Internal procedure to perform the rest of the send operation. Used by "Send" and for IP forwarding. *)
  1381. PROCEDURE DoSend*(destAdr: IP.Adr; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT) ;
  1382. VAR
  1383. linkDst: Network.LinkAdr;
  1384. nextHop: IP.Adr;
  1385. pmtu: LONGINT;
  1386. toFragment: BOOLEAN;
  1387. BEGIN
  1388. ASSERT (destAdr.usedProtocol = 6, 2345);
  1389. toFragment := FALSE;
  1390. (* Get Path Maximum transmission unit *)
  1391. pmtu := destCache.GetPMTU(destAdr);
  1392. pmtu := MIN(pmtu, linkMTU);
  1393. pmtu := MIN(pmtu, dev.mtu);
  1394. IF h3len+h4len+dlen > pmtu THEN
  1395. (* fragment packet *)
  1396. toFragment := TRUE;
  1397. END;
  1398. IF dev.type = Network.TypeEthernet THEN
  1399. IF IsNodeLocalAdr(destAdr) OR IsLinkLocalMulticastAdr(destAdr) OR IP.AdrsEqual(destAdr, localAdr) THEN
  1400. (* send local loopback. If destAdr is a node local adr packet sould only be received from
  1401. the same interfaces as it was sent *)
  1402. Machine.AtomicInc(IP.NIPSentLocalLoopback);
  1403. dev.Send(linkDst, EtherTypeIP, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen, TRUE);
  1404. ELSE
  1405. (* check destination cache for next-hop *)
  1406. nextHop := destCache.GetNextHop(destAdr);
  1407. (* Neighbor cache lookup for link-layer address of next hop *)
  1408. IF ~neighborCache.GetLinkLayerAdr(nextHop, linkDst) THEN
  1409. (* no link-layer address found initiate address resolution packet will be queued*)
  1410. neighborCache.AddressResolution(nextHop, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen);
  1411. ELSE
  1412. IF ~toFragment THEN
  1413. dev.Send(linkDst, EtherTypeIP, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen, FALSE);
  1414. ELSE
  1415. DoFragAndSend(pmtu, linkDst, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen);
  1416. END;
  1417. END;
  1418. END;
  1419. ELSE
  1420. (* Network.TypePointToPoint *)
  1421. Machine.AtomicInc(IP.NIPSentPointToPoint);
  1422. dev.Send(linkDst,
  1423. EtherTypeIP,
  1424. l3hdr,
  1425. l4hdr,
  1426. data,
  1427. h3len,
  1428. h4len,
  1429. dofs,
  1430. dlen,
  1431. IP.AdrsEqual (destAdr, localAdr));
  1432. END;
  1433. END DoSend;
  1434. (** Fragment packets and send them *)
  1435. PROCEDURE DoFragAndSend(pmtu: LONGINT; linkDst: Network.LinkAdr; l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT);
  1436. VAR
  1437. maxDataLen: LONGINT;
  1438. fragmentOffset: LONGINT;
  1439. oldNextHeader: LONGINT;
  1440. l4hdrFragment: POINTER TO ARRAY OF CHAR; (* fragment header *)
  1441. dataFragment: POINTER TO ARRAY OF CHAR; (* fragment data *)
  1442. fragmentHdrSet: SET;
  1443. fragID: LONGINT;
  1444. i: LONGINT;
  1445. BEGIN
  1446. fragID := GetFragmentID();
  1447. (* do fragmentation *)
  1448. maxDataLen := pmtu - MinIPHdrLen - FragmentHdrLen;
  1449. DEC(maxDataLen, maxDataLen MOD 8); (* 64-bit boundary *)
  1450. fragmentOffset := 0;
  1451. (* change IP header *)
  1452. oldNextHeader := ORD(l3hdr[6]); (* next header *)
  1453. l3hdr[6] := CHR(IPv6FragmentType);
  1454. (* build fragment header *)
  1455. NEW(l4hdrFragment, FragmentHdrLen);
  1456. fragmentHdrSet := {};
  1457. fragmentHdrSet := fragmentHdrSet + {0};
  1458. Network.PutNet4(l4hdrFragment^, 0, SYSTEM.VAL(LONGINT, fragmentHdrSet));
  1459. l4hdrFragment^[0] := CHR(oldNextHeader);
  1460. Network.PutNet4(l4hdrFragment^, 4, fragID);
  1461. (* fragment data *)
  1462. NEW(dataFragment, maxDataLen);
  1463. FOR i := 0 TO h4len - 1 DO
  1464. dataFragment^[i] := l4hdr[i];
  1465. END;
  1466. FOR i := h4len TO maxDataLen - 1 DO
  1467. dataFragment^[i] := data[i-h4len + dofs];
  1468. END;
  1469. INC(fragmentOffset, maxDataLen - h4len + dofs);
  1470. (* adjust payload length *)
  1471. Network.PutNet2(l3hdr, 4, maxDataLen + FragmentHdrLen);
  1472. (* first packet *)
  1473. dev.Send(linkDst, EtherTypeIP, l3hdr, l4hdrFragment^, dataFragment^, h3len, FragmentHdrLen, 0, maxDataLen, FALSE);
  1474. WHILE fragmentOffset < h4len + dlen DO
  1475. IF fragmentOffset + maxDataLen > h4len + dlen THEN
  1476. (* last fragment *)
  1477. fragmentHdrSet := SYSTEM.VAL(SET, LSH((fragmentOffset - dofs + h4len) DIV 8, 3));
  1478. fragmentHdrSet := fragmentHdrSet - {0, 1, 2};
  1479. Network.PutNet4(l4hdrFragment^, 0, SYSTEM.VAL(LONGINT, fragmentHdrSet));
  1480. l4hdrFragment^[0] := CHR(oldNextHeader);
  1481. l4hdrFragment^[1] := 0X;
  1482. Network.PutNet4(l4hdrFragment^, 4, fragID);
  1483. (* fragment data *)
  1484. FOR i := 0 TO dlen - fragmentOffset - 1 DO
  1485. dataFragment^[i] := data[i + fragmentOffset];
  1486. END;
  1487. (* adjust payload length *)
  1488. Network.PutNet2(l3hdr, 4, dlen - fragmentOffset + FragmentHdrLen);
  1489. dev.Send(linkDst, EtherTypeIP, l3hdr, l4hdrFragment^, dataFragment^, h3len, FragmentHdrLen, 0, dlen - fragmentOffset, FALSE);
  1490. INC(fragmentOffset, maxDataLen);
  1491. ELSE
  1492. (* fragment in the middle *)
  1493. fragmentHdrSet := SYSTEM.VAL(SET, LSH((fragmentOffset - dofs + h4len) DIV 8, 3));
  1494. fragmentHdrSet := fragmentHdrSet + {0} - {1,2};
  1495. Network.PutNet4(l4hdrFragment^, 0, SYSTEM.VAL(LONGINT, fragmentHdrSet));
  1496. l4hdrFragment^[0] := CHR(oldNextHeader);
  1497. l4hdrFragment^[1] := 0X;
  1498. Network.PutNet4(l4hdrFragment^, 4, fragID);
  1499. (* fragment data *)
  1500. FOR i := 0 TO maxDataLen - 1 DO
  1501. dataFragment^[i] := data[i + fragmentOffset];
  1502. END;
  1503. dev.Send(linkDst, EtherTypeIP, l3hdr, l4hdrFragment^, dataFragment^, h3len, FragmentHdrLen, 0, maxDataLen, FALSE);
  1504. INC(fragmentOffset, maxDataLen);
  1505. END;
  1506. END;
  1507. END DoFragAndSend;
  1508. (** Enumerate all ARP table entries. In IPv6 Enumerate the Neighbors*)
  1509. PROCEDURE ARPEnumerate*(handle: IP.ARPHandler);
  1510. (* This procedure has to be inherited but is ignored because in IPv6 ARP is not used *)
  1511. END ARPEnumerate;
  1512. (** Performs a check for Network if a packet is accepted by this interface *)
  1513. PROCEDURE IsPacketAccepted(buffer: Network.Buffer): BOOLEAN;
  1514. VAR
  1515. i: LONGINT;
  1516. isAccepted: BOOLEAN;
  1517. BEGIN
  1518. isAccepted := TRUE;
  1519. IF ~IP.IsNilAdr(localAdr) THEN
  1520. (* When interface is not yet configurated take all packets *)
  1521. (* If it is a link-local interface take link-local multicast packets *)
  1522. IF ~((IsLinkLocalAdr(localAdr)) & (buffer.data[24] = 0FFX)) THEN
  1523. FOR i := 0 TO 15 DO
  1524. IF buffer.data[i+24] # localAdr.ipv6Adr[i] THEN
  1525. isAccepted := FALSE;
  1526. END;
  1527. END;
  1528. END;
  1529. END;
  1530. RETURN isAccepted;
  1531. END IsPacketAccepted;
  1532. (** Checks if an IPv6 address is a multicast address in IPv6 there are no broadcasts *)
  1533. PROCEDURE IsBroadcast*(adr: IP.Adr) : BOOLEAN;
  1534. BEGIN
  1535. RETURN IsMulticast (adr);
  1536. END IsBroadcast;
  1537. (** Check if adr is a local multicast address *)
  1538. PROCEDURE IsMulticast*(adr: IP.Adr) : BOOLEAN;
  1539. BEGIN
  1540. IF adr.ipv6Adr[0] = 0FFX THEN
  1541. RETURN TRUE;
  1542. ELSE
  1543. RETURN FALSE;
  1544. END;
  1545. END IsMulticast;
  1546. (* Checks if adr is a solicited node address *)
  1547. PROCEDURE IsSolicitedNodeAdr(adr: IP.Adr): BOOLEAN;
  1548. VAR
  1549. isSolicitedNode: BOOLEAN;
  1550. BEGIN
  1551. isSolicitedNode := TRUE;
  1552. IF ~AdrsPartEqual(linkLocalMulticastNodeAdr, adr, 0, 1) THEN
  1553. isSolicitedNode := FALSE;
  1554. END;
  1555. IF ~AdrsPartEqual(IP.NilAdr, adr, 2, 10) THEN
  1556. isSolicitedNode := FALSE;
  1557. END;
  1558. IF ~((adr.ipv6Adr[11] = 1X) & (adr.ipv6Adr[12] = 0FFX)) THEN
  1559. isSolicitedNode := FALSE;
  1560. END;
  1561. IF ~AdrsPartEqual(localAdr, adr, 13, 15) THEN
  1562. isSolicitedNode := FALSE
  1563. END;
  1564. RETURN isSolicitedNode;
  1565. END IsSolicitedNodeAdr;
  1566. (* Check if adr is a node-local adr: localAdr, nodeLocalMulticastAdr *)
  1567. PROCEDURE IsNodeLocalAdr (adr: IP.Adr): BOOLEAN;
  1568. VAR
  1569. isNodeLocal: BOOLEAN;
  1570. BEGIN
  1571. isNodeLocal := FALSE;
  1572. IF (IP.AdrsEqual(adr, localAdr)) OR (IP.AdrsEqual(adr, nodeLocalMulticastNodeAdr)) THEN
  1573. isNodeLocal := TRUE;
  1574. END;
  1575. RETURN isNodeLocal;
  1576. END IsNodeLocalAdr;
  1577. (* Reads the source address of a IP packet buffer *)
  1578. PROCEDURE ReadSrcAdr* (buffer: Network.Buffer): IP.Adr;
  1579. VAR
  1580. i: LONGINT;
  1581. retAdr: IP.Adr;
  1582. BEGIN
  1583. retAdr.usedProtocol := IP.IPv6;
  1584. FOR i := 0 TO 15 DO
  1585. retAdr.ipv6Adr[i] := buffer.data[i+8];
  1586. END;
  1587. RETURN retAdr;
  1588. END ReadSrcAdr;
  1589. (* Reads the destination address of a IP packet buffer *)
  1590. PROCEDURE ReadDestAdr* (buffer: Network.Buffer):IP. Adr;
  1591. VAR
  1592. i: LONGINT;
  1593. retAdr: IP.Adr;
  1594. BEGIN
  1595. retAdr.usedProtocol := IP.IPv6;
  1596. FOR i := 0 TO 15 DO
  1597. retAdr.ipv6Adr[i] := buffer.data[i+24];
  1598. END;
  1599. RETURN retAdr;
  1600. END ReadDestAdr;
  1601. (* writes the interface ID to a IPv6 address (last 64 bits) *)
  1602. PROCEDURE SetInterfaceID*(VAR ip: IP.Adr);
  1603. VAR
  1604. bitSet: SET;
  1605. BEGIN
  1606. (* IEEE 802 Address to IPv6 Interface Identifier:
  1607. cccccc00 cccccccc cccccccc xxxxxxxx xxxxxxxx xxxxxxxx
  1608. IEEE 802 Address
  1609. ccccccc00 cccccccc cccccccc 11111111 11111110 xxxxxxxx xxxxxxxx xxxxxxxx
  1610. EUI-64 address
  1611. cccccc10 cccccccc cccccccc 11111111 11111110 xxxxxxxx xxxxxxxx xxxxxxxx
  1612. *)
  1613. ip.usedProtocol := IP.IPv6;
  1614. ip.ipv6Adr[13] := dev.local[3];
  1615. ip.ipv6Adr[14] := dev.local[4];
  1616. ip.ipv6Adr[15] := dev.local[5];
  1617. ip.ipv6Adr[11] := 0FFX;
  1618. ip.ipv6Adr[12] := 0FEX;
  1619. ip.ipv6Adr[8] := dev.local[0];
  1620. ip.ipv6Adr[9] := dev.local[1];
  1621. ip.ipv6Adr[10] := dev.local[2];
  1622. bitSet := SYSTEM.VAL(SET, ip.ipv6Adr[8]);
  1623. (* toggle second bit *)
  1624. IF 1 IN bitSet THEN
  1625. bitSet := bitSet - {1};
  1626. ELSE
  1627. bitSet := bitSet + {1};
  1628. END;
  1629. ip.ipv6Adr[8] := SYSTEM.VAL(CHAR, bitSet);
  1630. END SetInterfaceID;
  1631. (** Creates a pseudo-header for checksum calculation (TCP/UDP) and returns the length of this header *)
  1632. PROCEDURE WritePseudoHeader*(VAR pseudoHdr: ARRAY OF CHAR;
  1633. src, dst: IP.Adr;
  1634. nextHeader, pktLengthUpperLayer: LONGINT): LONGINT;
  1635. VAR
  1636. i: LONGINT;
  1637. tmpAdr: ARRAY 4 OF LONGINT;
  1638. BEGIN
  1639. (* UDP/TCP Pseudo-header (for checksum calculation)
  1640. 00 128 source address
  1641. 16 128 destination address
  1642. 32 32 Upper Layer Packet Length
  1643. 36 24 zero = 0
  1644. 39 8 Next header *)
  1645. IF DEBUG THEN
  1646. ASSERT (IP.IsNilAdr(src) OR (src.usedProtocol = IP.IPv6));
  1647. ASSERT (IP.IsNilAdr(dst) OR (dst.usedProtocol = IP.IPv6));
  1648. END;
  1649. (* cast src adr to LONGINT array *)
  1650. FOR i := 0 TO 3 DO
  1651. tmpAdr[i] := ORD(src.ipv6Adr[i*4 + 0]);
  1652. tmpAdr[i] := (tmpAdr[i] * 256) + ORD(src.ipv6Adr[i*4 + 1]);
  1653. tmpAdr[i] := (tmpAdr[i] * 256) + ORD(src.ipv6Adr[i*4 + 2]);
  1654. tmpAdr[i] := (tmpAdr[i] * 256) + ORD(src.ipv6Adr[i*4 + 3]);
  1655. Network.PutNet4(pseudoHdr, i*4, tmpAdr[i]); (* local IP address *)
  1656. END;
  1657. (* cast dst adr to LONGINT array *)
  1658. FOR i := 0 TO 3 DO
  1659. tmpAdr[i] := 0;
  1660. tmpAdr[i] := ORD(dst.ipv6Adr[i*4 + 0]);
  1661. tmpAdr[i] := (tmpAdr[i] * 256) + ORD(dst.ipv6Adr[i*4 + 1]);
  1662. tmpAdr[i] := (tmpAdr[i] * 256) + ORD(dst.ipv6Adr[i*4 + 2]);
  1663. tmpAdr[i] := (tmpAdr[i] * 256) + ORD(dst.ipv6Adr[i*4 + 3]);
  1664. Network.PutNet4(pseudoHdr, (i*4)+16, tmpAdr[i]); (* foreign IP address *)
  1665. END;
  1666. (* Upper Layer Packet Length *)
  1667. Network.PutNet4(pseudoHdr, 32, pktLengthUpperLayer);
  1668. (* Zero and next header *)
  1669. Network.PutNet4(pseudoHdr, 36, nextHeader);
  1670. RETURN 40; (* IPv6 pseudo header length *)
  1671. END WritePseudoHeader;
  1672. (* Received a neighbor solicitation message *)
  1673. PROCEDURE ReceiveNeighborSolicitation*(srcAdr, dstAdr: IP.Adr; buffer: Network.Buffer);
  1674. VAR
  1675. target: IP.Adr;
  1676. i: LONGINT;
  1677. int: IP.Interface;
  1678. BEGIN
  1679. target.usedProtocol := IP.IPv6;
  1680. FOR i := 0 TO 15 DO
  1681. target.ipv6Adr[i] := buffer.data[buffer.ofs + 4 + i];
  1682. END;
  1683. int := IP.InterfaceByDstIP(target);
  1684. IF (int # NIL) & (IP.AdrsEqual(int.localAdr, target)) THEN
  1685. (* send a soliciated neighbor advertisement message *)
  1686. sendNeighborAdvertisement(int(Interface), buffer.src, srcAdr, TRUE);
  1687. END;
  1688. Network.ReturnBuffer(buffer);
  1689. END ReceiveNeighborSolicitation;
  1690. (* Received a neighbor advertisement message *)
  1691. PROCEDURE ReceiveNeighborAdvertisement* (srcAdr, dstAdr: IP.Adr; buffer: Network.Buffer);
  1692. VAR
  1693. neighborEntry: NeighborCacheEntry;
  1694. flags: SET;
  1695. routerFlag: BOOLEAN;
  1696. solicitedFlag: BOOLEAN;
  1697. overrideFlag: BOOLEAN;
  1698. linkAdrsEqual: BOOLEAN; (* Are both link-addresses equal (in neighbor advertisement and cache *)
  1699. hasTargetLinkOption: BOOLEAN;
  1700. targetLinkAdr: Network.LinkAdr;
  1701. newRouter: IP.Adr;
  1702. BEGIN
  1703. (* Check for duplicated address *)
  1704. IF IP.AdrsEqual(srcAdr, localAdr) THEN
  1705. KernelLog.Ln; KernelLog.String("Duplicate address detected. Shuting down interface: ");
  1706. KernelLog.String(dev.name);
  1707. KernelLog.Ln;
  1708. Close;
  1709. ELSE
  1710. neighborEntry := neighborCache.Get(srcAdr);
  1711. IF neighborEntry = NIL THEN
  1712. (* make a new entry. According to RFC 2461 entry should not be added. But because of V6InterfaceByDstIP
  1713. unsolicited neigbor advertisements have to be accepted *)
  1714. neighborCache.Add(srcAdr);
  1715. neighborEntry := neighborCache.Get(srcAdr);
  1716. END;
  1717. (* read flags *)
  1718. flags := SYSTEM.VAL(SET, Network.GetNet4(buffer.data, buffer.ofs));
  1719. routerFlag := 31 IN flags;
  1720. solicitedFlag := 30 IN flags;
  1721. overrideFlag := 29 IN flags;
  1722. IF neighborEntry.reachability = Incomplete THEN
  1723. (* save link address *)
  1724. neighborEntry.linkAdr := buffer.src;
  1725. IF solicitedFlag THEN
  1726. neighborEntry.reachability := Reachable;
  1727. Kernel.SetTimer(neighborEntry.lastConfirmation, ReachableTime);
  1728. ELSE
  1729. neighborEntry.reachability := Stale;
  1730. END;
  1731. neighborEntry.isRouter := routerFlag;
  1732. neighborCache.SendQueuedPackets(neighborEntry);
  1733. ELSE
  1734. (* reachability is not incomplete *)
  1735. IF (buffer.len - buffer.ofs) > (MinIPHdrLen + IP.ICMPHdrLen + NeighborHdrLen) THEN
  1736. (* Option is available *)
  1737. IF (buffer.data[buffer.ofs + NeighborHdrLen] = 2X) & (buffer.data[buffer.ofs + NeighborHdrLen + 1] = 1X) THEN
  1738. (* Target link-layer address option *)
  1739. hasTargetLinkOption := TRUE;
  1740. buffer.ofs := buffer.ofs + NeighborHdrLen;
  1741. icmpLinkLayerAdrOption(buffer, targetLinkAdr);
  1742. linkAdrsEqual := Network.LinkAdrsEqual(targetLinkAdr, neighborEntry.linkAdr);
  1743. ELSE
  1744. hasTargetLinkOption := FALSE;
  1745. linkAdrsEqual := FALSE;
  1746. END;
  1747. ELSE
  1748. hasTargetLinkOption := FALSE;
  1749. linkAdrsEqual := FALSE;
  1750. END;
  1751. IF (~overrideFlag) & (~linkAdrsEqual) & (neighborEntry.reachability = Reachable) THEN
  1752. neighborEntry.reachability := Stale;
  1753. END;
  1754. IF overrideFlag OR (~overrideFlag & linkAdrsEqual) OR (~hasTargetLinkOption) THEN
  1755. (* Update neighbor cache *)
  1756. IF hasTargetLinkOption THEN
  1757. neighborEntry.linkAdr := targetLinkAdr
  1758. END;
  1759. IF solicitedFlag THEN
  1760. neighborEntry.reachability := Reachable;
  1761. Kernel.SetTimer(neighborEntry.lastConfirmation, ReachableTime);
  1762. ELSIF hasTargetLinkOption THEN
  1763. neighborEntry.reachability := Stale;
  1764. END;
  1765. IF (neighborEntry.isRouter) & ~routerFlag THEN
  1766. (* changed from a router to normal host *)
  1767. routers.Remove(neighborEntry.neighborIP);
  1768. newRouter := routers.GetRouter();
  1769. destCache.ChangeDests(neighborEntry.neighborIP, newRouter);
  1770. END;
  1771. neighborEntry.isRouter := routerFlag;
  1772. END;
  1773. END;
  1774. END;
  1775. Network.ReturnBuffer(buffer);
  1776. END ReceiveNeighborAdvertisement;
  1777. (* initiate a router solicitation *)
  1778. PROCEDURE RouterSolicitation*;
  1779. BEGIN
  1780. sendRouterSolicitation(SELF);
  1781. INC(routerSolCount);
  1782. END RouterSolicitation;
  1783. (* Receive a Router Advertisement message *)
  1784. PROCEDURE ReceiveRouterAdvertisement*(srcAdr: IP.Adr; buffer: Network.Buffer);
  1785. VAR
  1786. int: IP.Interface;
  1787. intv6: Interface;
  1788. intName: IP.Name;
  1789. newLocalAdr: IP.Adr;
  1790. hopLimit: LONGINT;
  1791. flags: SET;
  1792. managedFlag: BOOLEAN;
  1793. otherStatefulFlag: BOOLEAN;
  1794. homeAgentFlag: BOOLEAN;
  1795. routerLifetime: LONGINT;
  1796. reachableTime: LONGINT;
  1797. retransTimer: LONGINT;
  1798. linkAdr: Network.LinkAdr;
  1799. mtu: LONGINT;
  1800. onLink: ARRAY MaxPrefixOptions OF BOOLEAN;
  1801. autonomous: ARRAY MaxPrefixOptions OF BOOLEAN;
  1802. routerAddress: ARRAY MaxPrefixOptions OF BOOLEAN;
  1803. sitePrefix: ARRAY MaxPrefixOptions OF BOOLEAN;
  1804. validLifetime: ARRAY MaxPrefixOptions OF LONGINT;
  1805. preferredLifetime: ARRAY MaxPrefixOptions OF LONGINT;
  1806. sitePrefixLength: ARRAY MaxPrefixOptions OF LONGINT;
  1807. localPrefix: ARRAY MaxPrefixOptions OF IP.Adr;
  1808. router: RoutersEntry;
  1809. hasSrcLinkLayerOption: BOOLEAN;
  1810. hasMTUOption: BOOLEAN;
  1811. prefixItem: PrefixesEntry;
  1812. nbrOfPrefixOpt: LONGINT;
  1813. i: LONGINT;
  1814. res: WORD;
  1815. tmpStr: ARRAY 8 OF CHAR;
  1816. (* Parse options of a router advertisement message return FALSE on error *)
  1817. PROCEDURE ParseRouterAdvOptions(): BOOLEAN;
  1818. BEGIN
  1819. WHILE buffer.len > 0 DO
  1820. (* Options are available *)
  1821. CASE ORD(buffer.data[buffer.ofs]) OF
  1822. IP.ICMPSrcLLAdrOptionType:
  1823. (* Check length field *)
  1824. IF ORD(buffer.data[buffer.ofs + 1]) <= 0 THEN
  1825. RETURN FALSE;
  1826. END;
  1827. hasSrcLinkLayerOption := TRUE;
  1828. icmpLinkLayerAdrOption(buffer, linkAdr);
  1829. |IP.ICMPPrefixInfoOptionType:
  1830. (* Check length field *)
  1831. IF ORD(buffer.data[buffer.ofs + 1]) <= 0 THEN
  1832. RETURN FALSE;
  1833. END;
  1834. icmpPrefixInfoOption(buffer,
  1835. onLink[nbrOfPrefixOpt],
  1836. autonomous[nbrOfPrefixOpt],
  1837. routerAddress[nbrOfPrefixOpt],
  1838. sitePrefix[nbrOfPrefixOpt],
  1839. validLifetime[nbrOfPrefixOpt],
  1840. preferredLifetime[nbrOfPrefixOpt],
  1841. sitePrefixLength[nbrOfPrefixOpt],
  1842. localPrefix[nbrOfPrefixOpt]);
  1843. INC(nbrOfPrefixOpt);
  1844. |IP.ICMPMTUOptionType:
  1845. (* Check length field *)
  1846. IF ORD(buffer.data[buffer.ofs + 1]) <= 0 THEN
  1847. RETURN FALSE;
  1848. END;
  1849. hasMTUOption := TRUE;
  1850. icmpMTUOption(buffer, mtu);
  1851. mtu := MIN(mtu, linkMTU);
  1852. mtu := MIN(mtu, dev.mtu);
  1853. |IP.ICMPAdvIntOptionType:
  1854. (* Check length field *)
  1855. IF ORD(buffer.data[buffer.ofs + 1]) <= 0 THEN
  1856. RETURN FALSE;
  1857. END;
  1858. icmpAdvIntervalOption(buffer);
  1859. |IP.ICMPHomeAgOptionType:
  1860. (* Check length field *)
  1861. IF ORD(buffer.data[buffer.ofs + 1]) <= 0 THEN
  1862. RETURN FALSE;
  1863. END;
  1864. icmpHomeAgentInfoOption(buffer);
  1865. |IP.ICMPRouteOption:
  1866. (* Check length field *)
  1867. IF ORD(buffer.data[buffer.ofs + 1]) <= 0 THEN
  1868. RETURN FALSE;
  1869. END;
  1870. icmpRouteInfoOption(buffer);
  1871. ELSE
  1872. (* packet is not well-formed *)
  1873. IF DEBUG THEN
  1874. ASSERT(TRUE);
  1875. END;
  1876. RETURN FALSE;
  1877. END;
  1878. END;
  1879. RETURN TRUE; (* no error occured *)
  1880. END ParseRouterAdvOptions;
  1881. (* create IPv6-interfaces if necessary *)
  1882. PROCEDURE createInterfaces;
  1883. VAR
  1884. i: LONGINT;
  1885. currentPrefix: LONGINT;
  1886. BEGIN
  1887. (* autoconfiguration of interfaces *)
  1888. IF autoconfigurated THEN
  1889. IF createStatelessInterface THEN
  1890. (* FOR i := 0 TO (nbrOfPrefixOpt - 1) DO if this for loop is used programm crashes *)
  1891. currentPrefix := 0;
  1892. WHILE currentPrefix < nbrOfPrefixOpt DO
  1893. IF autonomous[currentPrefix] THEN
  1894. Strings.IntToStr(currentPrefix, tmpStr);
  1895. Strings.Concat(V6RouterIntName, tmpStr, intName);
  1896. Strings.Concat(intName , dev.name, intName);
  1897. NEW(intv6, intName, dev, res);
  1898. int := intv6;
  1899. IF res = IP.Ok THEN
  1900. int(Interface).autoconfigurated := TRUE;
  1901. newLocalAdr := localPrefix[currentPrefix];
  1902. newLocalAdr.data := 0;
  1903. int(Interface).SetInterfaceID(newLocalAdr);
  1904. int.SetAdrs(newLocalAdr, localPrefix[currentPrefix], IP.NilAdr, res);
  1905. IF res = IP.Ok THEN
  1906. KernelLog.String("IPv6: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  1907. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  1908. IP.OutInterface(int);
  1909. int(Interface).createStatelessInterface := FALSE;
  1910. (* set available DNS *)
  1911. FOR i := 0 TO DNScount - 1 DO
  1912. int.DNSAdd(DNS[i]);
  1913. END;
  1914. (* use the same caches for interfaces on the same device *)
  1915. int(Interface).routers := routers;
  1916. int(Interface).prefixes := prefixes;
  1917. int(Interface).neighborCache := neighborCache;
  1918. int(Interface).destCache := destCache;
  1919. END;
  1920. END;
  1921. END;
  1922. INC(currentPrefix);
  1923. END;
  1924. END;
  1925. IF createStatefulInterface THEN
  1926. (* (* create new interface on which asks a DHCPv6 *)
  1927. Strings.Concat(V6DHCPIntName , dev.name, intName);
  1928. NEW (intv6, intName, dev, res);
  1929. IF res = IP.Ok THEN
  1930. (* configure DHCP interface *)
  1931. END;
  1932. *) END;
  1933. END;
  1934. END createInterfaces;
  1935. BEGIN
  1936. hasSrcLinkLayerOption := FALSE;
  1937. hasMTUOption := FALSE;
  1938. nbrOfPrefixOpt := 0;
  1939. (* Checks if a router advertisement message is valid *)
  1940. (* Accept only link-local packets *)
  1941. IF ~AdrsPartEqual(srcAdr, linkLocalPrefix, 0, (linkLocalPrefix.data DIV 8) - 1 (* number of bytes *)) THEN
  1942. Network.ReturnBuffer(buffer);
  1943. RETURN;
  1944. END;
  1945. (* Hop limit = 255 *)
  1946. IF buffer.data[7] # 0FFX THEN
  1947. RETURN
  1948. END;
  1949. (* ICMP Code field = 0 *)
  1950. IF buffer.data[buffer.ofs - 3] # 0X THEN
  1951. RETURN;
  1952. END;
  1953. (* read packet contents *)
  1954. hopLimit := ORD(buffer.data[buffer.ofs]);
  1955. (* read flags *)
  1956. flags := SYSTEM.VAL(SET, Network.GetNet4(buffer.data, buffer.ofs + 1));
  1957. managedFlag := 31 IN flags;
  1958. otherStatefulFlag := 30 IN flags;
  1959. homeAgentFlag := 29 IN flags;
  1960. routerLifetime := Network.GetNet2(buffer.data, buffer.ofs + 2);
  1961. reachableTime := SYSTEM.VAL(LONGINT, Network.GetNet4(buffer.data, buffer.ofs + 4));
  1962. retransTimer := SYSTEM.VAL(LONGINT, Network.GetNet4(buffer.data, buffer.ofs + 8));
  1963. INC(buffer.ofs, RouterAdvHdrLen);
  1964. DEC(buffer.len, RouterAdvHdrLen);
  1965. (* Parse available options *)
  1966. IF ~ ParseRouterAdvOptions() THEN
  1967. Network.ReturnBuffer(buffer);
  1968. RETURN;
  1969. END;
  1970. (* Update default router list *)
  1971. router := routers.Get(srcAdr);
  1972. IF (router = NIL) & (routerLifetime # 0) THEN
  1973. (* Add a new default router *)
  1974. router := routers.Add(srcAdr, linkAdr, routerLifetime);
  1975. END;
  1976. Kernel.SetTimer(router.routerLifetime, routerLifetime * 1000);
  1977. IF routerLifetime # 0 THEN
  1978. IF hopLimit # 0 THEN
  1979. curHopLimit := hopLimit;
  1980. END;
  1981. ELSE
  1982. (* update destination cache for destinations using this router *)
  1983. router.router.reachability := Probe;
  1984. destCache.ChangeDests(srcAdr, routers.GetRouter());
  1985. END;
  1986. IF hasSrcLinkLayerOption & (routerLifetime # 0) THEN
  1987. IF router.router.linkAdr # linkAdr THEN
  1988. router.router.reachability := Stale;
  1989. router.router.linkAdr := linkAdr;
  1990. END;
  1991. END;
  1992. IF hasMTUOption & (mtu >= MinIPHdrLen)THEN
  1993. linkMTU := mtu;
  1994. END;
  1995. router.router.isRouter := TRUE;
  1996. (* go through all prefix options and update them *)
  1997. FOR i := 0 TO nbrOfPrefixOpt - 1 DO
  1998. IF onLink[i] THEN
  1999. prefixItem := prefixes.Get(localPrefix[i]);
  2000. IF prefixItem = NIL THEN
  2001. IF validLifetime[i] # 0 THEN
  2002. prefixes.Add(localPrefix[i], validLifetime[i]);
  2003. END;
  2004. ELSE
  2005. IF validLifetime[i] = 0 THEN
  2006. (* timeout prefix *)
  2007. prefixes.Remove(localPrefix[i]);
  2008. ELSE
  2009. Kernel.SetTimer(prefixItem.lifetime, validLifetime[i] * 1000); (* milliseconds *)
  2010. END;
  2011. END;
  2012. END;
  2013. END;
  2014. IF managedFlag OR otherStatefulFlag THEN
  2015. createStatefulInterface := TRUE;
  2016. END;
  2017. (* create necessary IPv6-interfaces *)
  2018. createInterfaces;
  2019. Network.ReturnBuffer(buffer);
  2020. END ReceiveRouterAdvertisement;
  2021. (** Receive a router solicitation message *)
  2022. PROCEDURE ReceiveRouterSolicitation*;
  2023. BEGIN
  2024. IF isRouter THEN
  2025. (* send a solicited router advertisement *)
  2026. sendRouterAdvertisement(SELF, linkLocalMulticastNodeAdr, linkMulticastAllNodesAdr, routerConfig);
  2027. END;
  2028. END ReceiveRouterSolicitation;
  2029. (* Receive a packet too big ICMP message *)
  2030. PROCEDURE ReceivePacketTooBig*(from: IP.Adr; buffer: Network.Buffer);
  2031. VAR
  2032. newPMTU: LONGINT;
  2033. BEGIN
  2034. (* ICMP Code field = 0 *)
  2035. IF buffer.data[buffer.ofs - 3] = 0X THEN
  2036. newPMTU := Network.GetNet4(buffer.data, 0);
  2037. destCache.ChangePMTU(from, newPMTU);
  2038. END;
  2039. Network.ReturnBuffer(buffer);
  2040. END ReceivePacketTooBig;
  2041. (** Configurate this interface as a router *)
  2042. PROCEDURE ConfigAsRouter*(newRouterConfig: RouterConfig);
  2043. VAR
  2044. prefixConfigItem: PrefixConfig;
  2045. intv6: Interface;
  2046. count: LONGINT;
  2047. tmpStr: ARRAY 8 OF CHAR;
  2048. newLocalAdr: IP.Adr;
  2049. res: WORD;
  2050. i: LONGINT;
  2051. BEGIN
  2052. isRouter := TRUE;
  2053. routerConfig := newRouterConfig;
  2054. routerConfig.next := NIL;
  2055. KernelLog.String("Interface "); KernelLog.String(name); KernelLog.String(" is configured as a IPv6 router"); KernelLog.Ln;
  2056. (* create an interface according to the router configuration *)
  2057. count := 0;
  2058. prefixConfigItem := newRouterConfig.Prefixes;
  2059. WHILE prefixConfigItem # NIL DO
  2060. IF prefixConfigItem.Autonomous THEN
  2061. Strings.IntToStr(count, tmpStr);
  2062. Strings.Concat(V6OwnRouterIntName, tmpStr, intName);
  2063. Strings.Concat(intName, dev.name, intName);
  2064. NEW(intv6, intName, dev, res);
  2065. IF res = IP.Ok THEN
  2066. intv6.autoconfigurated := TRUE;
  2067. newLocalAdr := prefixConfigItem.Prefix;
  2068. newLocalAdr.data := 0;
  2069. intv6.SetInterfaceID(newLocalAdr);
  2070. intv6.SetAdrs(newLocalAdr, prefixConfigItem.Prefix, IP.NilAdr, res);
  2071. IF res = IP.Ok THEN
  2072. KernelLog.String("IPv6: Add interface for LinkDevice '"); KernelLog.String(dev.name);
  2073. KernelLog.String("'. Error code: "); KernelLog.Int(res, 0); KernelLog.Ln;
  2074. IP.OutInterface(intv6);
  2075. intv6.createStatelessInterface := FALSE;
  2076. (* set available DNS *)
  2077. FOR i := 0 TO DNScount - 1 DO
  2078. intv6.DNSAdd(DNS[i]);
  2079. END;
  2080. (* use the same caches for interfaces on the same device *)
  2081. intv6.routers := routers;
  2082. intv6.prefixes := prefixes;
  2083. intv6.neighborCache := neighborCache;
  2084. intv6.destCache := destCache;
  2085. END;
  2086. END;
  2087. INC(count);
  2088. END;
  2089. prefixConfigItem := prefixConfigItem.next;
  2090. END;
  2091. END ConfigAsRouter;
  2092. (** Adds a packet to the fragment list *)
  2093. PROCEDURE AddToFragmentList(srcAdr, dstAdr: IP.Adr; buffer: Network.Buffer);
  2094. VAR
  2095. fragmentListItem: FragmentList;
  2096. newPacketFragmentItem: PacketFragment;
  2097. packetFragmentItem: PacketFragment;
  2098. fragmentID: LONGINT;
  2099. (** Ad new fragmentItem *)
  2100. PROCEDURE CreateNewFragAndAdd;
  2101. BEGIN
  2102. NEW(fragmentListItem);
  2103. fragmentListItem.fragmentID := fragmentID;
  2104. fragmentListItem.nextHeader := ORD(buffer.data[buffer.ofs]);
  2105. fragmentListItem.srcAdr := srcAdr;
  2106. fragmentListItem.dstAdr := dstAdr;
  2107. Kernel.SetTimer(fragmentListItem.startedAt, 60000); (* 60 seconds *)
  2108. fragmentListItem.fragmentCount := 1;
  2109. NEW(newPacketFragmentItem);
  2110. newPacketFragmentItem.buffer := buffer;
  2111. (* calculate fragment offset & more fragments flag *)
  2112. buffer.data[buffer.ofs] := 0X;
  2113. newPacketFragmentItem.fragmentOffset := Network.GetNet4(buffer.data, buffer.ofs);
  2114. (* more fragments flag *)
  2115. newPacketFragmentItem.moreFragments := 0 IN SYSTEM.VAL(SET, newPacketFragmentItem.fragmentOffset);
  2116. newPacketFragmentItem.fragmentOffset := 8 * (newPacketFragmentItem.fragmentOffset DIV 8); (* shift 3 right times 8 *)
  2117. buffer.data[buffer.ofs] := CHR(fragmentListItem.nextHeader);
  2118. newPacketFragmentItem.next := NIL;
  2119. newPacketFragmentItem.prev := NIL;
  2120. fragmentListItem.packets := newPacketFragmentItem;
  2121. fragmentListItem.next := fragmentList;
  2122. fragmentList := fragmentListItem;
  2123. END CreateNewFragAndAdd;
  2124. BEGIN
  2125. fragmentID := Network.GetNet4(buffer.data, buffer.ofs + 4);
  2126. (* Does already a entry exist *)
  2127. fragmentListItem := fragmentList;
  2128. WHILE (fragmentListItem # NIL) &
  2129. (fragmentListItem.fragmentID # fragmentID) &
  2130. (~IP.AdrsEqual(fragmentListItem.srcAdr, srcAdr)) &
  2131. ( ~IP.AdrsEqual(fragmentListItem.dstAdr, dstAdr)) DO
  2132. fragmentListItem := fragmentListItem.next;
  2133. END;
  2134. IF fragmentListItem = NIL THEN
  2135. CreateNewFragAndAdd();
  2136. ELSE
  2137. (* insert fragmented packet into right position *)
  2138. INC(fragmentListItem.fragmentCount);
  2139. NEW(newPacketFragmentItem);
  2140. newPacketFragmentItem.buffer := buffer;
  2141. (* calculate fragment offset *)
  2142. buffer.data[buffer.ofs] := 0X;
  2143. newPacketFragmentItem.fragmentOffset := Network.GetNet4(buffer.data, buffer.ofs);
  2144. (* more fragments flag *)
  2145. newPacketFragmentItem.moreFragments := 0 IN SYSTEM.VAL(SET, newPacketFragmentItem.fragmentOffset);
  2146. newPacketFragmentItem.fragmentOffset := 8 * (newPacketFragmentItem.fragmentOffset DIV 8);(* shift 3 right times 8 *)
  2147. buffer.data[buffer.ofs] := CHR(fragmentListItem.nextHeader);
  2148. packetFragmentItem := fragmentListItem.packets;
  2149. LOOP
  2150. IF (packetFragmentItem.next = NIL) & (packetFragmentItem.fragmentOffset <= newPacketFragmentItem.fragmentOffset) THEN
  2151. (* last item *)
  2152. packetFragmentItem.next := newPacketFragmentItem;
  2153. newPacketFragmentItem.next := NIL;
  2154. newPacketFragmentItem.prev := packetFragmentItem;
  2155. EXIT;
  2156. END;
  2157. IF packetFragmentItem.fragmentOffset > newPacketFragmentItem.fragmentOffset THEN
  2158. newPacketFragmentItem.next := packetFragmentItem;
  2159. newPacketFragmentItem.prev := packetFragmentItem.prev;
  2160. packetFragmentItem.prev := newPacketFragmentItem;
  2161. IF newPacketFragmentItem.prev = NIL THEN
  2162. (* new first elem *)
  2163. fragmentListItem.packets := newPacketFragmentItem;
  2164. ELSE
  2165. (* elem in the middle *)
  2166. newPacketFragmentItem.prev.next := newPacketFragmentItem;
  2167. END;
  2168. EXIT;
  2169. END;
  2170. packetFragmentItem := packetFragmentItem.next;
  2171. END;
  2172. (* Reassemble packets *)
  2173. ReassembleFragments(fragmentListItem);
  2174. END;
  2175. END AddToFragmentList;
  2176. (** Reassemble fragmented packets *)
  2177. PROCEDURE ReassembleFragments(fragmentListItem: FragmentList);
  2178. VAR
  2179. packetFragmentItem: PacketFragment;
  2180. currentFragmentOffset: LONGINT;
  2181. lastPacketOk: BOOLEAN;
  2182. lastFragment: PacketFragment;
  2183. BEGIN
  2184. (* Check timer *)
  2185. IF Kernel.Expired(fragmentListItem.startedAt) THEN
  2186. (* send ICMP Time Exceeded -- Fragment Reassembly Time Exceeded message *)
  2187. IF fragmentListItem.packets.fragmentOffset = 0 THEN
  2188. (* only if first fragment was received *)
  2189. sendICMPv6TimeExceeded(SELF, fragmentListItem.packets.buffer, fragmentListItem.srcAdr, ICMPv6FragmentReassemblyExc);
  2190. END;
  2191. DelFragmentListEntry(fragmentListItem, TRUE);
  2192. ELSE
  2193. (* Check if all fragments are present *)
  2194. packetFragmentItem := fragmentListItem.packets;
  2195. currentFragmentOffset := 0;
  2196. lastPacketOk := FALSE;
  2197. WHILE (packetFragmentItem # NIL) & (currentFragmentOffset = packetFragmentItem.fragmentOffset) DO
  2198. IF packetFragmentItem.next = NIL THEN
  2199. (* last packet: no more fragments *)
  2200. lastPacketOk := ~packetFragmentItem.moreFragments;
  2201. lastFragment := packetFragmentItem;
  2202. END;
  2203. INC(currentFragmentOffset, packetFragmentItem.buffer.len - FragmentHdrLen);
  2204. packetFragmentItem := packetFragmentItem.next;
  2205. END;
  2206. IF (packetFragmentItem = NIL) & lastPacketOk THEN
  2207. (* Reassemble packet *)
  2208. (* connect packets through nextFragment *)
  2209. packetFragmentItem := fragmentListItem.packets;
  2210. WHILE packetFragmentItem.next # NIL DO
  2211. packetFragmentItem.buffer.nextFragment := packetFragmentItem.next.buffer;
  2212. (* adjust offset *)
  2213. INC(packetFragmentItem.next.buffer.ofs, FragmentHdrLen);
  2214. DEC(packetFragmentItem.next.buffer.len, FragmentHdrLen);
  2215. packetFragmentItem := packetFragmentItem.next;
  2216. END;
  2217. IPInput(dev, EtherTypeIP, fragmentListItem.packets.buffer);
  2218. DelFragmentListEntry(fragmentListItem, FALSE);
  2219. END;
  2220. END;
  2221. END ReassembleFragments;
  2222. (** Delete a entry in the fragmentation list *)
  2223. PROCEDURE DelFragmentListEntry(fragmentListEntry: FragmentList; returnBuffers: BOOLEAN);
  2224. VAR
  2225. fragmentListFind: FragmentList;
  2226. BEGIN
  2227. (* discard the fragmented packets *)
  2228. IF returnBuffers THEN
  2229. Network.ReturnBuffer(fragmentListEntry.packets.buffer);
  2230. END;
  2231. (* delete fragment list entry *)
  2232. IF fragmentList = fragmentListEntry THEN
  2233. (* delete first entry in fragment list *)
  2234. fragmentList := fragmentListEntry.next;
  2235. ELSE
  2236. (* delete entry in the middle or at the end *)
  2237. fragmentListFind := fragmentList;
  2238. WHILE (fragmentListFind.next # NIL) & (fragmentListFind.next # fragmentListEntry) DO
  2239. fragmentListFind := fragmentListFind.next;
  2240. END;
  2241. fragmentListFind.next := fragmentListFind.next.next;
  2242. END;
  2243. END DelFragmentListEntry;
  2244. (** Writes the configuration of this interface *)
  2245. PROCEDURE OutInterface*;
  2246. VAR i: LONGINT;
  2247. str : ARRAY 32 OF CHAR;
  2248. BEGIN
  2249. IF closed THEN
  2250. KernelLog.Enter;
  2251. KernelLog.String("IP.OutInterface: Error: Interface already closed!"); KernelLog.Ln;
  2252. KernelLog.Exit;
  2253. ELSE
  2254. KernelLog.Enter; KernelLog.Ln;
  2255. KernelLog.String("=== Interface ==="); KernelLog.Ln;
  2256. KernelLog.String("Interface name: "); KernelLog.String(name); KernelLog.Ln;
  2257. KernelLog.String("Attached device: "); KernelLog.String(dev.name);
  2258. IF dev.Linked() = Network.LinkLinked THEN
  2259. KernelLog.String(" (LinkLinked)"); KernelLog.Ln;
  2260. ELSIF dev.Linked() = Network.LinkNotLinked THEN
  2261. KernelLog.String(" (LinkNotLinked)"); KernelLog.Ln;
  2262. ELSE
  2263. KernelLog.String(" (LinkUnknown)"); KernelLog.Ln;
  2264. END;
  2265. Network.LinkAdrToStr(dev.local, 8, str);
  2266. KernelLog.String("MAC address: "); KernelLog.String(str); KernelLog.Ln;
  2267. KernelLog.String("Local address: "); IP.OutAdr(localAdr); KernelLog.Ln;
  2268. routers.OutRouters;
  2269. KernelLog.String("Prefix: "); IP.OutAdr(maskAdr); KernelLog.Ln;
  2270. IF DNScount > 0 THEN
  2271. FOR i:= 0 TO DNScount-1 DO
  2272. KernelLog.String("DNS server: "); IP.OutAdr(DNS[i]); KernelLog.Ln;
  2273. END;
  2274. ELSE
  2275. KernelLog.String("DNS server: none"); KernelLog.Ln;
  2276. END;
  2277. KernelLog.Exit;
  2278. END;
  2279. END OutInterface;
  2280. BEGIN {ACTIVE}
  2281. (* init timers *)
  2282. NEW(shortTimer);
  2283. Kernel.SetTimer(longTimer, LongTimerTimeout);
  2284. Kernel.SetTimer(duplicateTimer, LongTimerTimeout);
  2285. (* Init solicited multicast MAC address *)
  2286. linkMulticastSolicited[0] := 33X;
  2287. linkMulticastSolicited[1] := 33X;
  2288. linkMulticastSolicited[2] := 0FFX;
  2289. linkMulticastSolicited[3] := dev.local[3];
  2290. linkMulticastSolicited[4] := dev.local[4];
  2291. linkMulticastSolicited[5] := dev.local[5];
  2292. linkMulticastSolicited[6] := 0X;
  2293. linkMulticastSolicited[7] := 0X;
  2294. linkMTU := 1500; (* Default value for link MTU (assuming I'm on ethernet) *)
  2295. curHopLimit := 255; (* Default hop limit *)
  2296. REPEAT
  2297. shortTimer.Sleep(ShortTimerTimeout);
  2298. IF Kernel.Expired(duplicateTimer) THEN
  2299. IF autoconfigState = TentativeInterface THEN
  2300. autoconfigState := PreferredInterface;
  2301. END;
  2302. END;
  2303. (* Search fragment list for lost packets *)
  2304. fragmentListItem := fragmentList;
  2305. WHILE fragmentListItem # NIL DO
  2306. (* Check timer *)
  2307. IF Kernel.Expired(fragmentListItem.startedAt) THEN
  2308. (* send ICMP Time Exceeded -- Fragment Reassembly Time Exceeded message *)
  2309. IF fragmentListItem.packets.fragmentOffset = 0 THEN
  2310. (* only if first fragment was received *)
  2311. sendICMPv6TimeExceeded(SELF, fragmentListItem.packets.buffer, fragmentListItem.srcAdr, ICMPv6FragmentReassemblyExc);
  2312. END;
  2313. DelFragmentListEntry(fragmentListItem, TRUE);
  2314. END;
  2315. fragmentListItem := fragmentListItem.next;
  2316. END;
  2317. IF createStatelessInterface THEN
  2318. (* Do stateless autoconfiguration *)
  2319. IF sendRouterSolicitation # NIL THEN
  2320. IF routerSolCount < 4 THEN
  2321. RouterSolicitation;
  2322. ELSE
  2323. (* initiate DHCPv6 *)
  2324. createStatelessInterface := FALSE;
  2325. createStatefulInterface := TRUE;
  2326. (* (* create new interface on which asks a DHCPv6 *)
  2327. Strings.Concat(V6DHCPIntName , dev.name, intName);
  2328. NEW (intv6, intName, dev, res);
  2329. IF res = IP.Ok THEN
  2330. (* configure DHCP interface *)
  2331. END;
  2332. *) createStatefulInterface := FALSE;
  2333. END;
  2334. END;
  2335. END;
  2336. (* Interface acts as a router *)
  2337. IF isRouter THEN
  2338. IF nextRtrAdvertisement = 0 THEN
  2339. (* send a unsolicited router advertisement *)
  2340. sendRouterAdvertisement(SELF, linkLocalMulticastNodeAdr, linkMulticastAllNodesAdr, routerConfig);
  2341. (* When to send next unsolicited router advertisement *)
  2342. nextRtrAdvertisement := RandomNumber(MaxRtrAdvInterval - MinRtrAdvInterval);
  2343. INC(nextRtrAdvertisement, MinRtrAdvInterval);
  2344. nextRtrAdvertisement := nextRtrAdvertisement DIV ShortTimerTimeout;
  2345. ELSE
  2346. DEC(nextRtrAdvertisement);
  2347. END;
  2348. END;
  2349. IF Kernel.Expired(longTimer) THEN
  2350. IF autoconfigurated THEN
  2351. (* If no stateful or stateless interfaces exist, try to create them *)
  2352. int := IP.interfaces;
  2353. createStatefulInterface := TRUE;
  2354. createStatelessInterface := TRUE;
  2355. WHILE int # NIL DO
  2356. IF Strings.Pos(V6RouterIntName, int.name) = 0 THEN
  2357. createStatelessInterface := FALSE;
  2358. END;
  2359. IF Strings.Pos(V6DHCPIntName, int.name) = 0 THEN
  2360. createStatefulInterface := FALSE;
  2361. END;
  2362. int := int.next;
  2363. END;
  2364. END;
  2365. Kernel.SetTimer(longTimer, LongTimerTimeout);
  2366. (* Check caches for old entries and delete them *)
  2367. destCache.Clear(); (* Destination cache *)
  2368. prefixes.ClearExpired(); (* Clear expired prefixes *)
  2369. routers.ClearExpired(); (* Clear expired default routers *)
  2370. localAdrCache.ClearExpired(); (* Clear expored local addresses *)
  2371. RouterSolicitation();
  2372. END;
  2373. UNTIL closed;
  2374. END Interface;
  2375. TYPE
  2376. SendNeighborSolicitation* = PROCEDURE {DELEGATE} (interface: Interface; linkAdr: Network.LinkAdr; destAdr: IP.Adr; multicast: BOOLEAN);
  2377. SendNeighborAdvertisement* = PROCEDURE {DELEGATE} (interface: Interface; linkDst: Network.LinkAdr; destAdr: IP.Adr; solicited: BOOLEAN);
  2378. SendRouterSolicitation* = PROCEDURE {DELEGATE} (interface: Interface);
  2379. SendRouterAdvertisement* = PROCEDURE {DELEGATE} (interface: Interface; dstAdr: IP.Adr; dstLinkAdr: Network.LinkAdr; routerConfig:RouterConfig);
  2380. SendICMPv6TimeExceeded* = PROCEDURE {DELEGATE} (interface: Interface; discardedPacket: Network.Buffer; srcAdr: IP.Adr; code: LONGINT);
  2381. SendICMPv6ParamProb* = PROCEDURE {DELEGATE} (interface: Interface; discardedPacket: Network.Buffer; srcAdr: IP.Adr; probPointer, code: LONGINT);
  2382. ICMPLinkLayerAdrOption* = PROCEDURE {DELEGATE} (VAR buffer: Network.Buffer; VAR linkAdr: Network.LinkAdr);
  2383. ICMPPrefixInfoOption* = PROCEDURE {DELEGATE} (VAR buffer: Network.Buffer;
  2384. VAR onLink, autonomous, routerAddress, sitePrefix: BOOLEAN;
  2385. VAR validLifetime, preferredLifetime, sitePrefixLength: LONGINT;
  2386. VAR localPrefix: IP.Adr);
  2387. ICMPRedirectHdrOption* = PROCEDURE {DELEGATE} (VAR buffer: Network.Buffer);
  2388. ICMPMTUOption* = PROCEDURE {DELEGATE} (VAR buffer: Network.Buffer; VAR MTU: LONGINT);
  2389. ICMPAdvIntervalOption* = PROCEDURE {DELEGATE} (VAR buffer: Network.Buffer);
  2390. ICMPHomeAgentInfoOption* = PROCEDURE {DELEGATE} (VAR buffer: Network.Buffer);
  2391. ICMPRouteInfoOption* = PROCEDURE {DELEGATE} (VAR buffer: Network.Buffer);
  2392. VAR
  2393. (* Delegates *)
  2394. sendNeighborSolicitation*: SendNeighborSolicitation;
  2395. sendNeighborAdvertisement*: SendNeighborAdvertisement;
  2396. sendRouterSolicitation*: SendRouterSolicitation;
  2397. sendRouterAdvertisement*: SendRouterAdvertisement;
  2398. sendICMPv6TimeExceeded*: SendICMPv6TimeExceeded;
  2399. sendICMPv6ParamProb*: SendICMPv6ParamProb;
  2400. icmpLinkLayerAdrOption*: ICMPLinkLayerAdrOption;
  2401. icmpPrefixInfoOption*: ICMPPrefixInfoOption;
  2402. icmpRedirectHdrOption*: ICMPRedirectHdrOption;
  2403. icmpMTUOption*: ICMPMTUOption;
  2404. icmpAdvIntervalOption*: ICMPAdvIntervalOption;
  2405. icmpHomeAgentInfoOption*: ICMPHomeAgentInfoOption;
  2406. icmpRouteInfoOption*: ICMPRouteInfoOption;
  2407. (* Link-Local prefix *)
  2408. linkLocalPrefix: IP.Adr;
  2409. (* Multicast addresses *)
  2410. nodeLocalMulticastNodeAdr: IP.Adr;
  2411. nodeLocalMulticastRouterAdr: IP.Adr;
  2412. linkLocalMulticastNodeAdr*: IP.Adr;
  2413. linkLocalMulticastRouterAdr*: IP.Adr;
  2414. (* Ethernet multicast addresses *)
  2415. linkMulticastAllNodesAdr*: Network.LinkAdr;
  2416. linkMulticastAllRoutersAdr*: Network.LinkAdr;
  2417. (* list of devices *)
  2418. devList: DeviceList;
  2419. (* local address cache *)
  2420. localAdrCache: LocalAdrCache;
  2421. (* fragmentation *)
  2422. fragmentationID: LONGINT;
  2423. fragmentListItem: FragmentList;
  2424. (* random generator *)
  2425. randomZ: LONGINT;
  2426. (* Checks if a part of two addresses is equal *)
  2427. PROCEDURE AdrsPartEqual(adr1, adr2: IP.Adr; from, to: LONGINT): BOOLEAN;
  2428. VAR
  2429. i: LONGINT;
  2430. isPartEqual: BOOLEAN;
  2431. BEGIN
  2432. IF DEBUG THEN
  2433. ASSERT((from >= 0) & (from <= 15));
  2434. ASSERT((from >= 0) & (from <= 15));
  2435. ASSERT(from <= to);
  2436. END;
  2437. isPartEqual := TRUE;
  2438. FOR i := from TO to DO
  2439. IF (adr1.ipv6Adr[i] # adr2.ipv6Adr[i]) THEN
  2440. isPartEqual := FALSE;
  2441. END;
  2442. END;
  2443. RETURN isPartEqual;
  2444. END AdrsPartEqual;
  2445. (** Checks if a buffer contains a valid IPv6 packet; this check is performed for Network *)
  2446. PROCEDURE IsPacketValid(VAR buffer: Network.Buffer): BOOLEAN;
  2447. VAR
  2448. isValid: BOOLEAN;
  2449. BEGIN
  2450. isValid := FALSE;
  2451. Machine.AtomicInc(IP.NIPRcvTotal);
  2452. IF buffer.len >= MinIPHdrLen THEN
  2453. IF LSH(ORD(buffer.data[buffer.ofs]), -4) = IP.IPv6 THEN
  2454. isValid := TRUE;
  2455. ELSE
  2456. Machine.AtomicInc(IP.NIPBadVersion)
  2457. END
  2458. ELSE
  2459. Machine.AtomicInc(IP.NIPTooSmall)
  2460. END;
  2461. RETURN isValid;
  2462. END IsPacketValid;
  2463. (** Performs a check for Network if a packet is for a single interface *)
  2464. PROCEDURE IsPacketForSingleInt(buffer: Network.Buffer): BOOLEAN;
  2465. BEGIN
  2466. (* All IPv6 packets are delivered to only one interface *)
  2467. RETURN TRUE;
  2468. END IsPacketForSingleInt;
  2469. (* Check if adr is a link-local multicast adr: linkLocalMulticastAdr *)
  2470. PROCEDURE IsLinkLocalMulticastAdr (adr: IP.Adr): BOOLEAN;
  2471. VAR
  2472. isLinkLocal: BOOLEAN;
  2473. BEGIN
  2474. isLinkLocal := FALSE;
  2475. IF IP.AdrsEqual(adr, linkLocalMulticastNodeAdr) THEN
  2476. isLinkLocal := TRUE;
  2477. END;
  2478. RETURN isLinkLocal;
  2479. END IsLinkLocalMulticastAdr;
  2480. (* Check if adr is a link-local adr: FE80::/64 prefix *)
  2481. PROCEDURE IsLinkLocalAdr (adr: IP.Adr): BOOLEAN;
  2482. VAR
  2483. isLinkLocal: BOOLEAN;
  2484. BEGIN
  2485. isLinkLocal := FALSE;
  2486. IF IP.MatchPrefix(adr, linkLocalPrefix) THEN
  2487. isLinkLocal := TRUE;
  2488. END;
  2489. RETURN isLinkLocal;
  2490. END IsLinkLocalAdr;
  2491. (** Delivers the right interface for a specific destination *)
  2492. PROCEDURE V6InterfaceByDstIP(dstAdr: IP.Adr): IP.Interface;
  2493. VAR
  2494. retInt: Interface;
  2495. devListItem: DeviceList;
  2496. linkLocalInt: Interface;
  2497. neighborCacheItem: NeighborCacheEntry;
  2498. sleepTimer: Kernel.Timer;
  2499. sleepCounter: LONGINT; (* 5 times 100 ms *)
  2500. normalCase: BOOLEAN;
  2501. intItem: IP.Interface;
  2502. gw: IP.Interface;
  2503. linkDst: Network.LinkAdr;
  2504. devCount: LONGINT;
  2505. BEGIN
  2506. (* Problem: When two network devices are available it is impossible to know on
  2507. which device a link-local address is. Therefore neigbor solicitations are sent on
  2508. both devices. The procedure has then to wait until the neighbor advertisement
  2509. arrives. *)
  2510. retInt := NIL;
  2511. devListItem := devList;
  2512. NEW(sleepTimer);
  2513. sleepCounter := 0;
  2514. normalCase := TRUE;
  2515. (* Look if an address is a link-local address *)
  2516. IF IsLinkLocalAdr(dstAdr) THEN
  2517. (* Are there multiple devices present *)
  2518. devCount := 0;
  2519. WHILE devListItem # NIL DO
  2520. IF devListItem.device.name # "Loopback" THEN
  2521. INC(devCount);
  2522. END;
  2523. devListItem := devListItem.next;
  2524. END;
  2525. IF devCount > 1 THEN
  2526. normalCase := FALSE;
  2527. retInt := localAdrCache.GetInterface(dstAdr);
  2528. WHILE (retInt = NIL) & (sleepCounter < 5) DO
  2529. (* search in neighbor cache *)
  2530. devListItem := devList;
  2531. WHILE devListItem # NIL DO
  2532. linkLocalInt := devListItem.linkLocalInterface;
  2533. IF linkLocalInt # NIL THEN
  2534. (* search neighbor cache *)
  2535. neighborCacheItem := linkLocalInt.neighborCache.Get(dstAdr);
  2536. IF neighborCacheItem # NIL THEN
  2537. retInt := linkLocalInt;
  2538. END;
  2539. (* look if the dstAdr is equal a local address *)
  2540. IF IP.AdrsEqual(dstAdr, linkLocalInt.localAdr) THEN
  2541. retInt := linkLocalInt;
  2542. END;
  2543. END;
  2544. devListItem := devListItem.next;
  2545. END;
  2546. IF retInt = NIL THEN
  2547. (* send neigbor solicitations on all devices *)
  2548. devListItem := devList;
  2549. WHILE devListItem # NIL DO
  2550. IF (devListItem.linkLocalInterface # NIL) &
  2551. (devListItem.linkLocalInterface IS Interface) &
  2552. (devListItem.linkLocalInterface.dev.Linked() # Network.LinkNotLinked) THEN
  2553. (* link and IP destination addresses are the solicited node addresses *)
  2554. linkDst := linkMulticastAllNodesAdr;
  2555. linkDst[2] := 0FFX;
  2556. linkDst[3] := dstAdr.ipv6Adr[13];
  2557. linkDst[4] := dstAdr.ipv6Adr[14];
  2558. linkDst[5] := dstAdr.ipv6Adr[15];
  2559. (* Send a Neighbor Solicitation message *)
  2560. sendNeighborSolicitation(devListItem.linkLocalInterface(Interface), linkDst, dstAdr, TRUE);
  2561. END;
  2562. devListItem := devListItem.next;
  2563. END;
  2564. END;
  2565. sleepTimer.Sleep(200);
  2566. INC(sleepCounter);
  2567. END;
  2568. IF retInt # NIL THEN
  2569. (* store interface in local address cache *)
  2570. localAdrCache.Add(dstAdr, retInt);
  2571. END;
  2572. END;
  2573. END;
  2574. (* Normal case *)
  2575. IF (retInt = NIL) & normalCase THEN
  2576. gw := NIL;
  2577. intItem := IP.interfaces;
  2578. LOOP
  2579. IF intItem = NIL THEN
  2580. EXIT
  2581. END;
  2582. IF (intItem.protocol = IP.IPv6) & (~IP.IsNilAdr(intItem.localAdr)) & (intItem.dev.Linked() # Network.LinkNotLinked) THEN
  2583. IF IP.MatchPrefix(dstAdr, intItem.maskAdr) THEN
  2584. EXIT;
  2585. ELSIF (gw = NIL) & (~IP.IsNilAdr(intItem.maskAdr)) THEN
  2586. gw := intItem;
  2587. END;
  2588. END;
  2589. intItem := intItem.next;
  2590. END;
  2591. IF intItem # NIL THEN
  2592. retInt := intItem(Interface);
  2593. ELSE
  2594. retInt := gw(Interface);
  2595. END;
  2596. END;
  2597. RETURN retInt;
  2598. END V6InterfaceByDstIP;
  2599. (*
  2600. (** Deliver the link-local interface of a certain device *)
  2601. PROCEDURE GetLinkLocalInterface(dev: Network.LinkDevice): Interface;
  2602. VAR
  2603. devListItem: DeviceList;
  2604. BEGIN
  2605. devListItem := devList;
  2606. WHILE (devListItem # NIL) & (devListItem.device # dev) DO
  2607. devListItem := devListItem.next;
  2608. END;
  2609. IF devListItem # NIL THEN
  2610. RETURN devListItem.linkLocalInterface;
  2611. ELSE
  2612. RETURN NIL;
  2613. END;
  2614. END GetLinkLocalInterface;
  2615. *)
  2616. (** Deliver a ID for packet fragmentation *)
  2617. PROCEDURE GetFragmentID(): LONGINT;
  2618. BEGIN {EXCLUSIVE}
  2619. INC(fragmentationID);
  2620. RETURN fragmentationID;
  2621. END GetFragmentID;
  2622. (** Parses the routing header extension *)
  2623. PROCEDURE RoutingExtHeader(int: IP.Interface; type: LONGINT; srcAdr, dstAdr: IP.Adr; buffer: Network.Buffer);
  2624. VAR
  2625. segmentsLeft: LONGINT;
  2626. hdrExtLen: LONGINT;
  2627. receiver: IP.Receiver;
  2628. nextHeader: LONGINT;
  2629. nbrOfAdrs: LONGINT;
  2630. ithAddress: LONGINT;
  2631. tempAdr: ARRAY 16 OF CHAR;
  2632. intv6: Interface;
  2633. BEGIN
  2634. ASSERT (int IS Interface);
  2635. intv6 := int(Interface);
  2636. (* read values *)
  2637. nextHeader := ORD(buffer.data[buffer.ofs]);
  2638. hdrExtLen := ORD(buffer.data[buffer.ofs + 1]);
  2639. segmentsLeft := ORD(buffer.data[buffer.ofs + 3]);
  2640. IF IP.AdrsEqual(dstAdr, int.localAdr) THEN
  2641. IF segmentsLeft = 0 THEN
  2642. (* process next header *)
  2643. receiver := IP.receivers[nextHeader];
  2644. IF receiver # NIL THEN
  2645. (* do receiver upcall *)
  2646. INC(buffer.ofs, hdrExtLen * 8 + RoutingHdrLen);
  2647. DEC(buffer.len, hdrExtLen * 8 + RoutingHdrLen);
  2648. receiver(int, nextHeader, srcAdr, dstAdr, buffer);
  2649. (* Exit here w/o returning buffer because it is passed to a receiver *)
  2650. RETURN;
  2651. ELSE
  2652. Network.ReturnBuffer(buffer);
  2653. END;
  2654. ELSIF IP.IPForwarding THEN
  2655. IF hdrExtLen MOD 2 = 1 THEN
  2656. (* odd header extension length *)
  2657. sendICMPv6ParamProb(intv6, buffer, srcAdr, MinIPHdrLen + 2, 0);
  2658. Network.ReturnBuffer(buffer);
  2659. ELSE
  2660. (* segments left not correct *)
  2661. nbrOfAdrs := hdrExtLen DIV 2;
  2662. IF segmentsLeft > nbrOfAdrs THEN
  2663. sendICMPv6ParamProb(intv6, buffer, srcAdr, MinIPHdrLen + 4, 0);
  2664. Network.ReturnBuffer(buffer);
  2665. ELSE
  2666. DEC(segmentsLeft);
  2667. buffer.data[buffer.ofs + 4] := CHR(segmentsLeft);
  2668. ithAddress := nbrOfAdrs - segmentsLeft;
  2669. (* swap dest adr and ith address *)
  2670. Network.Copy(dstAdr.ipv6Adr, tempAdr, 0, 0, 16);
  2671. Network.Copy(buffer.data, dstAdr.ipv6Adr, 8 + (ithAddress - 1 * 16), 0, 16);
  2672. Network.Copy(tempAdr, buffer.data, 0, (ithAddress - 1 * 16), 16);
  2673. (* For forwarding set offset to IP level *)
  2674. INC(buffer.len, buffer.ofs);
  2675. buffer.ofs := 0;
  2676. END;
  2677. END;
  2678. ELSE
  2679. Network.ReturnBuffer(buffer);
  2680. END;
  2681. END;
  2682. END RoutingExtHeader;
  2683. (** Parses the hop-by-hop header extension, which is ignored up to now *)
  2684. PROCEDURE HopByHopExtHeader(int: IP.Interface; type: LONGINT; srcAdr, dstAdr: IP.Adr; buffer: Network.Buffer);
  2685. VAR
  2686. receiver: IP.Receiver;
  2687. nextHeader: LONGINT;
  2688. hdrExtLen: LONGINT;
  2689. intv6: Interface;
  2690. BEGIN
  2691. ASSERT(int IS Interface);
  2692. intv6 := int(Interface);
  2693. nextHeader := ORD(buffer.data[buffer.ofs]);
  2694. hdrExtLen := ORD(buffer.data[buffer.ofs + 1]);
  2695. (* process next header *)
  2696. receiver := IP.receivers[nextHeader];
  2697. IF receiver # NIL THEN
  2698. (* do receiver upcall *)
  2699. INC(buffer.ofs, hdrExtLen * 8 + HopByHopHdrLen);
  2700. DEC(buffer.len, hdrExtLen * 8 + HopByHopHdrLen);
  2701. receiver(intv6, nextHeader, srcAdr, dstAdr, buffer);
  2702. (* Exit here w/o returning buffer because it is passed to a receiver *)
  2703. RETURN;
  2704. ELSE
  2705. Network.ReturnBuffer(buffer);
  2706. END;
  2707. END HopByHopExtHeader;
  2708. (** Parses the destination header extension, which is ignored up to now *)
  2709. PROCEDURE DestinationExtHeader(int: IP.Interface; type: LONGINT; srcAdr, dstAdr: IP.Adr; buffer: Network.Buffer);
  2710. VAR
  2711. receiver: IP.Receiver;
  2712. nextHeader: LONGINT;
  2713. hdrExtLen: LONGINT;
  2714. intv6: Interface;
  2715. BEGIN
  2716. ASSERT(int IS Interface);
  2717. intv6 := int(Interface);
  2718. nextHeader := ORD(buffer.data[buffer.ofs]);
  2719. hdrExtLen := ORD(buffer.data[buffer.ofs + 1]);
  2720. (* process next header *)
  2721. receiver := IP.receivers[nextHeader];
  2722. IF receiver # NIL THEN
  2723. (* do receiver upcall *)
  2724. INC(buffer.ofs, hdrExtLen * 8 + DestinationHdrLen);
  2725. DEC(buffer.len, hdrExtLen * 8 + DestinationHdrLen);
  2726. receiver(intv6, nextHeader, srcAdr, dstAdr, buffer);
  2727. (* Exit here w/o returning buffer because it is passed to a receiver *)
  2728. RETURN;
  2729. ELSE
  2730. Network.ReturnBuffer(buffer);
  2731. END;
  2732. END DestinationExtHeader;
  2733. (** Deliver a random number between 0 and limit *)
  2734. PROCEDURE RandomNumber(limit: LONGINT): LONGINT;
  2735. CONST
  2736. a = 16807;
  2737. m = 2147483647;
  2738. q = m DIV a;
  2739. r = m MOD a;
  2740. VAR
  2741. g: LONGINT;
  2742. BEGIN
  2743. g := a*(randomZ MOD q) - r*(randomZ DIV q);
  2744. IF g > 0 THEN randomZ := g ELSE randomZ := g + m END;
  2745. RETURN ENTIER((randomZ*1.0D0/m) * limit); (* must compute this in double precision, e.g. (m-1)/m *)
  2746. END RandomNumber;
  2747. PROCEDURE Cleanup;
  2748. BEGIN
  2749. (* Remove all interfaces *)
  2750. WHILE IP.interfaces # NIL DO
  2751. IP.interfaces.Close();
  2752. END;
  2753. END Cleanup;
  2754. BEGIN
  2755. (* link-local prefix *)
  2756. linkLocalPrefix := IP.NilAdr;
  2757. linkLocalPrefix.usedProtocol := IP.IPv6;
  2758. linkLocalPrefix.ipv6Adr[0] := 0FEX;
  2759. linkLocalPrefix.ipv6Adr[1] := 80X;
  2760. linkLocalPrefix.data := 64;
  2761. (* init multicast addresses *)
  2762. nodeLocalMulticastNodeAdr := IP.NilAdr;
  2763. nodeLocalMulticastRouterAdr := IP.NilAdr;
  2764. linkLocalMulticastNodeAdr := IP.NilAdr;
  2765. linkLocalMulticastRouterAdr := IP.NilAdr;
  2766. nodeLocalMulticastNodeAdr.usedProtocol := IP.IPv6;
  2767. nodeLocalMulticastRouterAdr.usedProtocol := IP.IPv6;
  2768. linkLocalMulticastNodeAdr.usedProtocol := IP.IPv6;
  2769. linkLocalMulticastRouterAdr.usedProtocol := IP.IPv6;
  2770. nodeLocalMulticastNodeAdr.ipv6Adr[0] := 0FFX;
  2771. nodeLocalMulticastRouterAdr.ipv6Adr[0] := 0FFX;
  2772. linkLocalMulticastNodeAdr.ipv6Adr[0] := 0FFX;
  2773. linkLocalMulticastRouterAdr.ipv6Adr[0] := 0FFX;
  2774. nodeLocalMulticastNodeAdr.ipv6Adr[1] := 1X;
  2775. nodeLocalMulticastRouterAdr.ipv6Adr[1] :=1X;
  2776. linkLocalMulticastNodeAdr.ipv6Adr[1] := 2X;
  2777. linkLocalMulticastRouterAdr.ipv6Adr[1] := 2X;
  2778. nodeLocalMulticastNodeAdr.ipv6Adr[15] := 1X;
  2779. nodeLocalMulticastRouterAdr.ipv6Adr[15] :=2X;
  2780. linkLocalMulticastNodeAdr.ipv6Adr[15] := 1X;
  2781. linkLocalMulticastRouterAdr.ipv6Adr[15] := 2X;
  2782. (* Init Ethernet Multicast addresses *)
  2783. linkMulticastAllNodesAdr[0] := 33X;
  2784. linkMulticastAllNodesAdr[1] := 33X;
  2785. linkMulticastAllNodesAdr[2] := 0X;
  2786. linkMulticastAllNodesAdr[3] := 0X;
  2787. linkMulticastAllNodesAdr[4] := 0X;
  2788. linkMulticastAllNodesAdr[5] := 1X;
  2789. linkMulticastAllNodesAdr[6] := 0X;
  2790. linkMulticastAllNodesAdr[7] := 0X;
  2791. linkMulticastAllRoutersAdr[0] := 33X;
  2792. linkMulticastAllRoutersAdr[1] := 33X;
  2793. linkMulticastAllRoutersAdr[2] := 0X;
  2794. linkMulticastAllRoutersAdr[3] := 0X;
  2795. linkMulticastAllRoutersAdr[4] := 0X;
  2796. linkMulticastAllRoutersAdr[5] := 2X;
  2797. linkMulticastAllRoutersAdr[6] := 0X;
  2798. linkMulticastAllRoutersAdr[7] := 0X;
  2799. (* random generator initialization *)
  2800. randomZ := Kernel.GetTicks();
  2801. devList := NIL;
  2802. NEW(localAdrCache);
  2803. IP.v6InterfaceByDstIP := V6InterfaceByDstIP;
  2804. IP.InstallReceiver(IPv6RoutingHdrType, RoutingExtHeader);
  2805. IP.InstallReceiver(IPv6HopByHopHdrType, HopByHopExtHeader);
  2806. IP.InstallReceiver(IPv6DestinationHdrType, DestinationExtHeader);
  2807. Modules.InstallTermHandler(Cleanup);
  2808. END IPv6.
  2809. Free:
  2810. System.Free TraceRoute VNC Ping WMFTPClient FTPClient WebFTPServer TCPServices TLS InitNetwork Ping DHCP TCP DNS UDP ICMP IPv4 IPv6 IP~
  2811. Start:
  2812. InitNetwork.Init
  2813. Compile:
  2814. PC.Compile \s IP.Mod IPv4.Mod IPv6.Mod ICMP.Mod UDP.Mod DNS.Mod TCP.Mod DHCP.Mod InitNetwork.Mod WebFTPServer.Mod FTPClient.Mod WMFTPClient.Mod Ping.Mod VNC.Mod TraceRoute.Mod~
  2815. History:
  2816. 02.05.2005 eb Created.
  2817. 07.2005 eb Cache added