! Slow ether module for (Moose) INet proceess, GDMR, Jan 1988 ! This module contains an external procedure which is called by the main ! dispatcher to send a buffer out to the ether, and an autonomous process ! which takes packets from the ether and fills in the relevant fields in the ! buffer before putting it on the inbound IP queue. %option "-Nonstandard-NoCheck-NoDiag-NoLine" %constinteger inbound priority = 7 %constinteger inbound size = 10240 %constinteger out done priority = 7 %constinteger out done size = 10240 %constinteger IP protocol type = 6 %include "INet:Formats.Inc" %include "INet:Utility.Inc" %include "INet:Stats.Inc" %include "INet:Lights.Inc" %include "GDMR_E:2Meg.Inc" !! %include "INet:Dump.Inc" %externalrecord(INet statistics fm)%spec stats %externalpredicatespec FS lookup(%string(31) what, %integername value) %systemroutinespec phex(%integer x) %externalrecord(semaphore fm)%spec dispatch semaphore %externalrecord(queue fm)%spec IP inbound queue %externalinteger slow ether address = 0 %externalintegerspec slow IP address %externalintegerspec slow network %externalroutinespec add local route(%integer network, metric, %integer via) !%externalrecord(non peer info fm)%namespec sp %ownrecord(mailbox fm)%name ether mailbox %ownrecord(semaphore fm) TX semaphore = 0 %ownrecord(mailbox fm) TX response = 0 %ownrecord(semaphore fm) RX semaphore = 0 %ownrecord(ether request fm) RX request = 0 %ownrecord(mailbox fm) RX response = 0 %externalroutine slow ether outbound(%record(buffer fm)%name b) ! Send the specified buffer on its way as protocol type 6. Note that ! ether addresses are formed from IP addresses by taking the low-order ! 8 bits worth -- assuming class-C addresses, this would be the "address- ! within-network" part. %record(ether request fm)%name TX request %integer target !! printstring("Slow ether outbound: "); phex(addr(b)) !! write(b_bytes, 1); space; print INet address(b_IP peer) !! space; print INet address(b_IP target); newline !! dump(byteinteger(addr(b_IP header)), b_bytes) !L! lights or B(slow ether light) target = b_IP target & 255 target = 0 %if target = 255; ! Broadcast TX request == record(addr(b_message(0))) setup message(TX request, size of(TX request)) TX request_code = ether write TX request_tag = addr(b) TX request_ra = target TX request_type = IP protocol type TX request_buffer == byteinteger(addr(b_IP header)) TX request_bytes = b_bytes send message(TX request, ether mailbox, TX response) ! Response will be handled by autonomous process below... %end %routine outbound done %record(ether request fm)%name r %record(buffer fm)%name b open input(2, ":N"); select input(2) open output(2, ":T"); select output(2) %cycle r == receive message(TX response) %if r_status # ether success %start pdate printstring("INet slow ether: ") printstring(ether errors(r_status)) newline stats_slow errors out = stats_slow errors out + 1 %finish ! Finally drop/enqueue the packet. It will be retransmitted ! by the higher layers if required.... b == record(r_tag) stats_slow packets out = stats_slow packets out + 1 stats_slow bytes out = stats_slow bytes out + b_bytes %if addr(b_IP header) # addr(r_buffer) %start printstring("Dubious buffer address: "); phex(addr(b)) space; phex(addr(b_IP header)); space phex(addr(r_buffer)); newline %finish %if b_next queue == nil %start !! printstring("No next queue"); newline release buffer(b) %else %if b_flags & requeue flag # 0 %start !! printstring("Requeue on "); phex(addr(b_next queue)); newline requeue(b, b_next queue) %else !! printstring("Enqueue on "); phex(addr(b_next queue)); newline enqueue(b, b_next queue) %finish %finish !L! lights and B(\ slow ether light) %repeat %end %routine inbound process %owninteger RX sequence = 0 %record(buffer fm)%name b %record(ether request fm)%name r open input(2, ":N"); select input(2) open output(2, ":T"); select output(2) !! printstring("Slow inbound handler started"); newline %cycle b == claim buffer %if b == nil %start printstring("No buffers??"); newline %stop %finish !! printstring("Inbound buffer at "); phex(addr(b)); newline RX sequence = RX sequence + 1 RX request_code = ether read RX request_tag = RX sequence RX request_type = IP protocol type RX request_buffer == b_data(32) send message(RX request, ether mailbox, RX response) !! printstring("Read queued, buffer at "); phex(addr(b)); newline r == receive message(RX response) !L! lights or A(slow ether light) %if r_tag # RX sequence %start pdate printstring("INet slow ether: dud tag ") phex(r_tag); space; phex(RX sequence) newline stats_slow errors in = stats_slow errors in + 1 release buffer(b) %else %if r_status # ether success pdate printstring("INet slow ether: ") printstring(ether errors(r_status)) newline stats_slow errors in = stats_slow errors in + 1 release buffer(b) %else b_bytes = r_bytes b_IP header == record(addr(b_data(32))) b_next queue == nil b_flags = broadcast flag %if r_ra = 0 b_interface = 1 stats_slow packets in = stats_slow packets in + 1 stats_slow bytes in = stats_slow bytes in + b_bytes !! printstring("Received "); write(b_bytes, 0) !! printstring(" into "); phex(addr(b)); newline !! dump(byteinteger(addr(b_IP header)), b_bytes) enqueue(b, IP inbound queue) signal semaphore(dispatch semaphore) %finish !L! lights and A(\ slow ether light) %repeat %end %externalroutine start slow ether ! Set up mailboxes, etc, register ourselves as protocol 6, and start ! the receiver process. %record(process fm)%name p %record(ether request fm)%name r %integer x %label start inbound, start out done %if FS lookup(ether mailbox name, x) %start ether mailbox == record(x) %else printstring("No slow ether mailbox??"); newline %stop %finish setup semaphore(TX semaphore) setup mailbox(TX response, TX semaphore) setup semaphore(RX semaphore) setup mailbox(RX response, RX semaphore) setup message(RX request, size of(RX request)) RX request_code = ether register RX request_type = IP protocol type send message(RX request, ether mailbox, RX response) r == receive message(RX response) %if r_status # ether success %start printstring("Register: "); printstring(ether errors(r_status)) newline %stop %finish RX request_code = ether station address send message(RX request, ether mailbox, RX response) r == receive message(RX response) %if r_status # ether success %start printstring("Enquire address: "); printstring(ether errors(r_status)) newline %stop %finish slow ether address = r_context slow IP address = 193 << 24 ! 208 << 16 ! 205 << 8 ! slow ether address slow network = slow IP address & 16_FFFFFF00 add local route(slow IP address, 1, 1) {} printstring("Slow ether IP address is ") {} print INet address(slow IP address); newline p == create process(inbound size, addr(start inbound), inbound priority, nil) p == create process(out done size, addr(start out done), out done priority, nil) !! printstring("INet slow ether handler started"); newline %return start inbound: inbound process start out done: outbound done %end %end %of %file