structure ipdatagram = struct exception ip_Exception of string; type ipheader = { vershl : Word8.word, serv : Word8.word, totlen : Word8Array.array, ident : Word8Array.array, frags : Word8Array.array, ttl : Word8.word, proto : Word8.word, cksum : Word8Array.array, source : LargeWord.word, dest : LargeWord.word }; val empty_ipheader = { vershl = Word8.fromInt(0), serv = Word8.fromInt(0), totlen = double.get(Word8.fromInt(0), Word8.fromInt(0)), ident = double.get(Word8.fromInt(0), Word8.fromInt(0)), frags = double.get(Word8.fromInt(0), Word8.fromInt(0)), ttl = Word8.fromInt(0), proto = Word8.fromInt(0), cksum = double.get(Word8.fromInt(0), Word8.fromInt(0)), source = LargeWord.fromInt(0), dest = LargeWord.fromInt(0) }:ipheader; type payload = Word8Array.array; fun getipheader(data:Word8Array.array) = if (Word8Array.length(data) < 20) then raise ip_Exception("The IP header is incomplete\n") else { vershl = Word8Array.sub(data, 0), serv = Word8Array.sub(data,1), totlen = double.get(Word8Array.sub(data,2), Word8Array.sub(data,3)), ident = double.get(Word8Array.sub(data,4), Word8Array.sub(data,5)), frags = double.get(Word8Array.sub(data,6), Word8Array.sub(data,7)), ttl = Word8Array.sub(data, 8), proto = Word8Array.sub(data, 9), cksum = double.get(Word8Array.sub(data,10), Word8Array.sub(data,11)), source = Pack32Big.subArr(data, 3), dest = Pack32Big.subArr(data, 4) }:ipheader ; fun sum (tot: Word32.word, i, header:Word8Array.array, ip_header_length) = let val word16 = Pack16Big.subArr(header, i) in if (i