Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5841 → Rev 5842

/kernel/trunk/network/IPv4.inc
215,7 → 215,6
; It will also re-construct fragmented packets
;
; IN: Pointer to buffer in [esp]
; size of buffer in [esp+4]
; pointer to device struct in ebx
; pointer to IPv4 header in edx
; size of IPv4 packet in ecx
223,7 → 222,7
;
;-----------------------------------------------------------------
align 4
IPv4_input: ; TODO: add IPv4 raw sockets support
IPv4_input:
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: packet from %u.%u.%u.%u ",\
[edx + IPv4_header.SourceAddress + 0]:1,[edx + IPv4_header.SourceAddress + 1]:1,\
232,6 → 231,10
[edx + IPv4_header.DestinationAddress + 0]:1,[edx + IPv4_header.DestinationAddress + 1]:1,\
[edx + IPv4_header.DestinationAddress + 2]:1,[edx + IPv4_header.DestinationAddress + 3]:1
 
call NET_ptr_to_num4
cmp edi, -1
je .invalid_device
 
;-------------------------------
; re-calculate the checksum
 
240,40 → 243,32
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Checksum ok\n"
 
;-----------------------------------
; Check if destination IP is correct
;--------------------------------
; Check if destination IP matches
 
call NET_ptr_to_num4
 
; check if it matches local ip (Using RFC1122 strong end system model)
 
; local ip (Using RFC1122 strong end system model)
mov eax, [edx + IPv4_header.DestinationAddress]
cmp eax, [IP_LIST + edi]
je .ip_ok
 
; check for broadcast (IP or (not SUBNET))
 
; network layer broadcast
cmp eax, [BROADCAST_LIST + edi]
je .ip_ok
 
; or a special broadcast (255.255.255.255)
 
; physical layer broadcast (255.255.255.255)
cmp eax, 0xffffffff
je .ip_ok
 
; maybe it's a multicast (224.0.0.0/4)
 
; multicast (224.0.0.0/4 = 224.0.0.0 to 239.255.255.255)
and eax, 0x0fffffff
cmp eax, 224
je .ip_ok
 
; maybe we just dont have an IP yet and should accept everything on the IP level
 
cmp [IP_LIST + edi], 0
je .ip_ok
 
; or it's just not meant for us.. :(
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: Destination address does not match!\n"
jmp .dump
 
305,7 → 300,6
xchg cl, ch ;
sub ecx, esi ;
 
lea edi, [edx + IPv4_header.SourceAddress] ; make edi ptr to source and dest IPv4 address
mov al, [edx + IPv4_header.Protocol]
add esi, edx ; make esi ptr to data
 
318,15 → 312,64
cmp al, IP_PROTO_ICMP
je ICMP_input
 
;-------------------------------
; Look for a matching RAW socket
pusha
mov ecx, socket_mutex
call mutex_lock
popa
 
add ecx, esi
sub ecx, edx
mov esi, edx
movzx edx, al
mov eax, net_sockets
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump_unlock
 
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
 
cmp [eax + SOCKET.Protocol], edx
jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: found matching RAW socket: 0x%x\n", eax
 
pusha
lea ecx, [eax + SOCKET.mutex]
call mutex_lock
popa
 
jmp SOCKET_input
 
.dump_unlock:
 
pusha
mov ecx, socket_mutex
call mutex_unlock
popa
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: unknown protocol %u\n", al
 
.dump:
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_input: dumping\n"
inc [IPv4_packets_dumped] ; FIXME: use correct interface
inc [IPv4_packets_dumped + edi]
call NET_BUFF_free
ret
 
.invalid_device:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_input: packet originated from invalid device\n"
call NET_BUFF_free
ret
 
 
;---------------------------
; Fragmented packet handler
 
568,11 → 611,12
;
; IPv4_output
;
; IN: eax = Destination IP
; IN: al = protocol
; ah = TTL
; ebx = device ptr (or 0 to let IP layer decide)
; ecx = data length
; edx = Source IP
; di = TTL shl 8 + protocol
; edi = Destination IP
;
; OUT: eax = pointer to buffer start / 0 on error
; ebx = device ptr (send packet through this device)
589,7 → 633,8
cmp ecx, 65500 ; Max IPv4 packet size
ja .too_large
 
push ecx di eax
push ecx ax edi
mov eax, edi
call IPv4_route ; outputs device number in edi, dest ip in eax, source IP in edx
push edx
test edi, edi
642,7 → 687,10
 
.arp_error:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ARP error=%x\n", eax
add esp, 3*4+2
add esp, 4
pop eax
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output: ip=0x%x\n", eax
add esp, 4+2
xor eax, eax
ret
 
678,9 → 726,6
 
DEBUGF 1,"IPv4_output_raw: size=%u ptr=%x socket=%x\n", ecx, esi, eax
 
cmp ecx, 1480 ;;;;; FIXME
ja .too_large
 
sub esp, 8
push esi eax
 
707,7 → 752,7
mov dword[esp+4+4+4], eax
 
pop eax esi
;; todo: check socket options if we should add header, or just compute checksum
;; TODO: check socket options if we should add header, or just compute checksum
 
push edi ecx
rep movsb
734,11 → 779,14
ret
 
.error:
add esp, 6
add esp, 6+8+4+4
mov ebx, ENOBUFS ; FIXME: NOBUFS or MSGSIZE error
or eax, -1
ret
 
.arp_error:
add esp, 8+4+4
.too_large:
DEBUGF DEBUG_NETWORK_ERROR, "IPv4_output_raw: Failed\n"
mov ebx, ENOTCONN
or eax, -1
ret
 
