+ ; check for ipv4
+ ld a, [hl]
+ ld c, a
+ and $F0
+ swap a
+ sub $04
+ jr z, .ip_isv4
+ PUTSIL "ip_input: not ipv4 -- fuck off"
+ ret
+.ip_isv4
+ ; get length
+ ld a, c
+ and $0F
+ sla a
+ ld c, a
+ sla a
+ sub $14
+ ld b, a
+ push bc
+
+ ; check checksum
+ xor a
+ ld d, a
+ ld e, a
+ push hl
+.ip_cksumloop:
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ add e
+ ld e, a
+ ld a, b
+ add d
+ ld d, a
+ jr nc, .ip_noinc
+ inc de
+.ip_noinc:
+ dec c
+ jr nz, .ip_cksumloop
+
+ ; checksum ok
+ pop hl
+ ld a, d
+ or e
+ jr z, .ip_cksumgood
+ ld a, d
+ and e
+ cpl
+ or a
+ jr z, .ip_cksumgood
+ PUTSIL "ip_input: checksum fail -- bailing"
+ pop hl
+ ret
+.ip_cksumgood:
+ PUTSIL "ip_input: checksum good"
+ ld b, $00
+ ld c, $0C
+ add hl, bc
+ ld c, $04
+
+ ; print source IP
+ PUTSI "ip_input: this packet is from 0x"
+.ip_get_srcip:
+ ld a, [hli]
+ PUTHEX a
+ dec c
+ jr nz, .ip_get_srcip
+ PUTSIL "."
+
+ ; check dest IP
+ ld d, myIP >> 8
+ ld e, myIP & $FF
+ ld c, $04
+.ip_chkip:
+ ld b, [hl]
+ inc hl
+ ld a, [de]
+ inc de
+ cp b
+ jr nz, .ip_ipfail
+ dec c
+ jr nz, .ip_chkip
+
+ PUTSIL "ip_input: wheeeeeeeeeeeeeeee"
+ ; get protocol in A
+ ld d, $FF
+ ld e, -$0B
+ add hl, de
+ ld a, [hl]
+ ld d, $00
+ ld e, $0B
+ add hl, de
+
+ ; make hl point at beginning of data
+ pop bc
+ ld c, b
+ ld b, $00
+ add hl, bc
+
+ ; ok, pass it off to something else
+ cp $01
+ jr z, .ip_icmp
+ cp $11
+ jr z, .ip_udp
+ ret
+
+.ip_icmp:
+ call icmp_input
+ ret
+
+.ip_udp:
+ call udp_input
+ ret
+
+.ip_ipfail:
+ PUTSIL "ip_input: this packet is not to our IP address. Bailing."
+ pop hl
+ ret
+
+icmp_input:
+ PUTSIL "icmp_input: too lazy to parse -- fuck off"
+ ret
+
+udp_input:
+ PUTSIL "udp_input: too lazy to parse -- fuck off"