Rev 6915 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3545 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
7974 | hidnplayr | 3 | ;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;; |
3545 | hidnplayr | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; Part of the TCP/IP network stack for KolibriOS ;; |
||
7 | ;; ;; |
||
8 | ;; Written by hidnplayr@kolibrios.org ;; |
||
9 | ;; ;; |
||
5133 | hidnplayr | 10 | ;; Based on the algorithms used in 4.4BSD ;; |
3545 | hidnplayr | 11 | ;; ;; |
12 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
13 | ;; Version 2, June 1991 ;; |
||
14 | ;; ;; |
||
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
16 | |||
4850 | mario79 | 17 | $Revision: 7974 $ |
3545 | hidnplayr | 18 | |
6476 | hidnplayr | 19 | TCP_BIT_NEEDOUTPUT = 1 shl 0 |
20 | TCP_BIT_TIMESTAMP = 1 shl 1 |
||
21 | TCP_BIT_DROPSOCKET = 1 shl 2 |
||
22 | TCP_BIT_FIN_IS_ACKED = 1 shl 3 |
||
23 | |||
5976 | hidnplayr | 24 | ;-----------------------------------------------------------------; |
25 | ; ; |
||
26 | ; TCP_input: Add a segment to the incoming TCP queue. ; |
||
27 | ; ; |
||
28 | ; IN: [esp] = ptr to buffer ; |
||
29 | ; ebx = ptr to device struct ; |
||
30 | ; ecx = TCP segment size ; |
||
31 | ; edx = ptr to IPv4 header ; |
||
32 | ; esi = ptr to TCP segment ; |
||
33 | ; edi = interface number*4 ; |
||
34 | ; ; |
||
35 | ; OUT: / ; |
||
36 | ; ; |
||
37 | ;-----------------------------------------------------------------; |
||
3545 | hidnplayr | 38 | align 4 |
6011 | hidnplayr | 39 | tcp_input: |
6908 | ashmew2 | 40 | |
3545 | hidnplayr | 41 | ; record the current time |
5522 | hidnplayr | 42 | push [timer_ticks] ; in 1/100 seconds |
5842 | hidnplayr | 43 | push ebx ecx esi edx ; mind the order (see TCP_queue_entry struct) |
3545 | hidnplayr | 44 | mov esi, esp |
45 | |||
5842 | hidnplayr | 46 | push edi |
3545 | hidnplayr | 47 | add_to_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .fail |
5842 | hidnplayr | 48 | pop edi |
3545 | hidnplayr | 49 | add esp, sizeof.TCP_queue_entry |
50 | |||
3644 | hidnplayr | 51 | inc [TCP_segments_rx + edi] |
52 | |||
3545 | hidnplayr | 53 | xor edx, edx |
54 | mov eax, [TCP_input_event] |
||
55 | mov ebx, [eax + EVENT.id] |
||
56 | xor esi, esi |
||
57 | call raise_event |
||
58 | |||
59 | ret |
||
60 | |||
61 | .fail: |
||
5842 | hidnplayr | 62 | pop edi |
3556 | hidnplayr | 63 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP incoming queue is full, discarding packet!\n" |
3545 | hidnplayr | 64 | |
6011 | hidnplayr | 65 | call net_ptr_to_num4 |
3644 | hidnplayr | 66 | inc [TCP_segments_missed + edi] |
3545 | hidnplayr | 67 | |
5841 | hidnplayr | 68 | add esp, sizeof.TCP_queue_entry - 4 |
6011 | hidnplayr | 69 | call net_buff_free |
3545 | hidnplayr | 70 | ret |
71 | |||
72 | |||
6476 | hidnplayr | 73 | ;-----------------------------------------------------------------; |
74 | ; ; |
||
75 | ; TCP_process_input: Process segments from the incoming TCP queue.; |
||
76 | ; ; |
||
77 | ; IN: / ; |
||
78 | ; OUT: / ; |
||
79 | ; ; |
||
80 | ;-----------------------------------------------------------------; |
||
3545 | hidnplayr | 81 | align 4 |
6011 | hidnplayr | 82 | proc tcp_process_input |
3545 | hidnplayr | 83 | |
4339 | hidnplayr | 84 | locals |
85 | dataoffset dd ? |
||
4344 | hidnplayr | 86 | timestamp dd ? |
4347 | hidnplayr | 87 | temp_bits db ? |
6910 | hidnplayr | 88 | device dd ? |
4339 | hidnplayr | 89 | endl |
90 | |||
3545 | hidnplayr | 91 | xor esi, esi |
92 | mov ecx, MANUAL_DESTROY |
||
93 | call create_event |
||
94 | mov [TCP_input_event], eax |
||
95 | |||
96 | .wait: |
||
97 | mov eax, [TCP_input_event] |
||
98 | mov ebx, [eax + EVENT.id] |
||
99 | call wait_event |
||
100 | |||
101 | .loop: |
||
102 | get_from_queue TCP_queue, TCP_QUEUE_SIZE, sizeof.TCP_queue_entry, .wait |
||
103 | |||
104 | push [esi + TCP_queue_entry.timestamp] |
||
4344 | hidnplayr | 105 | pop [timestamp] |
3545 | hidnplayr | 106 | push [esi + TCP_queue_entry.buffer_ptr] |
107 | |||
108 | mov ebx, [esi + TCP_queue_entry.device_ptr] |
||
6910 | hidnplayr | 109 | mov [device], ebx |
3545 | hidnplayr | 110 | mov ecx, [esi + TCP_queue_entry.segment_size] |
6910 | hidnplayr | 111 | mov edi, [esi + TCP_queue_entry.ip_ptr] ; ptr to ipv4 header |
3545 | hidnplayr | 112 | mov esi, [esi + TCP_queue_entry.segment_ptr] ; change esi last |
113 | |||
6908 | ashmew2 | 114 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: size=%u time=%d\n", ecx, [timer_ticks] |
3545 | hidnplayr | 115 | |
116 | mov edx, esi |
||
117 | |||
6476 | hidnplayr | 118 | ; Verify the checksum (if not already done by hw) |
3545 | hidnplayr | 119 | |
4388 | hidnplayr | 120 | test [ebx + NET_DEVICE.hwacc], NET_HWACC_TCP_IPv4_IN |
121 | jnz .checksum_ok |
||
3545 | hidnplayr | 122 | |
123 | push ecx esi |
||
124 | pushw [esi + TCP_header.Checksum] |
||
125 | mov [esi + TCP_header.Checksum], 0 |
||
6011 | hidnplayr | 126 | tcp_checksum (edi+IPv4_header.SourceAddress), (edi+IPv4_header.DestinationAddress) |
5842 | hidnplayr | 127 | pop cx ; previous checksum |
3545 | hidnplayr | 128 | cmp cx, dx |
129 | pop edx ecx |
||
130 | jne .drop_no_socket |
||
131 | .checksum_ok: |
||
132 | |||
133 | ; Verify the data offset |
||
6476 | hidnplayr | 134 | |
4339 | hidnplayr | 135 | movzx eax, [edx + TCP_header.DataOffset] |
136 | and al, 0xf0 ; Calculate TCP segment header size (throwing away unused reserved bits in TCP header) |
||
137 | shr al, 2 |
||
138 | cmp al, sizeof.TCP_header ; Now see if it's at least the size of a standard TCP header |
||
139 | jb .drop_no_socket ; If not, drop the packet |
||
140 | mov [dataoffset], eax |
||
3545 | hidnplayr | 141 | |
142 | sub ecx, eax ; substract TCP header size from total segment size |
||
143 | jb .drop_no_socket ; If total segment size is less then the advertised header size, drop packet |
||
6908 | ashmew2 | 144 | DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_input: %u bytes of data\n", ecx |
3545 | hidnplayr | 145 | |
146 | ;------------------------------------------- |
||
147 | ; Convert Big-endian values to little endian |
||
148 | |||
149 | ntohd [edx + TCP_header.SequenceNumber] |
||
150 | ntohd [edx + TCP_header.AckNumber] |
||
151 | |||
152 | ntohw [edx + TCP_header.Window] |
||
153 | ntohw [edx + TCP_header.UrgentPointer] |
||
154 | |||
6476 | hidnplayr | 155 | ;----------------------------------------------------------------------------------- |
156 | ; |
||
3545 | hidnplayr | 157 | ; Find the socket pointer |
6476 | hidnplayr | 158 | ; |
159 | ;----------------------------------------------------------------------------------- |
||
3545 | hidnplayr | 160 | |
161 | ; IP Packet TCP Destination Port = local Port |
||
162 | ; (IP Packet SenderAddress = Remote IP) OR (Remote IP = 0) |
||
163 | ; (IP Packet TCP Source Port = remote Port) OR (remote Port = 0) |
||
164 | |||
165 | .findpcb: |
||
3647 | hidnplayr | 166 | pusha |
167 | mov ecx, socket_mutex |
||
168 | call mutex_lock |
||
169 | popa |
||
170 | |||
3545 | hidnplayr | 171 | mov ebx, net_sockets |
172 | mov si, [edx + TCP_header.DestinationPort] |
||
173 | |||
174 | .socket_loop: |
||
175 | mov ebx, [ebx + SOCKET.NextPtr] |
||
176 | or ebx, ebx |
||
3647 | hidnplayr | 177 | jz .no_socket ;respond_seg_reset |
3545 | hidnplayr | 178 | |
179 | cmp [ebx + SOCKET.Domain], AF_INET4 |
||
180 | jne .socket_loop |
||
181 | |||
182 | cmp [ebx + SOCKET.Protocol], IP_PROTO_TCP |
||
183 | jne .socket_loop |
||
184 | |||
185 | cmp [ebx + TCP_SOCKET.LocalPort], si |
||
186 | jne .socket_loop |
||
187 | |||
188 | mov eax, [ebx + IP_SOCKET.RemoteIP] |
||
5842 | hidnplayr | 189 | cmp eax, [edi + IPv4_header.SourceAddress] |
3545 | hidnplayr | 190 | je @f |
191 | test eax, eax |
||
192 | jnz .socket_loop |
||
193 | @@: |
||
194 | |||
195 | mov ax, [ebx + TCP_SOCKET.RemotePort] |
||
196 | cmp [edx + TCP_header.SourcePort], ax |
||
197 | je .found_socket |
||
198 | test ax, ax |
||
199 | jnz .socket_loop |
||
200 | .found_socket: ; ebx now contains the socketpointer |
||
3647 | hidnplayr |