746,119 → 794,122
;--------------------------------------------------------
;
;
; IN: dword [esp] = pointer to buffer containing ipv4 packet to be fragmented
; esi = pointer to ip header in that buffer
; ecx = max size of fragments
; IN: [esp] = pointer to buffer containing ipv4 packet to be fragmented
; edi = pointer to ip header in that buffer
; ebx = device ptr
;
; OUT: /
;
;--------------------------------------------------------
proc IPv4_fragment stdcall buffer
 
align 4
IPv4_fragment:
locals
offset dd ?
headerlength dd ?
headerptr dd ?
dataptr dd ?
remaining dd ?
segmentsize dd ?
endl
 
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment\n"
 
and ecx, not 111b ; align 4
; We must be able to put at least 8 bytes per segment
movzx eax, byte[edi] ; IHL
and eax, 0xf
shl eax, 2
mov [headerlength], eax
add eax, 8
mov ecx, [ebx + NET_DEVICE.mtu]
and ecx, not 11b
cmp ecx, eax
jb .fail
 
cmp ecx, sizeof.IPv4_header + 8 ; must be able to put at least 8 bytes
jb .err2
mov [edi + IPv4_header.HeaderChecksum], 0
 
push esi ecx
mov eax, [esi + IPv4_header.DestinationAddress]
call ARP_IP_to_MAC
pop ecx esi
cmp eax, -1
jz .err2
mov [segmentsize], ecx
mov [headerptr], edi
movzx ecx, [edi + IPv4_header.TotalLength]
xchg cl, ch
sub ecx, [headerlength]
mov [remaining], ecx
mov [offset], 0
 
push ebx
push ax
add edi, [headerlength]
mov [dataptr], edi
 
mov ebx, [NET_DRV_LIST]
lea eax, [ebx + ETH_DEVICE.mac]
push eax
.loop:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
 
mov ecx, [segmentsize]
cmp ecx, [remaining]
jbe @f
mov ecx, [remaining]
@@:
 
push esi ; ptr to ip header
sub ecx, sizeof.IPv4_header ; substract header size
push ecx ; max data size
push dword 0 ; offset
 
.new_fragment:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: new fragment"
 
mov ax, ETHER_PROTO_IPv4
lea ebx, [esp + 4*4]
mov edx, [esp]
add edx, [edx + NET_BUFF.offset]
; add edx, ETH_header.DstMAC ; = 0
call ETH_output
jz .err
jz .fail
 
push edi
mov edx, ecx
 
; copy header
mov esi, [esp + 2*4]
mov ecx, 5 ; 5 dwords: TODO: use IHL field of the header!
mov esi, [headerptr]
mov ecx, [headerlength]
shr ecx, 2
rep movsd
 
; copy data
mov esi, [esp + 2*4]
add esi, sizeof.IPv4_header
add esi, [esp] ; offset
mov esi, [dataptr]
add esi, [offset]
mov ecx, edx
sub ecx, [headerlength]
shr ecx, 2
rep movsd
pop edi
 
mov ecx, [esp + 1*4]
DEBUGF DEBUG_NETWORK_VERBOSE, "IPv4_fragment: copying %u bytes\n", ecx
rep movsb
 
; now, correct header
mov ecx, [esp + 1*4]
add ecx, sizeof.IPv4_header
xchg cl, ch
mov [edi + IPv4_header.TotalLength], cx
; packet length
mov ax, dx
xchg al, ah
mov [edi + IPv4_header.TotalLength], ax
 
mov ecx, [esp] ; offset
xchg cl, ch
; offset
mov eax, [offset]
xchg al, ah
 
; cmp dword[esp + 4*4], 0 ; last fragment?;<<<<<<
; je .last_fragment
or cx, 1 shl 2 ; more fragments
; .last_fragment:
mov [edi + IPv4_header.FlagsAndFragmentOffset], cx
sub edx, [headerlength]
sub [remaining], edx
je @f
jb .fail
or ah, 1 shl 2 ; more fragments
add [offset], edx
@@:
mov [edi + IPv4_header.FlagsAndFragmentOffset], ax
 
mov [edi + IPv4_header.HeaderChecksum], 0
 
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<< send the packet
mov ecx, [esp + 1*4]
 
push edx eax
; Send the fragment
IPv4_checksum edi
 
call [ebx + NET_DEVICE.transmit]
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 
mov ecx, [esp+4]
add [esp], ecx
cmp [remaining], 0
jne .loop
 
mov ecx, [esp+3*4+6+4] ; ptr to begin of buff
add ecx, [esp+3*4+6+4+4] ; buff size
sub ecx, [esp+2*4] ; ptr to ip header
add ecx, [esp] ; offset
call NET_BUFF_free
ret
 
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: %u bytes remaining\n", ecx
 
cmp ecx, [esp+1*4]
jae .new_fragment
 
mov [esp+4], ecx ; set fragment size to remaining packet size
jmp .new_fragment
 
.err:
.fail:
DEBUGF DEBUG_NETWORK_ERROR, "Ipv4_fragment: failed\n"
.done:
add esp, 12 + 4 + 6
.err2:
DEBUGF DEBUG_NETWORK_VERBOSE, "Ipv4_fragment: dumping\n"
call NET_BUFF_free
ret
 
endp
 
 
 
;---------------------------------------------------------------------------
;
; IPv4_route
973,11 → 1024,6
pushd [edx + 4]
pop [eax + IP_SOCKET.RemoteIP]
 
; Set up data receiving queue
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION)
pop eax
 
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
 
/kernel/trunk/network/icmp.inc
133,8 → 133,9
; IN: Pointer to buffer in [esp]
; ebx = pointer to device struct
; ecx = ICMP Packet size
; edx = ptr to IPv4 header
; esi = ptr to ICMP Packet data
; edi = ptr to ipv4 source and dest address
; edi = interface number*4
;
; OUT: /
;
144,8 → 145,13
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input\n"
 
; Dump all multicasts and broadcasts
mov eax, [IP_LIST + edi]
cmp eax, [edx + IPv4_header.DestinationAddress]
jne .dump
 
