ARM.Network.Mod 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
  2. MODULE Network; (** AUTHOR "pjm, mvt"; PURPOSE "Abstract network device driver"; *)
  3. (* Ported to ARM by Timothée Martiel, 2014. *)
  4. IMPORT SYSTEM, Machine, KernelLog, Plugins, Kernel, Objects, Modules;
  5. CONST
  6. MaxLinkAdrSize* = 8; (** largest link address size in bytes *)
  7. MaxPacketSize* = 1600; (** maximum amount of data bytes in a link layer frame *)
  8. MaxNofBuffers = 10000; (* maximum number of buffers allowed within the whole net system *)
  9. (** Constants for LinkDevice.type *)
  10. TypePointToPoint* = 0;
  11. TypeEthernet* = 1;
  12. (** Constants for LinkDevice.Linked *)
  13. LinkNotLinked* = 0;
  14. LinkLinked* = 1;
  15. LinkUnknown* = 2;
  16. (** Constants for LinkDevice.calcChecksum and Buffer.calcChecksum *)
  17. ChecksumIP* = 0;
  18. ChecksumUDP* = 1;
  19. ChecksumTCP* = 2;
  20. (* Number of loopback packets that can be sent per 1-2 ms.
  21. This protects the upcall buffers from running out. *)
  22. MaxLoopbackPacketsPerMS = 500;
  23. TYPE
  24. LinkAdr* = ARRAY MaxLinkAdrSize OF CHAR; (** link layer address *)
  25. (** Buffer for passing network packets to upper layer protocols *)
  26. Buffer* = POINTER TO RECORD
  27. data*:ARRAY MaxPacketSize OF CHAR;
  28. ofs*: LONGINT; (** valid data starts at this offset *)
  29. len*: LONGINT; (** length of valid data *)
  30. l3ofs*: LONGINT; (** the layer 3 header starts at this offset *)
  31. l4ofs*: LONGINT; (** the layer 4 header starts at this offset *)
  32. src*: LinkAdr; (** link layer source address *)
  33. calcChecksum*: SET; (** these checksums are already verified by the device *)
  34. int*: LONGINT; (** used in TCP, UDP and ICMP, but can be used by any upper layer protocol *)
  35. set*: SET; (** used in TCP, but can be used by any upper layer protocol *)
  36. next*, prev*: Buffer; (** for queueing the buffer *)
  37. nextFragment*: Buffer; (** next buffer of a fragmented packet *)
  38. END;
  39. (* List of type i.e. 800X for IP *)
  40. TypeList = POINTER TO RECORD
  41. next: TypeList;
  42. type: LONGINT;
  43. recList: ReceiverList;
  44. END;
  45. ReceiverList = POINTER TO RECORD
  46. next: ReceiverList;
  47. owner: ANY;
  48. receiver: Receiver;
  49. isPacketValid: IsPacketValid;
  50. isPacketForSingleRec: IsPacketForSingleRec;
  51. isPacketAccepted: IsPacketAccepted;
  52. isForwardingOn: BOOLEAN;
  53. END;
  54. SendSnifferList = POINTER TO RECORD
  55. next: SendSnifferList;
  56. sniffer: SendSniffer;
  57. END;
  58. RecvSnifferList = POINTER TO RECORD
  59. next: RecvSnifferList;
  60. sniffer: ReceiveSniffer;
  61. END;
  62. (** Abstract implementation of a generic network driver object *)
  63. LinkDevice* = OBJECT (Plugins.Plugin)
  64. VAR
  65. (** pubic device properties *)
  66. type-: LONGINT; (** LinkType: TypePointToPoint, TypeEthernet *)
  67. local*: LinkAdr; (** local link address *)
  68. broadcast*: LinkAdr; (** link address for sending a broadcast *)
  69. mtu-: LONGINT; (** largest packet size in bytes *)
  70. adrSize*: LONGINT; (** link address size in bytes *)
  71. sendCount*, recvCount-: HUGEINT; (** number of bytes sent and received *)
  72. calcChecksum*: SET; (** these checksums are calculated by the device hardware when sending. *)
  73. typeList: TypeList; (* List of types i.e. 0800X for IP, holds all receiver for a certain type *)
  74. recList: ReceiverList; (* receiver list *)
  75. sendSnifferList: SendSnifferList; (* list for send sniffers *)
  76. recvSnifferList: RecvSnifferList; (* list for receive sniffers *)
  77. typeItem: TypeList; (* temporary item in type list *)
  78. recItem: ReceiverList; (* temporary item in receiver list *)
  79. sniffer: RecvSnifferList; (* temporary item in receive sniffer list *)
  80. discard: BOOLEAN; (* shall the current packet be discarded? (used in active body) *)
  81. finalized: BOOLEAN; (* is object already finalized or currently finalizing? *)
  82. (* queue for buffers waiting for upcall *)
  83. upBufFirst, upBufLast: Buffer;
  84. buf: Buffer; (* temporary buffer for active body *)
  85. bufSec: Buffer; (* temporary buffer for multiple interfaces listening *)
  86. (* timer and packet count for loopback bandwidth control *)
  87. timer: Kernel.MilliTimer;
  88. packetCount: LONGINT;
  89. i: LONGINT;
  90. (** Constructor - Initialize the driver and the device.
  91. NOTE:
  92. Is normally overridden by device driver. If so, this constructor has to be called at the beginning
  93. of the overriding constructor!
  94. *)
  95. PROCEDURE &Constr*(type, mtu, adrSize: LONGINT);
  96. BEGIN
  97. ASSERT((mtu >= 0) & (mtu <= MaxPacketSize));
  98. ASSERT((adrSize >= 0) & (adrSize <= MaxLinkAdrSize));
  99. IF type = TypeEthernet THEN
  100. ASSERT(adrSize = 6);
  101. END;
  102. SELF.type := type;
  103. SELF.mtu := mtu;
  104. SELF.adrSize := adrSize;
  105. SELF.sendCount := 0;
  106. SELF.recvCount := 0;
  107. SELF.calcChecksum := {};
  108. typeList := NIL;
  109. recList := NIL;
  110. upBufFirst := NIL;
  111. Kernel.SetTimer(timer, 2);
  112. packetCount := 0;
  113. finalized := FALSE;
  114. sendSnifferList := NIL;
  115. recvSnifferList := NIL;
  116. END Constr;
  117. (** Destructor - Finalize driver object. If connected = TRUE, device is still connected and has to be deinitialized.
  118. NOTE:
  119. Is normally overridden by device driver. If so, this method has to be called at the end
  120. of the overriding method!
  121. *)
  122. PROCEDURE Finalize*(connected: BOOLEAN);
  123. BEGIN {EXCLUSIVE}
  124. ASSERT(~finalized);
  125. finalized := TRUE;
  126. END Finalize;
  127. (** Return the link status of the device.
  128. This function has to be overridden by the device driver in order to provide this information.
  129. *)
  130. PROCEDURE Linked*(): LONGINT;
  131. BEGIN
  132. RETURN LinkUnknown;
  133. END Linked;
  134. (** Send a packet. Called by its user. Can be called concurrently. *)
  135. PROCEDURE Send*(dst: LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT; loopback: BOOLEAN);
  136. VAR
  137. sniffer: SendSnifferList;
  138. discard: BOOLEAN; (* shall the packet be discarded? *)
  139. BEGIN (* can run concurrently with InstallSendSniffer and RemoveSendSniffer *)
  140. ASSERT(~finalized);
  141. discard := FALSE;
  142. sniffer := sendSnifferList;
  143. WHILE sniffer # NIL DO
  144. (* call sniffer *)
  145. discard := discard OR sniffer^.sniffer(SELF, dst, type, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen);
  146. sniffer := sniffer^.next;
  147. END;
  148. IF ~discard THEN
  149. (* send the packet *)
  150. IF loopback THEN
  151. Loopback(dst, type, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen);
  152. ELSE
  153. DoSend(dst, type, l3hdr, l4hdr, data, h3len, h4len, dofs, dlen);
  154. END;
  155. INC(sendCount, dlen + h3len + h4len);
  156. END;
  157. END Send;
  158. (** Do frame send operation. Must be overridden and implemented by device driver! *)
  159. (** Must be able to handle concurrent calls. e.g. by declaring itself as EXCLUSIVE! *)
  160. PROCEDURE DoSend*(dst: LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT);
  161. BEGIN
  162. HALT(301); (* Abstract! *)
  163. END DoSend;
  164. (* Do internal loopback. Send packet directly to the receive queue. *)
  165. PROCEDURE Loopback(dst: LinkAdr; type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; h3len, h4len, dofs, dlen: LONGINT);
  166. VAR buf: Buffer;
  167. BEGIN
  168. IF packetCount >= MaxLoopbackPacketsPerMS THEN
  169. WHILE ~Kernel.Expired(timer) DO
  170. (* no more packets can be sent until timer is expired *)
  171. Objects.Yield();
  172. END;
  173. Kernel.SetTimer(timer, 2);
  174. packetCount := 0;
  175. END;
  176. buf := GetNewBuffer();
  177. IF buf # NIL THEN
  178. buf.l3ofs := 0;
  179. buf.l4ofs := 0;
  180. buf.ofs := 0;
  181. buf.len := 0;
  182. buf.src := dst;
  183. buf.calcChecksum := {ChecksumIP, ChecksumUDP, ChecksumTCP};
  184. (* Copy data to receive buffer *)
  185. Copy(l3hdr, buf.data, 0, buf.len, h3len);
  186. INC(buf.len, h3len);
  187. Copy(l4hdr, buf.data, 0, buf.len, h4len);
  188. INC(buf.len, h4len);
  189. Copy(data, buf.data, dofs, buf.len, dlen);
  190. INC(buf.len, dlen);
  191. (* Queue the receive buffer *)
  192. QueueBuffer(buf, type);
  193. Machine.AtomicInc(packetCount)
  194. ELSE (* packet loss in loopback :o *)
  195. END
  196. END Loopback;
  197. (** Install a receiver for the given type. *)
  198. PROCEDURE InstallReceiver*(owner: ANY;
  199. type: LONGINT;
  200. receiver: Receiver;
  201. isPacketValid: IsPacketValid;
  202. isPacketForSingleRec: IsPacketForSingleRec;
  203. isPacketAccepted: IsPacketAccepted;
  204. isForwardingOn: BOOLEAN);
  205. VAR
  206. typeItem: TypeList;
  207. recItem: ReceiverList;
  208. BEGIN {EXCLUSIVE} (* can run concurrently with active body *)
  209. ASSERT(owner # NIL);
  210. ASSERT(~finalized);
  211. ASSERT(receiver # NIL);
  212. ASSERT(isPacketValid # NIL);
  213. ASSERT(isPacketForSingleRec # NIL);
  214. ASSERT(isPacketAccepted # NIL);
  215. IF type = 806H THEN
  216. KernelLog.String("Registered ARP receiver"); KernelLog.Ln
  217. ELSE
  218. KernelLog.String("Registered NON ARP receiver"); KernelLog.Ln
  219. END;
  220. (* exists the type already? *)
  221. typeItem := typeList;
  222. WHILE (typeItem # NIL) & (typeItem^.type # type) DO
  223. typeItem := typeItem^.next;
  224. END;
  225. IF typeItem = NIL THEN
  226. (* create new type item *)
  227. NEW(typeItem);
  228. typeItem^.next := typeList;
  229. typeItem^.type := type;
  230. typeItem^.recList := NIL;
  231. typeList := typeItem;
  232. END;
  233. (* create a new receiver list item *)
  234. NEW(recItem);
  235. recItem^.owner := owner;
  236. recItem^.receiver := receiver;
  237. recItem^.isPacketValid := isPacketValid;
  238. recItem^.isPacketForSingleRec := isPacketForSingleRec;
  239. recItem^.isPacketAccepted := isPacketAccepted;
  240. recItem^.isForwardingOn := isForwardingOn;
  241. recItem^.next := typeItem^.recList;
  242. typeItem^.recList := recItem;
  243. END InstallReceiver;
  244. (** Remove the currently installed receiver for the given type. *)
  245. PROCEDURE RemoveReceiver*(owner: ANY; type: LONGINT);
  246. VAR
  247. typeItem: TypeList;
  248. recItem: ReceiverList;
  249. typeItemDel: TypeList;
  250. BEGIN {EXCLUSIVE} (* can run concurrently with active body *)
  251. ASSERT(owner # NIL);
  252. ASSERT(~finalized);
  253. (* search type *)
  254. typeItem := typeList;
  255. WHILE (typeItem # NIL) & (typeItem^.type # type) DO
  256. typeItem := typeItem^.next;
  257. END;
  258. IF typeItem # NIL THEN
  259. (* search and remove receiver *)
  260. recItem := typeItem^.recList;
  261. IF (recItem # NIL) & (recItem^.owner = owner) THEN
  262. (* remove first item *)
  263. typeItem^.recList := recItem^.next;
  264. ELSE
  265. (* search list *)
  266. WHILE (recItem^.next # NIL) & (recItem^.next^.owner # owner) DO
  267. recItem := recItem^.next;
  268. END;
  269. IF recItem^.next # NIL THEN
  270. (* found a receiver *)
  271. recItem^.next := recItem^.next^.next;
  272. END;
  273. END;
  274. (* If there is no receiver anymore remove type *)
  275. IF typeItem^.recList = NIL THEN
  276. typeItemDel := typeItem;
  277. typeItem := typeList;
  278. IF (typeItem = typeItemDel) THEN
  279. (* remove first type *)
  280. typeList := typeItem^.next;
  281. ELSE
  282. (* search type list *)
  283. WHILE (typeItem^.next # typeItemDel) DO
  284. typeItem := typeItem^.next;
  285. END;
  286. typeItem^.next := typeItem^.next^.next;
  287. END;
  288. END;
  289. END;
  290. END RemoveReceiver;
  291. (** Install a sniffer for sent packets *)
  292. PROCEDURE InstallSendSniffer*(s: SendSniffer);
  293. VAR item: SendSnifferList;
  294. BEGIN {EXCLUSIVE}
  295. ASSERT(~finalized);
  296. item := sendSnifferList;
  297. WHILE (item # NIL) & (item^.sniffer # s) DO
  298. item := item^.next;
  299. END;
  300. IF item # NIL THEN
  301. (* sniffer already registered *)
  302. ELSE
  303. NEW(item);
  304. item^.sniffer := s;
  305. item^.next := sendSnifferList;
  306. sendSnifferList := item;
  307. END;
  308. END InstallSendSniffer;
  309. (** Remove a sniffer for sent packets *)
  310. PROCEDURE RemoveSendSniffer*(s: SendSniffer);
  311. VAR item: SendSnifferList;
  312. BEGIN {EXCLUSIVE}
  313. ASSERT(~finalized);
  314. IF sendSnifferList = NIL THEN
  315. (* empty list *)
  316. ELSIF sendSnifferList^.sniffer = s THEN
  317. (* remove first item *)
  318. sendSnifferList := sendSnifferList^.next;
  319. ELSE
  320. (* search list *)
  321. item := sendSnifferList;
  322. WHILE (item^.next # NIL) & (item^.next^.sniffer # s) DO
  323. item := item^.next;
  324. END;
  325. IF item^.next # NIL THEN
  326. item^.next := item^.next^.next;
  327. ELSE
  328. (* sniffer not found *)
  329. END;
  330. END;
  331. END RemoveSendSniffer;
  332. (** Install a sniffer for received packets *)
  333. PROCEDURE InstallReceiveSniffer*(s: ReceiveSniffer);
  334. VAR item: RecvSnifferList;
  335. BEGIN {EXCLUSIVE}
  336. ASSERT(~finalized);
  337. item := recvSnifferList;
  338. WHILE (item # NIL) & (item^.sniffer # s) DO
  339. item := item^.next;
  340. END;
  341. IF item # NIL THEN
  342. (* sniffer already registered *)
  343. ELSE
  344. NEW(item);
  345. item^.sniffer := s;
  346. item^.next := recvSnifferList;
  347. recvSnifferList := item;
  348. END;
  349. END InstallReceiveSniffer;
  350. (** Remove a sniffer for received packets *)
  351. PROCEDURE RemoveReceiveSniffer*(s: ReceiveSniffer);
  352. VAR item: RecvSnifferList;
  353. BEGIN {EXCLUSIVE}
  354. ASSERT(~finalized);
  355. IF recvSnifferList = NIL THEN
  356. (* empty list *)
  357. ELSIF recvSnifferList^.sniffer = s THEN
  358. (* remove first item *)
  359. recvSnifferList := recvSnifferList^.next;
  360. ELSE
  361. (* search list *)
  362. item := recvSnifferList;
  363. WHILE (item^.next # NIL) & (item^.next^.sniffer # s) DO
  364. item := item^.next;
  365. END;
  366. IF item^.next # NIL THEN
  367. item^.next := item^.next^.next;
  368. ELSE
  369. (* sniffer not found *)
  370. END;
  371. END;
  372. END RemoveReceiveSniffer;
  373. (** Queue buffer for upcall. Called from inside the LinkDevice object, normally from the interrupt handler. *)
  374. PROCEDURE QueueBuffer*(buf: Buffer; type: LONGINT);
  375. BEGIN {EXCLUSIVE}
  376. ASSERT(buf # NIL);
  377. buf.int := type; (* use "int" field for type information *)
  378. buf.next := NIL;
  379. IF upBufFirst = NIL THEN
  380. upBufFirst := buf;
  381. ELSE
  382. upBufLast.next := buf;
  383. END;
  384. upBufLast := buf;
  385. END QueueBuffer;
  386. BEGIN {ACTIVE, PRIORITY(Objects.High)}
  387. (* can run concurrently with SetReceiver, QueueBuffer, InstallReceiverSniffer and RemoveReceiverSniffer *)
  388. LOOP
  389. BEGIN {EXCLUSIVE}
  390. AWAIT((upBufFirst # NIL) OR finalized);
  391. IF (upBufFirst = NIL) & finalized THEN
  392. (* terminate process after all buffer upcalls are done *)
  393. EXIT;
  394. END;
  395. buf := upBufFirst;
  396. upBufFirst := upBufFirst.next;
  397. END;
  398. INC(recvCount, buf.len);
  399. discard := FALSE;
  400. sniffer := recvSnifferList;
  401. WHILE sniffer # NIL DO
  402. (* call sniffer *)
  403. discard := discard OR sniffer^.sniffer(SELF, buf.int, buf);
  404. sniffer := sniffer^.next;
  405. END;
  406. IF ~discard THEN
  407. (* search for type *)
  408. typeItem := typeList;
  409. WHILE (typeItem # NIL) & (typeItem^.type # buf.int) DO
  410. typeItem := typeItem^.next;
  411. END;
  412. IF typeItem # NIL THEN
  413. (* type item found check if packet is valid *)
  414. recItem := typeItem^.recList;
  415. IF (recItem # NIL) & (recItem^.isPacketValid(buf)) THEN
  416. IF recItem^.next # NIL THEN
  417. (* multiple receivers installed *)
  418. IF ~(recItem^.isPacketForSingleRec(buf)) THEN
  419. (* multiple receivers copy buffer *)
  420. WHILE recItem^.next # NIL DO
  421. bufSec := GetNewBuffer();
  422. (* copy buffer *)
  423. FOR i := 0 TO MaxPacketSize - 1 DO
  424. bufSec^.data[i] := buf^.data[i];
  425. END;
  426. bufSec^.ofs := buf^.ofs;
  427. bufSec^.len := buf^.len;
  428. bufSec^.l3ofs := buf^.l3ofs;
  429. bufSec^.l4ofs := buf^.l4ofs;
  430. bufSec^.src := buf^.src;
  431. bufSec^.calcChecksum := buf^.calcChecksum;
  432. bufSec^.int := buf^.int;
  433. bufSec^.set := buf^.set;
  434. (* deliver copied buffer to interface *)
  435. recItem^.receiver(SELF, typeItem^.type, bufSec);
  436. recItem := recItem^.next;
  437. END;
  438. (* deliver original buffer *)
  439. recItem^.receiver(SELF, typeItem^.type, buf);
  440. ELSE
  441. (* search for a single receiver *)
  442. WHILE (recItem # NIL) & ~(recItem^.isPacketAccepted(buf)) DO
  443. recItem := recItem^.next;
  444. END;
  445. IF recItem # NIL THEN
  446. (* deliver buffer *)
  447. recItem^.receiver(SELF, typeItem^.type, buf);
  448. ELSE
  449. (* Packet is not accepted ip ipforwarding is turned on deliver it *)
  450. recItem := typeItem^.recList;
  451. IF recItem^.isForwardingOn THEN
  452. (* deliver buffer *)
  453. recItem^.receiver(SELF, typeItem^.type, buf);
  454. ELSE
  455. discard := TRUE;
  456. END;
  457. END;
  458. END;
  459. ELSE
  460. (* single receiver deliver buffer directly *)
  461. IF recItem^.isPacketAccepted(buf) OR ~(recItem^.isPacketForSingleRec(buf)) THEN
  462. recItem^.receiver(SELF, typeItem^.type, buf);
  463. ELSE
  464. (* Packet is not accepted ip ipforwarding is turned on deliver it *)
  465. IF recItem^.isForwardingOn THEN
  466. (* deliver buffer *)
  467. recItem^.receiver(SELF, typeItem^.type, buf);
  468. ELSE
  469. discard := TRUE;
  470. END;
  471. END;
  472. END;
  473. ELSE
  474. discard := TRUE;
  475. END;
  476. ELSE
  477. discard := TRUE;
  478. END;
  479. END;
  480. IF discard THEN
  481. (* discard packet and return buffer *)
  482. ReturnBuffer(buf);
  483. END;
  484. END;
  485. END LinkDevice;
  486. TYPE
  487. (** Upcall procedures *)
  488. (** Packet receiver upcall
  489. CAUTION:
  490. After the buffer has been used, it has to be returned by calling Network.ReturnBuffer(buffer)!
  491. The Receiver can do this by itself or delegate this job to other procedures or processes, wherever the
  492. buffer is passed to. It has not necessarily to be returned within the receiver upcall.
  493. *)
  494. Receiver* = PROCEDURE {DELEGATE} (dev: LinkDevice; type: LONGINT; buffer: Buffer);
  495. IsPacketForSingleRec* = PROCEDURE {DELEGATE} (buffer: Buffer): BOOLEAN; (* Checks if an incoming packet should be sent to only one installed receivers *)
  496. IsPacketAccepted* = PROCEDURE {DELEGATE} (buffer: Buffer): BOOLEAN; (* Checks if an incoming packet is accepted from a certain installed receiver *)
  497. IsPacketValid* = PROCEDURE {DELEGATE} (VAR buffer: Buffer): BOOLEAN; (* Checks if an incoming packet is valid *)
  498. (* Sniffer for sent packets. May modify type, headers and data. Return TRUE if packet shall be discarded. *)
  499. (* Must be able to handle concurrent calls. e.g. by declaring itself as EXCLUSIVE. *)
  500. SendSniffer* = PROCEDURE {DELEGATE} (dev: LinkDevice; VAR dst: LinkAdr; VAR type: LONGINT; CONST l3hdr, l4hdr, data: ARRAY OF CHAR; VAR h3len, h4len, dofs, dlen: LONGINT): BOOLEAN;
  501. (* Sniffer for received packets. May modify type and buffer. Return TRUE if packet shall be discarded. *)
  502. (* Will never be called concurrenty from the same LinkDevice. *)
  503. ReceiveSniffer* = PROCEDURE {DELEGATE} (dev: LinkDevice; VAR type: LONGINT; buffer: Buffer): BOOLEAN;
  504. (** Module variables *)
  505. VAR
  506. registry*: Plugins.Registry;
  507. nofBuf: LONGINT; (* number of buffers existing *)
  508. nofFreeBuf: LONGINT; (* number of free buffers *)
  509. freeBufList: Buffer; (* free buffer list *)
  510. (** Get a new buffer - return NIL if MaxNofBuffers is exceeded *)
  511. PROCEDURE GetNewBuffer*(): Buffer;
  512. VAR item: Buffer;
  513. BEGIN {EXCLUSIVE}
  514. IF freeBufList # NIL THEN
  515. (* free buffer is available *)
  516. item := freeBufList;
  517. freeBufList := freeBufList.next;
  518. Machine.AtomicAdd(nofFreeBuf, -1);
  519. ELSIF nofBuf < MaxNofBuffers THEN
  520. (* no free buffer available - create new one *)
  521. NEW(item);
  522. Machine.AtomicInc(nofBuf);
  523. ELSE
  524. (* not allowed to create more buffers *)
  525. item := NIL;
  526. END;
  527. RETURN item;
  528. END GetNewBuffer;
  529. (** Return a buffer to be reused *)
  530. PROCEDURE ReturnBuffer*(buf: Buffer);
  531. VAR
  532. oldBuffer: Buffer;
  533. BEGIN {EXCLUSIVE}
  534. oldBuffer := buf;
  535. WHILE buf # NIL DO
  536. buf.next := freeBufList;
  537. freeBufList := buf;
  538. Machine.AtomicInc(nofFreeBuf);
  539. oldBuffer := buf;
  540. buf := buf.nextFragment;
  541. oldBuffer.nextFragment := NIL;
  542. END;
  543. END ReturnBuffer;
  544. (* Passed to registry.Enumerate() to Finalize each registered LinkDevice *)
  545. PROCEDURE Finalize(p: Plugins.Plugin);
  546. BEGIN
  547. p(LinkDevice).Finalize(TRUE);
  548. END Finalize;
  549. (** Test whether the n bytes of buf1 and buf2 starting at ofs1 and ofs2 respectively are equal *)
  550. PROCEDURE Equal*(VAR buf1, buf2: ARRAY OF CHAR; ofs1, ofs2, n: LONGINT): BOOLEAN;
  551. BEGIN
  552. WHILE (n > 0) & (buf1[ofs1] = buf2[ofs2]) DO INC(ofs1); INC(ofs2); DEC(n) END;
  553. RETURN n <= 0
  554. END Equal;
  555. (** Procedures to put and get data from and to arrays. No index checks are done due to performance! *)
  556. (** Put a 32-bit host value into buf[ofs..ofs+3] *)
  557. PROCEDURE Put4*(VAR buf: ARRAY OF CHAR; ofs, val: LONGINT);
  558. BEGIN
  559. SYSTEM.PUT8(ADDRESSOF(buf[ofs]), val MOD 100H);
  560. SYSTEM.PUT8(ADDRESSOF(buf[ofs + 1]), (val DIV 100H) MOD 100H);
  561. SYSTEM.PUT8(ADDRESSOF(buf[ofs + 2]), (val DIV 10000H) MOD 100H);
  562. SYSTEM.PUT8(ADDRESSOF(buf[ofs + 3]), (val DIV 1000000H) MOD 100H)
  563. END Put4;
  564. (** Put a 16-bit host value into buf[ofs..ofs+1] *)
  565. PROCEDURE Put2*(VAR buf: ARRAY OF CHAR; ofs, val: LONGINT);
  566. (*CODE
  567. LDR R0, [FP, #val]
  568. LDR R1, [FP, #buf]
  569. LDR R2, [FP, #ofs]
  570. ADD R2, R1, R2
  571. STRH R0, [R2, #0]*)
  572. BEGIN
  573. SYSTEM.PUT8(ADDRESSOF(buf[ofs]), INTEGER(val) MOD 100H);
  574. SYSTEM.PUT8(ADDRESSOF(buf[ofs + 1]), INTEGER(val) DIV 100H);
  575. END Put2;
  576. (** Get a 32-bit host value from buf[ofs..ofs+3] *)
  577. PROCEDURE Get4*(VAR buf: ARRAY OF CHAR; ofs: LONGINT): LONGINT;
  578. (*CODE
  579. LDR R1, [FP, #buf]
  580. LDR R2, [FP, #ofs]
  581. ADD R2, R1, R2
  582. LDR R0, [R2, #0]*)
  583. BEGIN
  584. RETURN (*SYSTEM.VAL(LONGINT, SYSTEM.GET16(ADDRESSOF(buf[ofs]))) + LSH(SYSTEM.VAL(LONGINT, SYSTEM.GET16(ADDRESSOF(buf[ofs]) + 2)), 16)*)
  585. LONGINT(ORD(buf[ofs])) + LONGINT(ORD(buf[ofs + 1])) * 100H + LONGINT(ORD(buf[ofs + 2])) * 10000H + LONGINT(ORD(buf[ofs + 3])) * 1000000H;
  586. END Get4;
  587. (** Get a 16-bit host value from buf[ofs..ofs+1] *)
  588. PROCEDURE Get2*(VAR buf: ARRAY OF CHAR; ofs: LONGINT): LONGINT;
  589. (*CODE
  590. LDR R1, [FP, #buf]
  591. LDR R2, [FP, #ofs]
  592. ADD R2, R1, R2
  593. LDRH R0, [R2, #0]*)
  594. BEGIN
  595. RETURN LONGINT(ORD(buf[ofs])) + LONGINT(ORD(buf[ofs + 1])) * 100H
  596. END Get2;
  597. (** Put a 32-bit host value into buf[ofs..ofs+3] in network byte order *)
  598. PROCEDURE PutNet4*(VAR buf: ARRAY OF CHAR; ofs, val: LONGINT);
  599. BEGIN
  600. SYSTEM.PUT8(ADDRESSOF(buf[ofs]), (val DIV 1000000H) MOD 100H);
  601. SYSTEM.PUT8(ADDRESSOF(buf[ofs + 1]), (val DIV 10000H) MOD 100H);
  602. SYSTEM.PUT8(ADDRESSOF(buf[ofs + 2]), (val DIV 100H) MOD 100H);
  603. SYSTEM.PUT8(ADDRESSOF(buf[ofs + 3]), val MOD 100H);
  604. END PutNet4;
  605. (** Put a 16-bit host value into buf[ofs..ofs+1] in network byte order *)
  606. PROCEDURE PutNet2*(VAR buf: ARRAY OF CHAR; ofs, val: LONGINT);
  607. BEGIN
  608. SYSTEM.PUT8(ADDRESSOF(buf[ofs]), INTEGER(val) DIV 100H);
  609. SYSTEM.PUT8(ADDRESSOF(buf[ofs +1]), INTEGER(val) MOD 100H);
  610. END PutNet2;
  611. (** Get a 32-bit network value from buf[ofs..ofs+3] in host byte order *)
  612. PROCEDURE GetNet4*(VAR buf: ARRAY OF CHAR; ofs: LONGINT): LONGINT;
  613. (*CODE
  614. LDR R1, [FP, #buf]
  615. LDR R2, [FP, #ofs]
  616. ADD R2, R1, R2
  617. LDR R0, [R2, #0]
  618. REV R0, R0*)
  619. BEGIN
  620. RETURN LONGINT(ORD(buf[ofs])) * 1000000H + LONGINT(ORD(buf[ofs + 1])) * 10000H + LONGINT(ORD(buf[ofs + 2])) * 100H + LONGINT(ORD(buf[ofs + 3]))
  621. END GetNet4;
  622. (** Get a 16-bit network value from buf[ofs..ofs+1] in host byte order *)
  623. PROCEDURE GetNet2*(VAR buf: ARRAY OF CHAR; ofs: LONGINT): LONGINT;
  624. (*CODE
  625. LDR R1, [FP, #buf]
  626. LDR R2, [FP, #ofs]
  627. ADD R2, R1, R2
  628. LDRH R0, [R2, #0]
  629. REV16 R0, R0*)
  630. BEGIN
  631. RETURN LONGINT(ORD(buf[ofs])) * 100H + LONGINT(ORD(buf[ofs + 1]))
  632. END GetNet2;
  633. (** Convert a LinkAdr to a printable string (up to size*3 characters) *)
  634. PROCEDURE LinkAdrToStr*(VAR adr: LinkAdr; size: LONGINT; VAR s: ARRAY OF CHAR);
  635. VAR
  636. i, j: LONGINT;
  637. hex: ARRAY 17 OF CHAR;
  638. BEGIN
  639. ASSERT(LEN(s) >= size*3); (* enough space for largest result *)
  640. hex := "0123456789ABCDEF";
  641. i := 0;
  642. FOR j := 0 TO size-1 DO
  643. s[i] := hex[ORD(adr[j]) DIV 10H MOD 10H]; INC(i);
  644. s[i] := hex[ORD(adr[j]) MOD 10H]; INC(i);
  645. IF j = size-1 THEN s[i] := 0X ELSE s[i] := ":" END;
  646. INC(i);
  647. END;
  648. END LinkAdrToStr;
  649. (** Write a link address *)
  650. PROCEDURE OutLinkAdr*(VAR adr: LinkAdr; size: LONGINT);
  651. VAR s: ARRAY MaxLinkAdrSize*3 OF CHAR;
  652. BEGIN
  653. LinkAdrToStr(adr, size, s);
  654. KernelLog.String(s);
  655. END OutLinkAdr;
  656. (** Are two link addresses equl *)
  657. PROCEDURE LinkAdrsEqual*(adr1: LinkAdr; adr2: LinkAdr): BOOLEAN;
  658. VAR
  659. i: LONGINT;
  660. adrsEqual: BOOLEAN;
  661. BEGIN
  662. adrsEqual := TRUE;
  663. i := 0;
  664. WHILE (i<8) & (adr1[i] = adr2[i]) DO
  665. INC(i);
  666. END;
  667. IF i < 8 THEN
  668. adrsEqual := FALSE;
  669. END;
  670. RETURN adrsEqual;
  671. END LinkAdrsEqual;
  672. (** Copy data from array to array *)
  673. PROCEDURE Copy*(CONST from: ARRAY OF CHAR; VAR to: ARRAY OF CHAR; fofs, tofs, len: LONGINT);
  674. BEGIN
  675. IF len > 0 THEN
  676. ASSERT((fofs+len <= LEN(from)) & (tofs+len <= LEN(to)));
  677. SYSTEM.MOVE(ADDRESSOF(from[fofs]), ADDRESSOF(to[tofs]), len);
  678. END;
  679. END Copy;
  680. PROCEDURE Cleanup;
  681. BEGIN
  682. registry.Enumerate(Finalize);
  683. Plugins.main.Remove(registry)
  684. END Cleanup;
  685. BEGIN
  686. nofBuf := 0;
  687. nofFreeBuf := 0;
  688. NEW(registry, "Network", "Network interface drivers");
  689. Modules.InstallTermHandler(Cleanup);
  690. END Network.
  691. (*
  692. History:
  693. 10.10.2003 mvt Complete redesign and additional implementation of buffer handling and upcall mechanism
  694. 17.10.2003 mvt Changed the way of initialization and finalization (now only Constr/Finalize)
  695. 21.10.2003 mvt Changed SetReceiver to InstallReceiver and RemoveReceiver
  696. 15.11.2003 mvt Changed buffering to work with EXCLUSIVE sections instead of using locking and a semaphore.
  697. 16.11.2003 mvt Added support for checksum calclulation by the device.
  698. 25.11.2003 mvt Added l3ofs and l4ofs to Buffer type.
  699. 17.12.2003 mvt Changed variable "linked" to method "Linked".
  700. 02.05.2005 eb Supports multiple interfaces per device.
  701. *)
  702. (**
  703. How to use the module:
  704. The module is loaded as soon as it is used first. It needn't to be loaded explicitly at startup. It can also be unloaded an reloaded without reboot.
  705. How to use a driver:
  706. Network driver objects in Bluebottle are extensions of the Network.LinkDevice object. All loaded instances of network driver objects are registered in the registry Network.registry. To obtain access to a network driver, use the Get, Await or GetAll methods of this registry.
  707. Example:
  708. VAR dev: Network.LinkDevice;
  709. dev := Network.registry.Get(""); (* if no name is specified, first device (or NIL) is returned *)
  710. The Send method of LinkDevice is used to send a packet. The dst parameter specifies the link destination address (e.g., a 6-byte ethernet MAC address for an ethernet device). The type parameter specifies the link-layer protocol type (e.g. 800H when sending IP over ethernet). The source address of the packet is automatically generated by the device, if necessary.
  711. For reasons of reducing buffer copying between network layers, the method allows 3 buffers to be passed:
  712. The l3hdr, l4hdr, data, h3len, h4len, dofs and dlen fields specify 3 buffers:
  713. One buffer for a layer 3 header, one for a layer 4 header and one for the payload of the packet. The buffers don't have to be filled like this. They are simply concatenated to one frame by the device driver. Therefore, each of them is allowed to be empty.
  714. The layer 3 header is stored in: l3hdr[0..h3len-1]
  715. The layer 4 header is stored in: l4hdr[0..h4len-1]
  716. The payload is stored in data[dofs..dofs+dlen-1]
  717. Example:
  718. CONST
  719. Type = 05555H; (* link-layer protocol type *)
  720. VAR
  721. dlen: LONGINT;
  722. l3hdr: ARRAY HdrLen OF CHAR;
  723. data: ARRAY MaxDataLen OF CHAR;
  724. (* - l3hdr[0..HdrLen-1] contains the layer 3 packet header.
  725. - data[0..dlen-1] contains the packet data.
  726. - there is no layer 4 header in this example, i.e. an empty buffer is passed (len=0)
  727. *)
  728. dev.Send(dev.broadcast, Type, l3hdr, l3hdr, data, HdrLen, 0, 0, dlen); (* send a broadcast packet *)
  729. Packet receiving is driven by the driver object. A receiver interested in a specific type of packet registers itself using the InstallReceiver method. The type parameter specifies the link-layer protocol type, which must be unique. There can only be one receiver installed per type. When a packet arrives, the driver object looks at the protocol type and calls the specific receiver (if any is installed for this type).
  730. Example:
  731. PROCEDURE Receiver(dev: Network.LinkDevice; type: LONGINT; buffer: Network.Buffer);
  732. BEGIN
  733. ASSERT(type = Type);
  734. CheckAdr(buffer.src); (* some link layer source address checks *)
  735. IF ~(ChecksumForThisProtocol IN buffer.calcChecksum) THEN
  736. VerifyChecksum(buffer);
  737. END;
  738. ExamineLayer3Header(buffer.data, buffer.ofs, Layer3HeaderSize);
  739. ProcessPayload(buffer.data, buffer.ofs+Layer3HeaderSize, buffer.len-Header3LayerSize);
  740. (* MANDATORY!!
  741. Buffer must be returned here! - or at higher layers, if the buffer is passed there! *)
  742. Network.ReturnBuffer(buffer);
  743. END Receiver;
  744. dev.InstallReceiver(Type, Receiver); (* install the receiver *)
  745. When passing the buffer to a higher layer (e.g. layer 4), the field "l3ofs" should be set in order to enable the higher layer protocol to access this layer's header (required by ICMP).
  746. The same is valid for the field "l4ofs" when passing the buffer to a higher layer than 4.
  747. The "type" field of a LinkDevice specifies what kind of device it is. Currently, two options (constants) are available:
  748. - TypePointToPoint: dev is a point-to-point link (device), e.g. PPP
  749. - TypeEthernet: dev is an ethernet device
  750. For point-to-point links, the following rules are met:
  751. In constructor, the "local" and "broadcast" parameters are ignored.
  752. If it is not possible to transmit the layer 3 type of packet, the type is set to 0 for the received packet.
  753. If the field "adrSize" is 0, the dst address parameter in Send() is ignored and the src address parameter in the Receiver is not defined.
  754. If "adrSize" is > 0, the dst address passed in Send() is transmitted and presented as src address for the received packet.
  755. The "local" and "broadcast" fields of the object specify the link-level address of the device, and the broadcast address, respectively. If needed, they have to be set during device initialization.
  756. The mtu field specifies the largest allowed packet size in bytes, excluding layer 2 headers and trailers (e.g. 1500 for ethernet).
  757. The "sendCount" and "recvCount" fields show the number of data bytes sent and received by the device since the driver object was loaded.
  758. How to implement a driver:
  759. IMPORTANT:
  760. - Read first "How to use a driver"!
  761. - Read comments of methods you override!
  762. A network driver object is implemented by extending the LinkDevice object. At least the "DoSend" method has to be overridden with a concrete implementation. Normally, you will also override the constructor, the destructor (method "Finalize") and the method "Linked".
  763. CAUTION:
  764. If you override the constructor or destructor:
  765. - At the beginning of the overriding constructor, the overridden constructor has to be called!
  766. - At the end of the overriding destructor, the overridden destructor has to be called!
  767. NOTE:
  768. The device has to be registered and deregistered as a Plugin in Network.registry by the device driver as follows:
  769. Add the device to the registry after it is ready to send/receive data!
  770. Remove the device from the registry before you begin to deinitialize the device!
  771. Normally, the device driver will have to install an interrupt handler for receiving packets. This handler must be installed in Objects. Interrupts registered in Machine are not allowed! (because they are not allowed to call QueueBuffer due to its EXCLUSIVE section)
  772. If you use interrupts:
  773. - do the minimum operations required for receiving and queueing a packet!
  774. - return immediately after having done the operations!
  775. Receiving and queueing packets is done like this:
  776. When you are notified of an incomming network packet (normally by an interrupt), get a new buffer by calling:
  777. buf := Network.GetNewBuffer();
  778. If buf = NIL, the packet has to be discarded because all buffers are currently in use and the maximum amount of buffers (MaxNofBuffers) is exceeded.
  779. If buf # NIL (the normal case), read the packet data into buf.data and set buf.ofs and buf.len accordingly.
  780. The buffer is not initialized in any way.
  781. If the device supports DMA, you could try to get the buffers earlier and pass their physical addesses to the device. With this you can save one packet copying operation!
  782. In addition to the fields "data", "ofs", "len" of "buffer", it is mandatory to set the fields "src" and "calcChecksum" correctly. "src" is the link layer source address and "calcChecksum" is the set of checksums already verified by the device (normally {}).
  783. As soon as the buffer contains the whole packet data, it is passed to the upper layers by calling:
  784. QueueBuffer(buf, type);
  785. Where "type" is the layer 3 type of the packet.
  786. See TestNet.Mod (SendBroadcast, SendTest and Receiver) and IP.Mod (ARPRequest and ARPInput) for an example of packet sending and receiving. See Ethernet3Com90x.Mod for an example of an ethernet driver object and Loopback.Mod for a simple point-to-point link implementation.
  787. *)