mirror of
https://github.com/elliotnunn/NetBoot.git
synced 2025-02-11 08:31:10 +00:00
Basic dropped-packet tolerance
This commit is contained in:
parent
c16fa09c3d
commit
5c97e31336
35
ChainBoot.py
35
ChainBoot.py
@ -10,12 +10,17 @@ import struct
|
||||
import sys
|
||||
|
||||
import time
|
||||
import random
|
||||
|
||||
from snefru_hash import append_snefru
|
||||
|
||||
|
||||
|
||||
|
||||
UNRELIABILITY_PERCENT = 1
|
||||
def failchance():
|
||||
return (random.random() < UNRELIABILITY_PERCENT/100)
|
||||
|
||||
my_unique_ltoudp_id = b'El' + (os.getpid() & 0xFFFF).to_bytes(2, 'big')
|
||||
|
||||
|
||||
@ -83,6 +88,11 @@ def mk_ddp(dest_node, dest_socket, src_node, src_socket, proto_type, data):
|
||||
|
||||
return data
|
||||
|
||||
def send(ddp):
|
||||
if failchance(): return
|
||||
sock.sendto(ddp, (MCAST_ADDR, MCAST_PORT))
|
||||
|
||||
|
||||
|
||||
|
||||
def pstring(x):
|
||||
@ -164,7 +174,7 @@ while 1:
|
||||
# NBP LkUp
|
||||
|
||||
if len(nbp_tuples) == 1 and nbp_tuples[0][5] == 'BootServer': # Looking for us
|
||||
sock.sendto(mk_ddp(
|
||||
send(mk_ddp(
|
||||
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
||||
src_node=99, src_socket=99,
|
||||
proto_type=2,
|
||||
@ -176,8 +186,7 @@ while 1:
|
||||
0, # (My) Enumerator (i.e. which of many possible names for 99/99 is this?)
|
||||
) +
|
||||
pstring(nbp_tuples[0][4]) + pstring('BootServer') + pstring('*')
|
||||
),
|
||||
(MCAST_ADDR, MCAST_PORT))
|
||||
))
|
||||
|
||||
elif ddp_proto_type == 10:
|
||||
# Mysterious ATBOOT protocol
|
||||
@ -234,13 +243,12 @@ while 1:
|
||||
# }BootPktRply;
|
||||
|
||||
# Ignore the silly user record. Just make the fucker work!
|
||||
sock.sendto(mk_ddp(
|
||||
send(mk_ddp(
|
||||
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
||||
src_node=99, src_socket=99,
|
||||
proto_type=10,
|
||||
data=struct.pack('>BBHLHHhL', 2, 1, boot_machine_id, boot_timestamp, 512, 0, 0, len(image) // 512).ljust(586, b'\0')
|
||||
),
|
||||
(MCAST_ADDR, MCAST_PORT))
|
||||
))
|
||||
|
||||
elif boot_type == 3:
|
||||
# It seems to want part of the boot image!
|
||||
@ -274,13 +282,12 @@ while 1:
|
||||
# } BootBlock,*BootBlockPtr;
|
||||
|
||||
# print(f' {blocknum}', end='', flush=True)
|
||||
sock.sendto(mk_ddp(
|
||||
send(mk_ddp(
|
||||
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
||||
src_node=99, src_socket=99,
|
||||
proto_type=10,
|
||||
data=struct.pack('>BBHH', 4, 1, boot_image_id, blocknum) + image[blocknum*512:blocknum*512+512]
|
||||
),
|
||||
(MCAST_ADDR, MCAST_PORT))
|
||||
))
|
||||
|
||||
# time.sleep(0.5)
|
||||
# break # wait for another request, you mofo!
|
||||
@ -291,13 +298,12 @@ while 1:
|
||||
boot_imgname = boot_imgname.decode('mac_roman')
|
||||
for blk in range(boot_blkoffset, boot_blkoffset + boot_blkcnt):
|
||||
thisblk = writable_image[blk*512:blk*512+512]
|
||||
sock.sendto(mk_ddp(
|
||||
send(mk_ddp(
|
||||
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
||||
src_node=99, src_socket=99,
|
||||
proto_type=10,
|
||||
data=struct.pack('>BBH', 129, blk-boot_blkoffset, boot_seq) + thisblk
|
||||
),
|
||||
(MCAST_ADDR, MCAST_PORT))
|
||||
))
|
||||
|
||||
elif boot_type == 130:
|
||||
boot_type, blk, seq, boot_imgnum, hunk_start = struct.unpack_from('>BBHLL', whole_data)
|
||||
@ -312,13 +318,12 @@ while 1:
|
||||
del buf[(blk % 32) * 512 + 512:]
|
||||
writable_image[hunk_start*512:hunk_start*512+len(buf)] = buf
|
||||
|
||||
sock.sendto(mk_ddp(
|
||||
send(mk_ddp(
|
||||
dest_node=llap_src_node, dest_socket=ddp_src_socket,
|
||||
src_node=99, src_socket=99,
|
||||
proto_type=10,
|
||||
data=struct.pack('>BBH', 131, 0, seq)
|
||||
),
|
||||
(MCAST_ADDR, MCAST_PORT))
|
||||
))
|
||||
|
||||
else:
|
||||
print(f'ATBOOT type={boot_type} vers={boot_vers} contents={repr(data)}')
|
||||
|
@ -1,4 +1,6 @@
|
||||
kUserRecLen equ 568
|
||||
kInitialWaitMsec equ 10000
|
||||
kSubsequentWaitMsec equ 1000
|
||||
|
||||
Code
|
||||
|
||||
@ -185,6 +187,12 @@ gSaveAddr dcb.b 16
|
||||
gAddr dcb.b 16
|
||||
even
|
||||
|
||||
; Time Manager task
|
||||
tmLink dc.l 0
|
||||
tmType dc.w 0
|
||||
tmAddr dc.l 0
|
||||
tmCount dc.l 0
|
||||
|
||||
; Drive queue element
|
||||
dqFlags dc.l $00080000
|
||||
dqLink dc.l 0
|
||||
@ -231,8 +239,20 @@ DrvrPrime
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
DrvrReSendRead
|
||||
; Time Manager task
|
||||
lea tmLink,A0
|
||||
dc.w $A059 ; _RmvTime
|
||||
|
||||
move.l gMyDCE,A1 ; get Device Mgr registers
|
||||
move.l 6+2(A1),A0
|
||||
|
||||
; truncate ioActCount
|
||||
and.l #-32*512,$28(A0) ; truncate ioActCount
|
||||
|
||||
DrvrSendRead
|
||||
; Called from Prime routine or socket listener: PB/DCE in A0/A1 must be preserved (but we only require A0)
|
||||
; Called from Prime routine, socket listener or Time Manager:
|
||||
; PB/DCE in A0/A1 must be preserved (but we only require A0)
|
||||
lea gExpectHdr,A2
|
||||
clr.w (A2)+
|
||||
addq.w #1,(A2) ; packet filter sequence word
|
||||
@ -294,15 +314,38 @@ DrvrCopyAddrStruct
|
||||
|
||||
DrvrDidSendRead
|
||||
; Called as completion routine: PB/result in A0/D0, must preserve all registers other than A0/A1/D0-D2
|
||||
lea gExpectHdr,A2
|
||||
move.w #$8100,(A2) ; Enable packet reception
|
||||
lea gExpectHdr,A0
|
||||
move.w #$8100,(A0) ; Enable packet reception
|
||||
move.l #kInitialWaitMsec,D0
|
||||
|
||||
rts ; TODO: set up a timeout/retry task
|
||||
DrvrInstallReSendRead
|
||||
; Called from anywhere, D0=waittime, can clobber anything
|
||||
lea tmLink,A0
|
||||
pea DrvrReSendRead
|
||||
move.l (SP)+,tmAddr-tmLink(A0)
|
||||
move.l D0,-(SP)
|
||||
dc.w $A058 ; _InsTime
|
||||
move.l (SP)+,D0
|
||||
dc.w $A05A ; _PrimeTime
|
||||
rts
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
DrvrReSendWrite
|
||||
; Time Manager task
|
||||
lea tmLink,A0
|
||||
dc.w $A059 ; _RmvTime
|
||||
|
||||
move.l gMyDCE,A1 ; get Device Mgr registers
|
||||
move.l 6+2(A1),A0
|
||||
|
||||
; truncate ioActCount
|
||||
sub.l #512,$28(A0)
|
||||
and.l #-32*512,$28(A0) ; truncate ioActCount
|
||||
|
||||
DrvrSendWrite
|
||||
; Called from Prime routine or socket listener: PB/DCE in A0/A1 must be preserved (but we only require A0)
|
||||
; Called from Prime routine, socket listener or Time Manager:
|
||||
; PB/DCE in A0/A1 must be preserved (but we only require A0)
|
||||
|
||||
; D1 = block index within chunk
|
||||
move.l $28(A0),D1
|
||||
@ -329,7 +372,7 @@ DrvrSendWrite
|
||||
addq.w #1,(A2) ; packet filter sequence word
|
||||
.notFirstBlockOfChunk
|
||||
|
||||
bsr.s DrvrCopyAddrStruct
|
||||
bsr DrvrCopyAddrStruct
|
||||
|
||||
lea gQuery,A2
|
||||
move.b #$82,(A2)+ ; Means a polite request
|
||||
@ -381,13 +424,19 @@ DrvrDidSendWrite ; completion routine for the above control call..
|
||||
move.l D1,$28(A0)
|
||||
|
||||
cmp.l D0,D1
|
||||
beq.s .sentAllOfChunk
|
||||
beq.s DrvrInstallReSendWrite
|
||||
and.l #(32-1)*512,D0
|
||||
beq.s .sentAllOfChunk
|
||||
beq.s DrvrInstallReSendWrite
|
||||
bra DrvrSendWrite
|
||||
|
||||
.sentAllOfChunk
|
||||
rts ; TODO: set up a timeout/retry task
|
||||
DrvrInstallReSendWrite
|
||||
lea tmLink,A0
|
||||
pea DrvrReSendWrite
|
||||
move.l (SP)+,tmAddr-tmLink(A0)
|
||||
dc.w $A058 ; _InsTime
|
||||
move.l #kInitialWaitMsec,D0
|
||||
dc.w $A05A ; _PrimeTime
|
||||
rts
|
||||
|
||||
DrvrClearBlock
|
||||
move.w #$32/2-1,D0
|
||||
@ -463,6 +512,11 @@ DrvrSockListener
|
||||
clr.b D3
|
||||
bne DrvrTrashPacket
|
||||
|
||||
movem.l A0-A1/D0-D2,-(SP)
|
||||
lea tmLink,A0
|
||||
dc.w $A059 ; _RmvTime
|
||||
movem.l (SP)+,A0-A1/D0-D2
|
||||
|
||||
btst #25,D2
|
||||
bne.s DrvrDidReceiveWrite
|
||||
|
||||
@ -506,7 +560,8 @@ DrvrDidReceiveRead
|
||||
addq.l #1,D1 ; If bitmap=$FFFFFFFF then get the next chunk of 32
|
||||
beq DrvrSendRead ; A0 must be the PB
|
||||
|
||||
rts ; Just return to await more packets.
|
||||
move.l #kSubsequentWaitMsec,D0
|
||||
bra DrvrInstallReSendRead ; Just return to await more packets.
|
||||
|
||||
DrvrDidReceiveWrite
|
||||
moveq.l #0,D3
|
||||
|
Loading…
x
Reference in New Issue
Block a user