; Check the checksum
push esi ecx
push esi ecx edx
push [esi + ICMP_header.Checksum]
mov [esi + ICMP_header.Checksum], 0
xor edx, edx
153,17 → 159,11
call checksum_2
pop si
cmp dx, si
pop ecx esi
pop edx ecx esi
jne .checksum_mismatch
 
DEBUGF DEBUG_NETWORK_VERBOSE, "ICMP_input: Checksum OK\n"
 
; Ualidate device ptr
mov eax, edi
call NET_ptr_to_num4
cmp edi, -1
je .dump
 
; Update stats
inc [ICMP_PACKETS_RX + edi]
 
177,10 → 177,10
call mutex_lock
popa
 
mov edx, [eax] ; ipv4 source address
add ecx, esi
sub ecx, edx
mov esi, edx
mov eax, net_sockets
.try_more:
; mov , [esi + ICMP_header.Identifier]
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
192,12 → 192,6
cmp [eax + SOCKET.Protocol], IP_PROTO_ICMP
jne .next_socket
 
cmp [eax + IP_SOCKET.RemoteIP], edx
jne .next_socket
 
; cmp [eax + ICMP_SOCKET.Identifier],
; jne .next_socket
 
pusha
mov ecx, socket_mutex
call mutex_unlock
376,7 → 370,7
;
; IN: eax = socket ptr
; ecx = data length
; esi = data offset
; edx = data pointer
;
;-----------------------------------------------------------------
align 4
385,13 → 379,13
DEBUGF DEBUG_NETWORK_VERBOSE, "Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
 
push edx
 
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
mov ebx, [eax + IP_SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP]
mov ebx, [eax + IP_SOCKET.device]
mov eax, [eax + IP_SOCKET.RemoteIP]
mov edi, [eax + IP_SOCKET.RemoteIP]
mov al, [eax + IP_SOCKET.ttl]
mov ah, IP_PROTO_ICMP
call IPv4_output
jz .exit
jz .fail
 
pop esi
push eax
417,8 → 411,12
inc [ICMP_PACKETS_TX + edi]
@@:
ret
.exit:
 
.fail:
pop edx
DEBUGF DEBUG_NETWORK_ERROR, "Creating ICMP Packet failed\n"
or eax, -1
mov ebx, EMSGSIZE ;;; FIXME
ret
 
 
/kernel/trunk/network/socket.inc
27,9 → 27,9
 
PID dd ? ; process ID
TID dd ? ; thread ID
Domain dd ? ; INET/LOCAL/..
Domain dd ? ; INET4/INET6/LOCAL/..
Type dd ? ; RAW/STREAM/DGRAM
Protocol dd ? ; ICMP/IPv4/ARP/TCP/UDP
Protocol dd ? ; UDP/TCP/ARP/ICMP
errorcode dd ?
device dd ? ; driver pointer, socket pointer if it's an LOCAL socket
 
47,6 → 47,8
 
LocalIP rd 4 ; network byte order
RemoteIP rd 4 ; network byte order
ttl db ?
rb 3 ; align
 
ends
 
150,14 → 152,6
 
ends
 
 
struct ICMP_SOCKET IP_SOCKET
 
Identifier dw ?
 
ends
 
 
struct RING_BUFFER
 
mutex MUTEX
313,6 → 307,8
cmp ecx, AF_INET4
jne .no_inet4
 
mov [eax + IP_SOCKET.ttl], 128
 
cmp edx, SOCK_DGRAM
je .udp
 
354,6 → 350,10
 
align 4
.udp:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
mov [eax + SOCKET.Protocol], IP_PROTO_UDP
mov [eax + SOCKET.snd_proc], SOCKET_send_udp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
373,6 → 373,10
 
align 4
.raw_ip:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
mov [eax + SOCKET.snd_proc], SOCKET_send_ip
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
381,6 → 385,10
 
align 4
.raw_icmp:
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
mov [eax + SOCKET.snd_proc], SOCKET_send_icmp
mov [eax + SOCKET.rcv_proc], SOCKET_receive_dgram
mov [eax + SOCKET.connect_proc], IPv4_connect
975,14 → 983,14
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: IPv4\n"
 
mov [esp+32], ecx
call IPv4_output_raw ; FIXME: IPv4_output_raw should return error codes!
call IPv4_output_raw
cmp eax, -1
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE
mov dword[esp+32], eax
mov dword[esp+20], ebx
ret
 
 
992,14 → 1000,14
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: ICMP\n"
 
mov [esp+32], ecx
call ICMP_output_raw ; FIXME: errorcodes
call ICMP_output_raw
cmp eax, -1
je .error
ret
 
.error:
mov dword[esp+32], -1
mov dword[esp+20], EMSGSIZE
mov dword[esp+32], eax
mov dword[esp+20], ebx
ret
 
 
1126,17 → 1134,23
ret
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_set_options
;
; IN: ecx = socket number
; edx = pointer to the options:
; dd level, optname, optlen, optval
; edx = pointer to socket_options
; OUT: -1 on error
;
;-----------------------------------------------------------------
 
struct socket_options
level dd ?
optname dd ?
optlen dd ?
optval dd ?
ends
 
align 4
SOCKET_set_opt:
 
1145,22 → 1159,20
call SOCKET_num_to_ptr
jz .invalid
 
cmp dword [edx], SOL_SOCKET
cmp [edx + socket_options.level], IP_PROTO_IP
je .ip
cmp [edx + socket_options.level], SOL_SOCKET
jne .invalid
 
cmp dword [edx+4], SO_BINDTODEVICE
je .bind
.socket:
cmp [edx + socket_options.optname], SO_BINDTODEVICE
jne .invalid
 
.invalid:
mov dword[esp+32], -1
mov dword[esp+20], EINVAL
ret
 
