/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 |