.TITLE CHKSUM Header/data checksum functions .NLIST BEX .ENABL LC ; ; Pdp11/dcn header/data checksum functions ; ; These functions are used to compute the various checksums ; used in ip-layer and transport-layer protocols. there are three ; types of checksums: ip header area, data area and tcp/udp. ; The ip header area and data area checksums include only their ; respective areas, while the tcp/udp checksum includes the ; data area together with a pseudo-header as follows: ; ; +---------------+---------------+ ; | source address | ; +---------------+---------------+ ; | destination address | ; +-------+-------+---------------+ ; | prtcl | 0 | length | ; +-------+-------+---------------+ ; ; The tcp/udp checksum extends over multiple fragments; while the ; data area checksum does not. ; ; Entry symbols ; .GLOBL CHKSUM ;checksum internet header .GLOBL TCPSUM ;checksum pseudo-header and data areas .GLOBL DATSUM ;checksum data area ; ; System definitions ; .ASECT .MCALL .COM,$DFIH ;moslib definitions .COM ;define common data $DFIH ;define internet header ; ; Procedure segment ; .PSECT $SUPI,I,RO ; ; Chksum (chk) compute internet header checksum ; R1 = packet pointer, returns r0 = checksum, cc(z) = 1 if ok ; CHKSUM: MOV R3,-(SP) ;save temporaries MOV R4,-(SP) CLR R0 MOVB IH.VER(R1),R3 ;compute length (words) BIC #^C17,R3 ASL R3 MOV #BUFLDR,R4 ;compute block pointer ADD R1,R4 1$: ADD (R4)+,R0 ;accumulate block checksum ADC R0 SOB R3,1$ BR CHK1 ; ; Datsum (dat) compute data area checksum ; R1 = packet pointer, returns r0 = checksum, cc(z) = 1 if ok ; DATSUM: MOV R3,-(SP) ;save temporaries MOV R4,-(SP) CLR R0 MOV PH.LNG(R1),R3 ;checksum data block MOV PH.OFS(R1),R4 JSR PC,SUMCHK BR CHK1 ; ; Tcpsum (tcp) compute tcp checksum ; R1 = packet pointer, returns r0 = checksum, cc(z) = 1 if ok ; TCPSUM: MOV R3,-(SP) ;save temporaries MOV R4,-(SP) CLR R0 MOV R1,-(SP) CLR -(SP) 2$: MOV PH.LNG(R1),R3 ;checksum data block ADD R3,@SP MOV PH.OFS(R1),R4 JSR PC,SUMCHK MOV PH.LNK(R1),R1 ;more fragments BNE 2$ ;branch if yes MOV (SP)+,R3 ;no. restore length MOV (SP)+,R1 SWAB R3 ;construct pseudo-header MOV R3,IH.CHK(R1) MOVB IH.TTL(R1),-(SP) CLRB IH.TTL(R1) MOV #IH.LEN-IH.TTL,R3 ;checksum pseudo-header MOV #IH.TTL,R4 JSR PC,SUMCHK MOVB (SP)+,IH.TTL(R1) CHK1: MOV (SP)+,R4 ;restore temporaries MOV (SP)+,R3 TST R0 ;recomplement BEQ 1$ COM R0 1$: RTS PC ; ; Function to checksum block ; R0 = accumulator, r1 = packet pointer, r3 = block byte count, ; R4 = block offset, returns r0 = updated accumulator ; SUMCHK: CLR -(SP) ;initialize ASR R3 ;convert to word count ADC @SP ;save odd-count switch ADD R1,R4 ;compute block pointer TST R3 ;is block empty BEQ 1$ ;branch if yes 2$: ADD (R4)+,R0 ;accumulate block checksum ADC R0 SOB R3,2$ 1$: TST @SP ;is odd-count switch set BEQ 4$ ;branch if no MOVB (R4)+,@SP ;yes. include odd byte in checksum 4$: ADD (SP)+,R0 ADC R0 RTS PC ; .END