.bind:
cmp dword[edx+8], 0
cmp [edx + socket_options.optlen], 0
je .unbind
 
movzx edx, byte[edx + 12]
movzx edx, byte[edx + socket_options.optval]
cmp edx, NET_DEVICES_MAX
ja .invalid
 
1180,14 → 1192,30
mov dword[esp+32], 0 ; success!
ret
 
.ip:
cmp [edx + socket_options.optname], IP_TTL
jne .invalid
 
.ttl:
mov bl, byte[edx + socket_options.optval]
mov [eax + IP_SOCKET.ttl], bl
 
mov dword[esp+32], 0 ; success!
ret
 
.already:
mov dword[esp+20], EALREADY
mov dword[esp+32], -1
ret
 
.invalid:
mov dword[esp+20], EINVAL
mov dword[esp+32], -1
ret
 
 
 
 
;-----------------------------------------------------------------
;
; SOCKET_pair
1474,6 → 1502,7
call mutex_unlock
popa
 
add esp, 8
call NET_BUFF_free
ret
 
/kernel/trunk/network/stack.inc
53,7 → 53,13
IP_PROTO_ICMP = 1
IP_PROTO_TCP = 6
IP_PROTO_UDP = 17
IP_PROTO_RAW = 255
 
; IP options
IP_TOS = 1
IP_TTL = 2
IP_HDRINCL = 3
 
; PPP protocol numbers
PPP_PROTO_IPv4 = 0x2100
PPP_PROTO_IPV6 = 0x5780
71,6 → 77,9
SOCK_DGRAM = 2
SOCK_RAW = 3
 
; Socket level
SOL_SOCKET = 0xffff
 
; Socket options
SO_ACCEPTCON = 1 shl 0
SO_BROADCAST = 1 shl 1
89,10 → 98,6
MSG_PEEK = 0x02
MSG_DONTWAIT = 0x40
 
; Socket level
SOL_SOCKET = 0
 
 
; Socket States
SS_NOFDREF = 0x0001 ; no file table ref any more
SS_ISCONNECTED = 0x0002 ; socket connected to a peer
/kernel/trunk/network/tcp_input.inc
24,9 → 24,10
;
; IN: [esp] = ptr to buffer
; ebx = ptr to device struct
; ecx = segment size
; ecx = TCP segment size
; edx = ptr to IPv4 header
; esi = ptr to TCP segment
; edi = ptr to ipv4 source address, followed by ipv4 dest address
; edi = interface number*4
;
; OUT: /
;
37,13 → 38,14
 
; record the current time
push [timer_ticks] ; in 1/100 seconds
push ebx ecx esi edi ; mind the order (see TCP_queue_entry struct)
push ebx ecx esi edx ; mind the order (see TCP_queue_entry struct)
mov esi, esp
 
push edi
add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail
pop edi
add esp, sizeof.TCP_queue_entry
 
call NET_ptr_to_num4
inc [TCP_segments_rx + edi]
 
xor edx, edx
55,6 → 57,7
ret
 
.fail:
pop edi
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n"
 
call NET_ptr_to_num4
94,7 → 97,7
 
mov ebx, [esi + TCP_queue_entry.device_ptr]
mov ecx, [esi + TCP_queue_entry.segment_size]
mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 source address, followed by ipv4 destination address
mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 header
mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last
 
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: size=%u time=%d\n", ecx, [timer_ticks]
111,7 → 114,7
push ecx esi
pushw [esi + TCP_header.Checksum]
mov [esi + TCP_header.Checksum], 0
TCP_checksum (edi), (edi+4)
TCP_checksum (edi+IPv4_header.SourceAddress), (edi+IPv4_header.DestinationAddress)
pop cx ; previous checksum
cmp cx, dx
pop edx ecx
170,7 → 173,7
jne .socket_loop
 
mov eax, [ebx + IP_SOCKET.RemoteIP]
cmp eax, [edi] ; Ipv4 source address
cmp eax, [edi + IPv4_header.SourceAddress]
je @f
test eax, eax
jnz .socket_loop
233,7 → 236,7
call mutex_unlock
popa
 
push ecx edx esi edi ;;;
push ecx edx esi edi
call SOCKET_fork
pop edi esi edx ecx
 
244,7 → 247,7
 
mov [temp_bits], TCP_BIT_DROPSOCKET
 
push dword [edi + 4] ; Ipv4 destination addres
push [edi + IPv4_header.DestinationAddress]
pop [ebx + IP_SOCKET.LocalIP]
 
push [edx + TCP_header.DestinationPort]
1211,7 → 1214,7
 
;;; TODO: check if it's a broadcast or multicast, and drop if so
 
push dword [edi] ; Ipv4 source addres
push [edi + IPv4_header.SourceAddress]
pop [ebx + IP_SOCKET.RemoteIP]
 
push [edx + TCP_header.SourcePort]
1673,11 → 1676,13
 
.respond_seg_ack:
mov cl, TH_RST
xor ebx, ebx ; FIXME: find a way to get the receiving device ptr
call TCP_respond_segment
jmp .drop_no_socket
 
.respond_seg_syn:
mov cl, TH_RST + TH_ACK
xor ebx, ebx ; FIXME: find a way to get the receiving device ptr
call TCP_respond_segment
jmp .drop_no_socket
 
/kernel/trunk/network/tcp_output.inc
503,10 → 503,11
; Create the IP packet
 
mov ecx, esi
mov ebx, [eax + IP_SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip
mov ebx, [eax + IP_SOCKET.device]
mov eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
mov di, IP_PROTO_TCP shl 8 + 128
mov edi, [eax + IP_SOCKET.RemoteIP] ; dest ip
mov al, [eax + IP_SOCKET.ttl]
mov ah, IP_PROTO_TCP
call IPv4_output
jz .ip_error
 
/kernel/trunk/network/tcp_subr.inc
266,7 → 266,7
 
 
 
;---------------------------------------
;-----------------------------------------------------------------
;
; The fast way to send an ACK/RST/keepalive segment
;
275,7 → 275,10
; IN: ebx = socket ptr
; cl = flags
;
;--------------------------------------
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
TCP_respond:
 
285,11 → 288,12
; Create the IP packet
 
push cx ebx
mov eax, [ebx + IP_SOCKET.RemoteIP]
mov edx, [ebx + IP_SOCKET.LocalIP]
mov edi, [ebx + IP_SOCKET.RemoteIP]
mov al, [ebx + IP_SOCKET.ttl]
mov ah, IP_PROTO_TCP
mov ecx, sizeof.TCP_header
mov ebx, [ebx + IP_SOCKET.device]
mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128
call IPv4_output
jz .error
pop esi cx
347,18 → 351,18
ret
 
 
 
 
 
 
 
 
;-------------------------
;-----------------------------------------------------------------
;
; TCP_respond_segment:
;
; IN: edx = segment ptr (a previously received segment)
; edi = ptr to dest and src IPv4 addresses
; IN: ebx = device ptr
; edx = segment ptr (a previously received segment)
; edi = ptr to IPv4 header
; cl = flags
;
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
TCP_respond_segment:
369,11 → 373,10
; Create the IP packet
 
push cx edx
mov edx, [edi + 4]
mov eax, [edi]
mov edx, [edi + IPv4_header.DestinationAddress]
mov edi, [edi + IPv4_header.SourceAddress]
mov ecx, sizeof.TCP_header
mov di, IP_PROTO_TCP shl 8 + 128
xor ebx, ebx ;;; fixme
mov ax, IP_PROTO_TCP shl 8 + 128
call IPv4_output
jz .error
pop esi cx
/kernel/trunk/network/udp.inc
57,15 → 57,15
; Pseudoheader
mov edx, IP_PROTO_UDP
 
add dl, [IP1+1]
adc dh, [IP1+0]
adc dl, [IP1+3]
adc dh, [IP1+2]
add dl, byte[IP1+1]
adc dh, byte[IP1+0]
adc dl, byte[IP1+3]
adc dh, byte[IP1+2]
 
adc dl, [IP2+1]
adc dh, [IP2+0]
adc dl, [IP2+3]
adc dh, [IP2+2]
adc dl, byte[IP2+1]
adc dh, byte[IP2+0]
adc dl, byte[IP2+3]
adc dh, byte[IP2+2]
 
adc dl, cl ; byte[esi+UDP_header.Length+1]
adc dh, ch ; byte[esi+UDP_header.Length+0]
103,14 → 103,14
; UDP_input:
;
; Called by IPv4_input,
; this procedure will inject the udp data diagrams in the application sockets.
; this procedure will inject the UDP data in the application sockets.
;
; IN: [esp] = Pointer to buffer
; [esp+4] = size of buffer
; IN: [esp] = ptr to buffer
; ebx = ptr to device struct
; ecx = UDP Packet size
; esi = ptr to UDP header
; edi = ptr to ipv4 source and dest address
; ecx = UDP packet size
; edx = ptr to IPv4 header
; esi = ptr to UDP packet data
; edi = interface number*4
;
; OUT: /
;
127,7 → 127,8
 
; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
 
UDP_checksum (edi), (edi+4)
mov eax, edx
UDP_checksum (eax+IPv4_header.SourceAddress), (eax+IPv4_header.DestinationAddress)
jnz .checksum_mismatch
 
.no_checksum:
148,9 → 149,7
 
mov cx, [esi + UDP_header.SourcePort]
mov dx, [esi + UDP_header.DestinationPort]
mov edi, [edi + 4] ; ipv4 source address
mov eax, net_sockets
 
.next_socket:
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
172,15 → 171,15
call mutex_unlock
popa
 
;;; TODO: when packet is processed, check more sockets!
;;; TODO: when packet is processed, check more sockets?!
 
; FIXME: check remote IP if possible
;
; cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
; je @f
; cmp [eax + IP_SOCKET.RemoteIP], edi
; cmp [eax + IP_SOCKET.RemoteIP],
; jne .next_socket
; @@:
;
; FIXME: UDP should check remote IP, but not under all circumstances!
 
cmp [eax + UDP_SOCKET.RemotePort], 0
je .updateport
194,7 → 193,6
popa
 
.updatesock:
call NET_ptr_to_num4
inc [UDP_PACKETS_RX + edi]
 
movzx ecx, [esi + UDP_header.Length]
257,10 → 255,11
 
sub esp, 4 ; Data ptr will be placed here
push edx esi
mov ebx, [eax + IP_SOCKET.device]
mov edx, [eax + IP_SOCKET.LocalIP]
mov ebx, [eax + IP_SOCKET.device]
mov eax, [eax + IP_SOCKET.RemoteIP]
mov di, IP_PROTO_UDP shl 8 + 128
mov edi, [eax + IP_SOCKET.RemoteIP]
mov al, [eax + IP_SOCKET.ttl]
mov ah, IP_PROTO_UDP
add ecx, sizeof.UDP_header
call IPv4_output
jz .fail
348,10 → 347,6
@@:
 
push eax
init_queue (eax + SOCKET_QUEUE_LOCATION) ; Set up data receiving queue
pop eax
 
push eax
lea ecx, [eax + SOCKET.mutex]
call mutex_unlock
pop eax
/programs/network/icmp/icmp.inc
1,77 → 1,75
; ICMP types & codes
 
ICMP_ECHOREPLY equ 0 ; echo reply message
ICMP_ECHOREPLY = 0 ; echo reply message
 
ICMP_UNREACH equ 3
ICMP_UNREACH_NET equ 0 ; bad net
ICMP_UNREACH_HOST equ 1 ; bad host
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol
ICMP_UNREACH_PORT equ 3 ; bad port
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio.
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff
ICMP_UNREACH = 3
ICMP_UNREACH_NET = 0 ; bad net
ICMP_UNREACH_HOST = 1 ; bad host
ICMP_UNREACH_PROTOCOL = 2 ; bad protocol
ICMP_UNREACH_PORT = 3 ; bad port
ICMP_UNREACH_NEEDFRAG = 4 ; IP_DF caused drop
ICMP_UNREACH_SRCFAIL = 5 ; src route failed
ICMP_UNREACH_NET_UNKNOWN = 6 ; unknown net
ICMP_UNREACH_HOST_UNKNOWN = 7 ; unknown host
ICMP_UNREACH_ISOLATED = 8 ; src host isolated
ICMP_UNREACH_NET_PROHIB = 9 ; prohibited access
ICMP_UNREACH_HOST_PROHIB = 10 ; ditto
ICMP_UNREACH_TOSNET = 11 ; bad tos for net
ICMP_UNREACH_TOSHOST = 12 ; bad tos for host
ICMP_UNREACH_FILTER_PROHIB = 13 ; admin prohib
ICMP_UNREACH_HOST_PRECEDENCE = 14 ; host prec vio.
ICMP_UNREACH_PRECEDENCE_CUTOFF = 15 ; prec cutoff
 
ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down
ICMP_SOURCEQUENCH = 4 ; Packet lost, slow down
 
ICMP_REDIRECT equ 5 ; shorter route, codes:
ICMP_REDIRECT_NET equ 0 ; for network
ICMP_REDIRECT_HOST equ 1 ; for host
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host
ICMP_REDIRECT = 5 ; shorter route, codes:
ICMP_REDIRECT_NET = 0 ; for network
ICMP_REDIRECT_HOST = 1 ; for host
ICMP_REDIRECT_TOSNET = 2 ; for tos and net
ICMP_REDIRECT_TOSHOST = 3 ; for tos and host
 
ICMP_ALTHOSTADDR equ 6 ; alternate host address
ICMP_ECHO equ 8 ; echo service
ICMP_ROUTERADVERT equ 9 ; router advertisement
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing
ICMP_ALTHOSTADDR = 6 ; alternate host address
ICMP_ECHO = 8 ; echo service
ICMP_ROUTERADVERT = 9 ; router advertisement
ICMP_ROUTERADVERT_NORMAL = 0 ; normal advertisement
ICMP_ROUTERADVERT_NOROUTE_COMMON = 16 ; selective routing
 
ICMP_ROUTERSOLICIT equ 10 ; router solicitation
ICMP_TIMXCEED equ 11 ; time exceeded, code:
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass
ICMP_ROUTERSOLICIT = 10 ; router solicitation
ICMP_TIMXCEED = 11 ; time exceeded, code:
ICMP_TIMXCEED_INTRANS = 0 ; ttl==0 in transit
ICMP_TIMXCEED_REASS = 1 ; ttl==0 in reass
 
ICMP_PARAMPROB equ 12 ; ip header bad
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent
ICMP_PARAMPROB_LENGTH equ 2 ; bad length
ICMP_PARAMPROB = 12 ; ip header bad
ICMP_PARAMPROB_ERRATPTR = 0 ; error at param ptr
ICMP_PARAMPROB_OPTABSENT = 1 ; req. opt. absent
ICMP_PARAMPROB_LENGTH = 2 ; bad length
 
ICMP_TSTAMP equ 13 ; timestamp request
ICMP_TSTAMPREPLY equ 14 ; timestamp reply
ICMP_IREQ equ 15 ; information request
ICMP_IREQREPLY equ 16 ; information reply
ICMP_MASKREQ equ 17 ; address mask request
ICMP_MASKREPLY equ 18 ; address mask reply
ICMP_TRACEROUTE equ 30 ; traceroute
ICMP_DATACONVERR equ 31 ; data conversion error
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply
ICMP_SKIP equ 39 ; SKIP
ICMP_TSTAMP = 13 ; timestamp r= est
ICMP_TSTAMPREPLY = 14 ; timestamp reply
ICMP_IREQ = 15 ; information r= est
ICMP_IREQREPLY = 16 ; information reply
ICMP_MASKREQ = 17 ; address mask r= est
ICMP_MASKREPLY = 18 ; address mask reply
ICMP_TRACEROUTE = 30 ; traceroute
ICMP_DATACONVERR = 31 ; data conversion error
ICMP_MOBILE_REDIRECT = 32 ; mobile host redirect
ICMP_IPV6_WHEREAREYOU = 33 ; IPv6 where-are-you
ICMP_IPV6_IAMHERE = 34 ; IPv6 i-am-here
ICMP_MOBILE_REGREQUEST = 35 ; mobile registration req
ICMP_MOBILE_REGREPLY = 36 ; mobile registreation reply
ICMP_SKIP = 39 ; SKIP
 
ICMP_PHOTURIS equ 40 ; Photuris
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
ICMP_PHOTURIS = 40 ; Photuris
ICMP_PHOTURIS_UNKNOWN_INDEX = 1 ; unknown sec index
ICMP_PHOTURIS_AUTH_FAILED = 2 ; auth failed
ICMP_PHOTURIS_DECRYPT_FAILED = 3 ; decrypt failed
 
 
 
virtual at 0
ICMP_Packet:
.Type db ?
.Code db ?
.Checksum dw ?
.Identifier dw ?
.SequenceNumber dw ?
.Data:
end virtual
struct ICMP_header
Type db ?
Code db ?
Checksum dw ?
Identifier dw ?
SequenceNumber dw ?
ends
/programs/network/icmp/ping.asm
12,8 → 12,6
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; TODO: ttl, user selectable size/number of packets
 
format binary as ""
 
BUFFERSIZE = 1500
28,7 → 26,7
dd I_END ; initialized size
dd IM_END+0x1000 ; required memory
dd IM_END+0x1000 ; stack pointer
dd s ; parameters
dd params ; parameters
dd 0 ; path
 
include '../../proc32.inc'
35,9 → 33,11
include '../../macros.inc'
purge mov,add,sub
include '../../dll.inc'
include '../../struct.inc'
include '../../network.inc'
 
include 'icmp.inc'
include 'ip.inc'
 
 
START:
53,13 → 53,28
push 1
call [con_start]
push title
push 25
push 250
push 80
push 25
push 80
call [con_init]
; expand payload to 65504 bytes
mov edi, icmp_packet.data+32
mov ecx, 65504/32-1
.expand_payload:
mov esi, icmp_packet.data
movsd
movsd
movsd
movsd
movsd
movsd
movsd
movsd
dec ecx
jnz .expand_payload
; main loop
cmp byte[s], 0
cmp byte[params], 0
jne parse_param
 
push str_welcome
69,8 → 84,8
push str_prompt
call [con_write_asciiz]
; read string
mov esi, s
push 256
mov esi, params
push 1024
push esi
call [con_gets]
; check for exit
93,10 → 108,14
mov [stats.time], 0
 
parse_param:
mov [count], 4 ; default number of pings to send
; parameters defaults
mov [count], 4
mov [size], 32
mov [ttl], 128
mov [timeout], 300
 
; Check if any additional parameters were given
mov esi, s
mov esi, params
mov ecx, 1024
.addrloop:
lodsb
123,6 → 142,42
mov [count], -1 ; infinite
jmp .param_loop
@@:
cmp al, 'n'
jne @f
call ascii_to_dec
test ebx, ebx
jz .invalid
mov [count], ebx
jmp .param_loop
@@:
cmp al, 'l'
jne @f
call ascii_to_dec
test ebx, ebx
jz .invalid
cmp ebx, 65500
ja .invalid
mov [size], ebx
jmp .param_loop
@@:
cmp al, 'i'
jne @f
call ascii_to_dec
test ebx, ebx
jz .invalid
cmp ebx, 255
ja .invalid
mov [ttl], ebx
jmp .param_loop
@@:
cmp al, 'w'
jne @f
call ascii_to_dec
test ebx, ebx
jz .invalid
mov [timeout], ebx
jmp .param_loop
@@:
; implement more parameters here
.invalid:
push str13
135,7 → 190,7
push esp ; fourth parameter
push 0 ; third parameter
push 0 ; second parameter
push s ; first parameter
push params ; first parameter
call [getaddrinfo]
pop esi
; test for error
166,9 → 221,19
mov [socketnum], eax
 
mcall connect, [socketnum], sockaddr1, 18
cmp eax, -1
je fail2
 
pushd [ttl]
pushd 4 ; length of option
pushd IP_TTL
pushd IPPROTO_IP
mcall setsockopt, [socketnum], esp
add esp, 16
cmp eax, -1
je fail2
 
mcall 40, EVM_STACK
; call [con_cls]
 
push str3
call [con_write_asciiz]
176,9 → 241,10
push [ip_ptr]
call [con_write_asciiz]
 
push (icmp_packet.length - ICMP_Packet.Data)
push [size]
push str3b
call [con_printf]
add esp, 2*4
 
mainloop:
call [con_get_flags]
188,9 → 254,14
inc [stats.tx]
mcall 26, 10 ; Get high precision timer count
mov [time_reference], eax
mcall send, [socketnum], icmp_packet, icmp_packet.length, 0
mov esi, [size]
add esi, sizeof.ICMP_header
xor edi, edi
mcall send, [socketnum], icmp_packet
cmp eax, -1
je fail2
 
mcall 23, 300 ; 3 seconds time-out
mcall 23, [timeout]
mcall 26, 10 ; Get high precision timer count
sub eax, [time_reference]
jz @f
203,54 → 274,102
@@:
mov [time_reference], eax
 
; Receive reply
mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, MSG_DONTWAIT
cmp eax, -1
je .no_response
test eax, eax
jz fail2
 
sub eax, ICMP_Packet.Data
; IP header length
movzx esi, byte[buffer_ptr]
and esi, 0xf
shl esi, 2
 
; Check packet length
sub eax, esi
sub eax, sizeof.ICMP_header
jb .invalid
mov [recvd], eax
 
cmp word[buffer_ptr + ICMP_Packet.Identifier], IDENTIFIER
jne .invalid
; make esi point to ICMP packet header
add esi, buffer_ptr
 
; OK, we have a response, update stats and let the user know
inc [stats.rx]
mov eax, [time_reference]
add [stats.time], eax
; we have a response, print the sender IP
push esi
mov eax, [buffer_ptr + IPv4_header.SourceAddress]
rol eax, 16
movzx ebx, ah
push ebx
movzx ebx, al
push ebx
shr eax, 16
movzx ebx, ah
push ebx
movzx ebx, al
push ebx
push str11
call [con_printf]
add esp, 5*4
pop esi
 
push str11 ; TODO: print IP address of packet sender
call [con_write_asciiz]
; What kind of response is it?
cmp [esi + ICMP_header.Type], ICMP_ECHOREPLY
je .echo_reply
cmp [esi + ICMP_header.Type], ICMP_TIMXCEED
je .ttl_exceeded
 
; validate the packet
lea esi, [buffer_ptr + ICMP_Packet.Data]
mov ecx, [recvd]
jmp .invalid
 
 
.echo_reply:
 
cmp [esi + ICMP_header.Identifier], IDENTIFIER
jne .invalid
 
; Validate the packet
add esi, sizeof.ICMP_header
mov ecx, [size]
mov edi, icmp_packet.data
repe cmpsb
jne .miscomp
 
; All OK, print to the user!
; update stats
inc [stats.rx]
mov eax, [time_reference]
add [stats.time], eax
 
movzx eax, [buffer_ptr + IPv4_header.TimeToLive]
push eax
mov eax, [time_reference]
xor edx, edx
mov ebx, 10
div ebx
push edx
push eax
; movzx eax, word[buffer_ptr + ICMP_Packet.SequenceNumber]
; push eax
push [recvd]
 
push str7
call [con_printf]
add esp, 5*4
 
jmp .continue
 
 
.ttl_exceeded:
push str14
call [con_write_asciiz]
 
jmp .continue
 
 
; Error in packet, print it to user
.miscomp:
sub edi, icmp_packet.data
sub edi, icmp_packet.data+1
push edi
push str9
call [con_printf]
add esp, 2*4
jmp .continue
 
; Invalid reply
271,14 → 390,14
cmp [count], -1
je .forever
dec [count]
jz done
jz .stats
.forever:
mcall 5, 100 ; wait a second
 
; wait a second before sending next request
mcall 5, 100
jmp mainloop
 
; Done..
done:
; Print statistics
.stats:
cmp [stats.rx], 0
jne @f
xor eax, eax
298,6 → 417,7
push [stats.tx]
push str12
call [con_printf]
add esp, 5*4
jmp main
 
; DNS error
320,10 → 440,46
mcall -1
 
 
ascii_to_dec:
 
lodsb
cmp al, ' '
jne .fail
 
xor eax, eax
xor ebx, ebx
.loop:
lodsb
test al, al
jz .done
cmp al, ' '
je .done
sub al, '0'
jb .fail
cmp al, 9
ja .fail
lea ebx, [ebx*4+ebx]
lea ebx, [ebx*2+eax]
jmp .loop
.fail:
xor ebx, ebx
.done:
dec esi
ret
 
 
 
 
; data
title db 'ICMP echo (ping) client',0
str_welcome db 'Please enter the hostname or IP-address of the host you want to ping,',10
db 'or just press enter to exit.',10,0
db 'or just press enter to exit.',10,10
db 'Options:',10
db ' -t Send packets till users abort.',10
db ' -n number Number of requests to send.',10
db ' -i TTL Time to live.',10
db ' -l size Size of echo request.',10
db ' -w time-out Time-out in hundredths of a second.',10,0
str_prompt db 10,'> ',0
str3 db 'Pinging to ',0
str3b db ' with %u data bytes',10,0
330,14 → 486,15
 
str4 db 10,0
str5 db 'Name resolution failed.',10,0
str6 db 'Could not open socket',10,0
str6 db 'Socket error.',10,0
str13 db 'Invalid parameter(s)',10,0
 
str11 db 'Answer: ',0
str7 db 'bytes=%u time=%u.%u ms',10,0
str11 db 'Answer from %u.%u.%u.%u: ',0
str7 db 'bytes=%u time=%u.%u ms TTL=%u',10,0
str8 db 'Timeout',10,0
str9 db 'Miscompare at offset %u',10,0
str10 db 'Invalid reply',10,0
str9 db 'miscompare at offset %u.',10,0
str10 db 'invalid reply.',10,0
str14 db 'TTL expired.',10,0
 
str12 db 10,'Statistics:',10,'%u packets sent, %u packets received',10,'average response time=%u.%u ms',10,0
 
350,6 → 507,9
time_reference dd ?
ip_ptr dd ?
count dd ?
size dd ?
ttl dd ?
timeout dd ?
recvd dd ? ; received number of bytes in last packet
 
stats:
381,18 → 541,17
 
socketnum dd ?
 
icmp_packet db 8 ; type
icmp_packet db ICMP_ECHO ; type
db 0 ; code
dw 0 ;
dw 0 ; checksum
.id dw IDENTIFIER ; identifier
.seq dw 0x0000 ; sequence number
.data db 'abcdefghijklmnopqrstuvwxyz012345'
.length = $ - icmp_packet
 
I_END:
rb 65504-32
 
s db 0
rb 1024
buffer_ptr rb BUFFERSIZE
params rb 1024
buffer_ptr: rb BUFFERSIZE
 
IM_END:
/programs/network/zeroconf/zeroconf.asm
20,7 → 20,7
 
; CONFIGURATION
 
TIMEOUT = 3 ; in seconds
TIMEOUT = 5 ; in seconds
BUFFER = 1024 ; in bytes
DHCP_TRIES = 3 ; number of times to try contacting DHCP server
__DEBUG__ = 1 ; enable/disable
318,8 → 318,8
 
pushd [ebp + interface.number]
pushd 4 ; length of option
pushd 1 shl 9 ; SO_BINDTODEVICE
pushd 0 ; SOL_SOCKET
pushd SO_BINDTODEVICE
pushd SOL_SOCKET
mcall 75, 8, [ebp + interface.socketNum], esp
add esp, 16
cmp eax, -1
/programs/network.inc
11,12 → 11,16
IPPROTO_ICMP = 1
IPPROTO_TCP = 6
IPPROTO_UDP = 17
IPPROTO_RAW = 255
 
; IP options
IP_TTL = 2
 
; Address families
AF_UNSPEC = 0
AF_LOCAL = 1
AF_INET4 = 2 ; IPv4
AF_INET6 = 28 ; IPv6 (not supported yet)
AF_INET6 = 28 ; IPv6
 
PF_UNSPEC = AF_UNSPEC
PF_LOCAL = AF_LOCAL
46,6 → 50,12
MSG_PEEK = 0x02
MSG_DONTWAIT = 0x40
 
; Socket levels
SOL_SOCKET = 0xffff
 
; Socket options
SO_BINDTODEVICE = 1 shl 9
 
struct sockaddr_in
sin_family dw ? ; sa_family_t
sin_port dw ? ; in_port_t