Subversion Repositories Kolibri OS

Rev

Rev 914 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 914 Rev 2971
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;  TCP.INC                                                     ;;
6
;;  TCP.INC                                                     ;;
7
;;                                                              ;;
7
;;                                                              ;;
8
;;  TCP Processes for Menuet OS  TCP/IP stack                   ;;
8
;;  TCP Processes for Menuet OS  TCP/IP stack                   ;;
9
;;                                                              ;;
9
;;                                                              ;;
10
;;  Version 0.6  4th July 2004                                  ;;
-
 
11
;;                                                              ;;
-
 
12
;;  Copyright 2002 Mike Hibbett, mikeh@oceanfree.net            ;;
10
;;  Copyright 2002 Mike Hibbett, mikeh@oceanfree.net            ;;
13
;;                                                              ;;
11
;;                                                              ;;
14
;;  See file COPYING for details                                ;;
12
;;  See file COPYING for details                                ;;
15
;;  v0.6 : Added reset handling in the established state        ;;
13
;;  v0.6 : Added reset handling in the established state        ;;
16
;;         Added a timer per socket to allow delays when        ;;
14
;;         Added a timer per socket to allow delays when        ;;
17
;;         rx window gets below 1KB                             ;;
15
;;         rx window gets below 1KB                             ;;
18
;;                                                              ;;
16
;;                                                              ;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20
 
18
 
21
$Revision: 914 $
19
$Revision: 2971 $
22
 
20
 
23
 
21
 
24
; TCP TCB states
22
; TCP TCB states
25
TCB_LISTEN         equ        1
23
TCB_LISTEN         equ        1
26
TCB_SYN_SENT       equ        2
24
TCB_SYN_SENT       equ        2
27
TCB_SYN_RECEIVED   equ        3
25
TCB_SYN_RECEIVED   equ        3
28
TCB_ESTABLISHED    equ        4
26
TCB_ESTABLISHED    equ        4
29
TCB_FIN_WAIT_1     equ        5
27
TCB_FIN_WAIT_1     equ        5
30
TCB_FIN_WAIT_2     equ        6
28
TCB_FIN_WAIT_2     equ        6
31
TCB_CLOSE_WAIT     equ        7
29
TCB_CLOSE_WAIT     equ        7
32
TCB_CLOSING        equ        8
30
TCB_CLOSING        equ        8
33
TCB_LAST_ACK       equ        9
31
TCB_LAST_ACK       equ        9
34
TCB_TIMED_WAIT	   equ	      10
32
TCB_TIMED_WAIT	   equ	      10
35
TCB_CLOSED         equ        11
33
TCB_CLOSED         equ        11
36
 
34
 
37
TH_FIN	= 0x01
35
TH_FIN	= 0x01
38
TH_SYN	= 0x02
36
TH_SYN	= 0x02
39
TH_RST	= 0x04
37
TH_RST	= 0x04
40
TH_PUSH = 0x08
38
TH_PUSH = 0x08
41
TH_ACK	= 0x10
39
TH_ACK	= 0x10
42
TH_URG	= 0x20
40
TH_URG	= 0x20
43
 
41
 
44
TWOMSL              equ     10      ; # of secs to wait before closing socket
42
TWOMSL              equ     10      ; # of secs to wait before closing socket
45
 
43
 
46
TCP_RETRIES         equ         5               ; Number of times to resend a packet
44
TCP_RETRIES         equ         5               ; Number of times to resend a packet
47
TCP_TIMEOUT         equ         10              ; resend if not replied to in x hs
45
TCP_TIMEOUT         equ         10              ; resend if not replied to in x hs
48
 
46
 
49
;*******************************************************************
47
;*******************************************************************
50
;   Interface
48
;   Interface
51
;
49
;
52
;       tcp_tx_handler      Handles the TCP transmit queue
50
;       tcp_tx_handler      Handles the TCP transmit queue
53
;       tcp_rx              The protocol handler for received data
51
;       tcp_rx              The protocol handler for received data
54
;       buildTCPPacket      fills in the packet headers and data
52
;       buildTCPPacket      fills in the packet headers and data
55
;       tcpStateMachine     Main state machine for received TCP packets
53
;       tcpStateMachine     Main state machine for received TCP packets
56
;       tcp_tcb_handler     1s timer, to erase tcb's in TIME_WAIT state
54
;       tcp_tcb_handler     1s timer, to erase tcb's in TIME_WAIT state
57
;
55
;
58
;*******************************************************************
56
;*******************************************************************
59
 
57
 
60
 
58
 
61
;   TCP Payload ( Data field in IP datagram )
59
;   TCP Payload ( Data field in IP datagram )
62
;
60
;
63
;    0                   1                   2                   3
61
;    0                   1                   2                   3
64
;    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
62
;    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
65
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66
;20 |          Source Port          |       Destination Port        |
64
;20 |          Source Port          |       Destination Port        |
67
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68
;24 |                        Sequence Number                        |
66
;24 |                        Sequence Number                        |
69
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70
;28 |                    Acknowledgment Number                      |
68
;28 |                    Acknowledgment Number                      |
71
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72
;32 |  Data |           |U|A|P|R|S|F|                               |
70
;32 |  Data |           |U|A|P|R|S|F|                               |
73
;   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
71
;   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
74
;   |       |           |G|K|H|T|N|N|                               |
72
;   |       |           |G|K|H|T|N|N|                               |
75
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76
;36 |           Checksum            |         Urgent Pointer        |
74
;36 |           Checksum            |         Urgent Pointer        |
77
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
78
;40 |                    Options                    |    Padding    |
76
;40 |                    Options                    |    Padding    |
79
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80
;   |                             data
78
;   |                             data
81
 
79
 
82
 
80
 
83
struc TCP_PACKET
81
struc TCP_PACKET
84
{  .SourcePort       dw  ?  ;+00
82
{  .SourcePort       dw  ?  ;+00
85
   .DestinationPort  dw  ?  ;+02
83
   .DestinationPort  dw  ?  ;+02
86
   .SequenceNumber   dd  ?  ;+04
84
   .SequenceNumber   dd  ?  ;+04
87
   .AckNumber        dd  ?  ;+08
85
   .AckNumber        dd  ?  ;+08
88
   .DataOffset       db  ?  ;+12 - DataOffset[0-3 bits] and Reserved[4-7]
86
   .DataOffset       db  ?  ;+12 - DataOffset[0-3 bits] and Reserved[4-7]
89
   .Flags            db  ?  ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
87
   .Flags            db  ?  ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
90
   .Window           dw  ?  ;+14
88
   .Window           dw  ?  ;+14
91
   .Checksum         dw  ?  ;+16
89
   .Checksum         dw  ?  ;+16
92
   .UrgentPointer    dw  ?  ;+18
90
   .UrgentPointer    dw  ?  ;+18
93
   .Options          rb  3  ;+20
91
   .Options          rb  3  ;+20
94
   .Padding          db  ?  ;+23
92
   .Padding          db  ?  ;+23
95
   .Data             db  ?  ;+24
93
   .Data             db  ?  ;+24
96
}
94
}
97
 
95
 
98
virtual at 0
96
virtual at 0
99
  TCP_PACKET TCP_PACKET
97
  TCP_PACKET TCP_PACKET
100
end virtual
98
end virtual
101
 
99
 
102
 
100
 
103
 
101
 
104
;***************************************************************************
102
;***************************************************************************
105
;   Function
103
;   Function
106
;      tcp_tcb_handler
104
;      tcp_tcb_handler
107
;
105
;
108
;   Description
106
;   Description
109
;       Handles sockets in the timewait state, closing them
107
;       Handles sockets in the timewait state, closing them
110
;       when the TCB timer expires
108
;       when the TCB timer expires
111
;
109
;
112
;***************************************************************************
110
;***************************************************************************
113
 
111
 
114
proc tcp_tcb_handler stdcall uses ebx
112
proc tcp_tcb_handler stdcall uses ebx
115
    ; scan through all the sockets, decrementing active timers
113
    ; scan through all the sockets, decrementing active timers
116
 
114
 
117
	mov	ebx, net_sockets
115
	mov	ebx, net_sockets
118
 
116
 
119
	cmp	[ebx + SOCKET.NextPtr], 0
117
	cmp	[ebx + SOCKET.NextPtr], 0
120
	je	.exit
118
	je	.exit
121
	DEBUGF	1, "K : sockets:\n"
119
	;DEBUGF	1, "K : sockets:\n"
122
 
120
 
123
  .next_socket:
121
  .next_socket:
124
	mov	ebx, [ebx + SOCKET.NextPtr]
122
	mov	ebx, [ebx + SOCKET.NextPtr]
125
	or	ebx, ebx
123
	or	ebx, ebx
126
	jz	.exit
124
	jz	.exit
127
 
125
 
128
	DEBUGF	1, "K :   %x: %x-%x-%x-%u\n", ebx, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
126
	;DEBUGF	1, "K :   %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
129
 
127
 
130
	cmp	[ebx + SOCKET.TCBTimer], 0
128
	cmp	[ebx + SOCKET.TCBTimer], 0
131
	jne	.decrement_tcb
129
	jne	.decrement_tcb
132
	cmp	[ebx + SOCKET.wndsizeTimer], 0
130
	cmp	[ebx + SOCKET.wndsizeTimer], 0
133
	jne	.decrement_wnd
131
	jne	.decrement_wnd
134
	jmp	.next_socket
132
	jmp	.next_socket
135
 
133
 
136
  .decrement_tcb:
134
  .decrement_tcb:
137
    ; decrement it, delete socket if TCB timer = 0 & socket in timewait state
135
    ; decrement it, delete socket if TCB timer = 0 & socket in timewait state
138
	dec	[ebx + SOCKET.TCBTimer]
136
	dec	[ebx + SOCKET.TCBTimer]
139
	jnz	.next_socket
137
	jnz	.next_socket
140
 
138
 
141
	cmp	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
139
	cmp	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
142
	jne	.next_socket
140
	jne	.next_socket
143
 
141
 
144
	push	[ebx + SOCKET.PrevPtr]
142
	push	[ebx + SOCKET.PrevPtr]
145
	stdcall net_socket_free, ebx
143
	stdcall net_socket_free, ebx
146
	pop	ebx
144
	pop	ebx
147
	jmp	.next_socket
145
	jmp	.next_socket
148
 
146
 
149
  .decrement_wnd:
147
  .decrement_wnd:
150
    ; TODO - prove it works!
148
    ; TODO - prove it works!
151
	dec	[ebx + SOCKET.wndsizeTimer]
149
	dec	[ebx + SOCKET.wndsizeTimer]
152
	jmp	.next_socket
150
	jmp	.next_socket
153
 
151
 
154
  .exit:
152
  .exit:
155
    ret
153
    ret
156
endp
154
endp
157
 
155
 
158
 
156
 
159
;***************************************************************************
157
;***************************************************************************
160
;   Function
158
;   Function
161
;      tcp_tx_handler
159
;      tcp_tx_handler
162
;
160
;
163
;   Description
161
;   Description
164
;       Handles queued TCP data
162
;       Handles queued TCP data
165
;       This is a kernel function, called by stack_handler
163
;       This is a kernel function, called by stack_handler
166
;
164
;
167
;***************************************************************************
165
;***************************************************************************
168
 
166
 
169
proc tcp_tx_handler stdcall
167
proc tcp_tx_handler stdcall
170
    ; decrement all resend buffers timers. If they
168
    ; decrement all resend buffers timers. If they
171
    ; expire, queue them for sending, and restart the timer.
169
    ; expire, queue them for sending, and restart the timer.
172
    ; If the retries counter reach 0, delete the entry
170
    ; If the retries counter reach 0, delete the entry
173
 
171
 
174
    mov     esi, resendQ
172
    mov     esi, resendQ
175
    mov     ecx, 0
173
    mov     ecx, 0
176
 
174
 
177
  .next_resendq:
175
  .next_resendq:
178
    cmp     ecx, NUMRESENDENTRIES
176
    cmp     ecx, NUMRESENDENTRIES
179
	je	.exit		    ; None left
177
	je	.exit		    ; None left
180
	;cmp     [esi], byte 0xFF                                    ; XTODO: 0xff -> 0
-
 
181
	cmp	dword[esi + 4], 0
178
	cmp	dword[esi + 4], 0
182
	jne	@f		     ; found one
179
	jne	@f		     ; found one
183
    inc     ecx
180
    inc     ecx
184
	add	esi, 8
181
	add	esi, 8
185
	jmp	.next_resendq
182
	jmp	.next_resendq
186
 
183
 
187
    @@: ; we have one. decrement it's timer by 1
184
    @@: ; we have one. decrement it's timer by 1
188
	dec	word[esi + 2]
185
	dec	word[esi + 2]
189
	jz	@f
186
	jz	@f
190
    inc     ecx
187
    inc     ecx
191
	add	esi, 8
188
	add	esi, 8
192
	jmp	.next_resendq	    ; Timer not zero, so move on
189
	jmp	.next_resendq	    ; Timer not zero, so move on
193
 
190
 
194
    @@:
191
    @@:
195
	;mov     bl, 0xff                                             ; XTODO: bl -> ebx, 0xff -> 0
-
 
196
	xor	ebx, ebx
192
	xor	ebx, ebx
197
    ; restart timer, and decrement retries
193
    ; restart timer, and decrement retries
198
    ; After the first resend, back of on next, by a factor of 5
194
    ; After the first resend, back of on next, by a factor of 5
199
	mov	[esi + 2], word TCP_TIMEOUT * 5
195
	mov	[esi + 2], word TCP_TIMEOUT * 5
200
	dec	byte[esi + 1]
196
	dec	byte[esi + 1]
201
	jnz	@f
197
	jnz	@f
202
 
198
 
203
    ; retries now 0, so delete from queue
199
    ; retries now 0, so delete from queue
204
	;xchg     [esi], bl                                          ; XTODO: bl -> ebx
-
 
205
	xchg	 [esi + 4], ebx
200
	xchg	 [esi + 4], ebx
206
 
201
 
207
    @@: ; resend packet
202
    @@: ; resend packet
208
	pushad
203
	pushad
209
 
204
 
210
    mov     eax, EMPTY_QUEUE
205
    mov     eax, EMPTY_QUEUE
211
    call    dequeue
206
    call    dequeue
212
    cmp     ax, NO_BUFFER
207
    cmp     ax, NO_BUFFER
213
	jne	.tth004z
208
	jne	.tth004z
214
 
209
 
215
    ; TODO - try again in 10ms.
210
    ; TODO - try again in 10ms.
216
	;cmp     bl, 0xff                                            ; XTODO: 0xff -> 0
-
 
217
	test	ebx, ebx
211
	test	ebx, ebx
218
	jnz	@f
212
	jnz	@f
219
	;mov     [esi], bl                                            ; XTODO: bl -> ebx
-
 
220
	mov	[esi + 4], ebx
213
	mov	[esi + 4], ebx
221
 
214
 
222
    @@: ; Mark it to expire in 10ms - 1 tick
215
    @@: ; Mark it to expire in 10ms - 1 tick
223
	mov	byte[esi + 1], 1
216
	mov	byte[esi + 1], 1
224
	mov	word[esi + 2], 1
217
	mov	word[esi + 2], 1
225
	jmp	.tth005
218
	jmp	.tth005
226
 
219
 
227
  .tth004z:
220
  .tth004z:
228
    ; we have a buffer # in ax
221
    ; we have a buffer # in ax
229
 
222
 
230
	push	eax ecx
223
	push	eax ecx
231
    mov     ecx, IPBUFFSIZE
224
    mov     ecx, IPBUFFSIZE
232
    mul     ecx
225
    mul     ecx
233
    add     eax, IPbuffs
226
    add     eax, IPbuffs
234
 
227
 
235
    ; we have the buffer address in eax
228
    ; we have the buffer address in eax
236
    mov     edi, eax
229
    mov     edi, eax
237
    pop     ecx
230
    pop     ecx
238
    ; Now get buffer location, and copy buffer across. argh! more copying,,
231
    ; Now get buffer location, and copy buffer across. argh! more copying,,
239
	mov	esi, resendBuffer
232
	mov	esi, resendBuffer
240
    @@: add	esi, IPBUFFSIZE
233
    @@: add	esi, IPBUFFSIZE
241
	loop	@b
234
	loop	@b
242
 
235
 
243
    ; we have resend buffer location in esi
236
    ; we have resend buffer location in esi
244
    mov     ecx, IPBUFFSIZE
237
    mov     ecx, IPBUFFSIZE
245
 
238
 
246
    ; copy data across
239
    ; copy data across
247
	push	edi
240
	push	edi
248
    cld
241
    cld
249
    rep     movsb
242
    rep     movsb
250
	pop	edi
243
	pop	edi
251
 
244
 
252
    ; queue packet
245
    ; queue packet
253
 
246
 
254
 
247
 
255
 
248
 
256
    mov     eax, NET1OUT_QUEUE
249
    mov     eax, NET1OUT_QUEUE
257
 
250
 
258
    mov     edx, [stack_ip]
251
    mov     edx, [stack_ip]
259
	cmp	edx, [edi + IP_PACKET.DestinationAddress]
252
	cmp	edx, [edi + IP_PACKET.DestinationAddress]
260
	jne	.not_local
253
	jne	.not_local
261
    mov     eax, IPIN_QUEUE
254
    mov     eax, IPIN_QUEUE
262
 
255
 
263
  .not_local:
256
  .not_local:
264
    pop     ebx
257
    pop     ebx
265
 
258
 
266
    call    queue
259
    call    queue
267
 
260
 
268
  .tth005:
261
  .tth005:
269
	popad
262
	popad
270
 
263
 
271
    inc     ecx
264
    inc     ecx
272
	add	esi, 8
265
	add	esi, 8
273
	jmp	.next_resendq
266
	jmp	.next_resendq
274
 
267
 
275
  .exit:
268
  .exit:
276
    ret
269
    ret
277
endp
270
endp
278
 
271
 
279
 
272
 
280
;***************************************************************************
273
;***************************************************************************
281
;   Function
274
;   Function
282
;      tcp_rx
275
;      tcp_rx
283
;
276
;
284
;   Description
277
;   Description
285
;       TCP protocol handler
278
;       TCP protocol handler
286
;       This is a kernel function, called by ip_rx
279
;       This is a kernel function, called by ip_rx
287
;       IP buffer address given in edx
280
;       IP buffer address given in edx
288
;          IP buffer number in eax
281
;          IP buffer number in eax
289
;          Free up (or re-use) IP buffer when finished
282
;          Free up (or re-use) IP buffer when finished
290
;
283
;
291
;***************************************************************************
284
;***************************************************************************
292
 
285
 
293
proc tcp_rx stdcall uses ebx
286
proc tcp_rx stdcall uses ebx
294
    ; The process is as follows.
287
    ; The process is as follows.
295
    ; Look for a socket with matching remote IP, remote port, local port
288
    ; Look for a socket with matching remote IP, remote port, local port
296
    ; if not found, then
289
    ; if not found, then
297
    ; look for remote IP + local port match ( where sockets remote port = 0)
290
    ; look for remote IP + local port match ( where sockets remote port = 0)
298
    ; if not found, then
291
    ; if not found, then
299
    ; look for a socket where local socket port == IP packets remote port
292
    ; look for a socket where local socket port == IP packets remote port
300
    ; where sockets remote port, remote IP = 0
293
    ; where sockets remote port, remote IP = 0
301
    ; discard if not found
294
    ; discard if not found
302
    ; Call sockets tcbStateMachine, with pointer to packet.
295
    ; Call sockets tcbStateMachine, with pointer to packet.
303
    ; the state machine will not delete the packet, so do that here.
296
    ; the state machine will not delete the packet, so do that here.
304
 
297
 
305
    push        eax
298
    push        eax
306
 
299
 
307
    ; Look for a socket where
300
    ; Look for a socket where
308
    ; IP Packet TCP Destination Port = local Port
301
    ; IP Packet TCP Destination Port = local Port
309
    ; IP Packet SA = Remote IP
302
    ; IP Packet SA = Remote IP
310
    ; IP Packet TCP Source Port = remote Port
303
    ; IP Packet TCP Source Port = remote Port
311
 
304
 
312
	mov	ebx, net_sockets
305
	mov	ebx, net_sockets
313
 
306
 
314
  .next_socket.1:
307
  .next_socket.1:
315
	mov	ebx, [ebx + SOCKET.NextPtr]
308
	mov	ebx, [ebx + SOCKET.NextPtr]
316
	or	ebx, ebx
309
	or	ebx, ebx
317
	jz	.next_socket.1.exit
310
	jz	.next_socket.1.exit
318
 
-
 
319
	cmp	[ebx + SOCKET.Status], SOCK_OPEN
-
 
320
	jne	.next_socket.1
-
 
321
 
311
 
322
;        DEBUGF  1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
312
;        DEBUGF  1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
323
 
313
 
324
	mov	ax, [edx + 20 + TCP_PACKET.DestinationPort]  ; get the dest. port from the TCP hdr
314
	mov	ax, [edx + 20 + TCP_PACKET.DestinationPort]  ; get the dest. port from the TCP hdr
325
	cmp	[ebx + SOCKET.LocalPort], ax		; get the dest. port from the TCP hdr
315
	cmp	[ebx + SOCKET.LocalPort], ax		; get the dest. port from the TCP hdr
326
	jne	.next_socket.1				; different - try next socket
316
	jne	.next_socket.1				; different - try next socket
327
 
317
 
328
;        DEBUGF  1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
318
;        DEBUGF  1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
329
 
319
 
330
	mov	eax, [edx + IP_PACKET.SourceAddress]	; get the source IP Addr from the IP hdr
320
	mov	eax, [edx + IP_PACKET.SourceAddress]	; get the source IP Addr from the IP hdr
331
	cmp	[ebx + SOCKET.RemoteIP], eax		; compare with socket's remote IP
321
	cmp	[ebx + SOCKET.RemoteIP], eax		; compare with socket's remote IP
332
	jne	.next_socket.1				; different - try next socket
322
	jne	.next_socket.1				; different - try next socket
333
 
323
 
334
;        DEBUGF  1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_PACKET.SourcePort]:4, [ebx + SOCKET.RemotePort]:4
324
;        DEBUGF  1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_PACKET.SourcePort]:4, [ebx + SOCKET.RemotePort]:4
335
 
325
 
336
	mov	ax, [edx + 20 + TCP_PACKET.SourcePort]	; get the source port from the TCP hdr
326
	mov	ax, [edx + 20 + TCP_PACKET.SourcePort]	; get the source port from the TCP hdr
337
	cmp	[ebx + SOCKET.RemotePort], ax		; compare with socket's remote port
327
	cmp	[ebx + SOCKET.RemotePort], ax		; compare with socket's remote port
338
	jne	.next_socket.1				; different - try next socket
328
	jne	.next_socket.1				; different - try next socket
339
 
329
 
340
    ; We have a complete match - use this socket
330
    ; We have a complete match - use this socket
341
	jmp	.change_state
331
	jmp	.change_state
342
 
332
 
343
  .next_socket.1.exit:
333
  .next_socket.1.exit:
344
 
334
 
345
    ; If we got here, there was no match
335
    ; If we got here, there was no match
346
    ; Look for a socket where
336
    ; Look for a socket where
347
    ; IP Packet TCP Destination Port = local Port
337
    ; IP Packet TCP Destination Port = local Port
348
    ; IP Packet SA = Remote IP
338
    ; IP Packet SA = Remote IP
349
    ; socket remote Port = 0
339
    ; socket remote Port = 0
350
 
340
 
351
	mov	ebx, net_sockets
341
	mov	ebx, net_sockets
352
 
342
 
353
  .next_socket.2:
343
  .next_socket.2:
354
	mov	ebx, [ebx + SOCKET.NextPtr]
344
	mov	ebx, [ebx + SOCKET.NextPtr]
355
	or	ebx, ebx
345
	or	ebx, ebx
356
	jz	.next_socket.2.exit
346
	jz	.next_socket.2.exit
357
 
-
 
358
	cmp	[ebx + SOCKET.Status], SOCK_OPEN
-
 
359
	jne	.next_socket.2
-
 
360
 
347
 
361
;        DEBUGF  1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
348
;        DEBUGF  1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
362
 
349
 
363
	mov	ax, [edx + 20 + TCP_PACKET.DestinationPort]  ; get the dest. port from the TCP hdr
350
	mov	ax, [edx + 20 + TCP_PACKET.DestinationPort]  ; get the dest. port from the TCP hdr
364
	cmp	[ebx + SOCKET.LocalPort], ax		; compare with socket's local port
351
	cmp	[ebx + SOCKET.LocalPort], ax		; compare with socket's local port
365
	jne	.next_socket.2				; different - try next socket
352
	jne	.next_socket.2				; different - try next socket
366
 
353
 
367
;        DEBUGF  1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
354
;        DEBUGF  1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
368
 
355
 
369
	mov	eax, [edx + IP_PACKET.SourceAddress]	; get the source IP Addr from the IP hdr
356
	mov	eax, [edx + IP_PACKET.SourceAddress]	; get the source IP Addr from the IP hdr
370
	cmp	[ebx + SOCKET.RemoteIP], eax		; compare with socket's remote IP
357
	cmp	[ebx + SOCKET.RemoteIP], eax		; compare with socket's remote IP
371
	jne	.next_socket.2				; different - try next socket
358
	jne	.next_socket.2				; different - try next socket
372
 
359
 
373
;        DEBUGF  1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
360
;        DEBUGF  1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
374
 
361
 
375
	cmp	[ebx + SOCKET.RemotePort], 0		; only match a remote socket of 0
362
	cmp	[ebx + SOCKET.RemotePort], 0		; only match a remote socket of 0
376
	jne	.next_socket.2				; different - try next socket
363
	jne	.next_socket.2				; different - try next socket
377
 
364
 
378
    ; We have a complete match - use this socket
365
    ; We have a complete match - use this socket
379
	jmp	.change_state
366
	jmp	.change_state
380
 
367
 
381
  .next_socket.2.exit:
368
  .next_socket.2.exit:
382
 
369
 
383
    ; If we got here, there was no match
370
    ; If we got here, there was no match
384
    ; Look for a socket where
371
    ; Look for a socket where
385
    ; IP Packet TCP Destination Port = local Port
372
    ; IP Packet TCP Destination Port = local Port
386
    ; socket Remote IP = 0
373
    ; socket Remote IP = 0
387
    ; socket remote Port = 0
374
    ; socket remote Port = 0
388
 
375
 
389
	mov	ebx, net_sockets
376
	mov	ebx, net_sockets
390
 
377
 
391
  .next_socket.3:
378
  .next_socket.3:
392
	mov	ebx, [ebx + SOCKET.NextPtr]
379
	mov	ebx, [ebx + SOCKET.NextPtr]
393
	or	ebx, ebx
380
	or	ebx, ebx
394
	jz	.next_socket.3.exit
381
	jz	.next_socket.3.exit
395
 
-
 
396
	cmp	[ebx + SOCKET.Status], SOCK_OPEN
-
 
397
	jne	.next_socket.3
-
 
398
 
382
 
399
;        DEBUGF  1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
383
;        DEBUGF  1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
400
 
384
 
401
	mov	ax, [edx + 20 + TCP_PACKET.DestinationPort]  ; get destination port from the TCP hdr
385
	mov	ax, [edx + 20 + TCP_PACKET.DestinationPort]  ; get destination port from the TCP hdr
402
	cmp	[ebx + SOCKET.LocalPort], ax		; compare with socket's local port
386
	cmp	[ebx + SOCKET.LocalPort], ax		; compare with socket's local port
403
	jne	.next_socket.3				; different - try next socket
387
	jne	.next_socket.3				; different - try next socket
404
 
388
 
405
;        DEBUGF  1, "K : tcp_rx - 3.addr: 00000000 - %x\n", [ebx + SOCKET.RemoteIP]
389
;        DEBUGF  1, "K : tcp_rx - 3.addr: 00000000 - %x\n", [ebx + SOCKET.RemoteIP]
406
 
390
 
407
	cmp	[ebx + SOCKET.RemoteIP], 0		; only match a socket remote IP of 0
391
	cmp	[ebx + SOCKET.RemoteIP], 0		; only match a socket remote IP of 0
408
	jne	.next_socket.3				; different - try next socket
392
	jne	.next_socket.3				; different - try next socket
409
 
393
 
410
;        DEBUGF  1, "K : tcp_rx - 3.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
394
;        DEBUGF  1, "K : tcp_rx - 3.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
411
 
395
 
412
	cmp	[ebx + SOCKET.RemotePort], 0		; only match a remote socket of 0
396
	cmp	[ebx + SOCKET.RemotePort], 0		; only match a remote socket of 0
413
	jne	.next_socket.3				; different - try next socket
397
	jne	.next_socket.3				; different - try next socket
414
 
398
 
415
    ; We have a complete match - use this socket
399
    ; We have a complete match - use this socket
416
	jmp	.change_state
400
	jmp	.change_state
417
 
401
 
418
  .next_socket.3.exit:
402
  .next_socket.3.exit:
419
 
403
 
420
    ; If we got here, we need to reject the packet
404
    ; If we got here, we need to reject the packet
421
 
405
 
422
	DEBUGF	1, "K : tcp_rx - dumped\n"
406
	DEBUGF	1, "K : tcp_rx - dumped\n"
423
	DEBUGF	1, "K :   --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [edx + IP_PACKET.SourceAddress], [edx + 20 + TCP_PACKET.SourcePort]:4, [edx + 20 + TCP_PACKET.Flags]:2
407
	DEBUGF	1, "K :   --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [edx + IP_PACKET.SourceAddress], [edx + 20 + TCP_PACKET.SourcePort]:4, [edx + 20 + TCP_PACKET.Flags]:2
424
;       mov     ebx, net_sockets
-
 
425
;
408
 
426
; .next_socket.4:
-
 
427
;       mov     ebx, [ebx + SOCKET.NextPtr]
-
 
428
;       or      ebx, ebx
-
 
429
;       jz      .next_socket.4.exit
-
 
430
;       DEBUGF  1, "K :   %x: %x-%x-%x-%u\n", ebx, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
-
 
431
;       jne     .next_socket.4
-
 
432
;
-
 
433
; .next_socket.4.exit:
-
 
434
	inc	[dumped_rx_count]
409
	inc	[dumped_rx_count]
435
	jmp	.exit
410
	jmp	.exit
436
 
411
 
437
  .change_state:
412
  .change_state:
438
 
413
 
439
    ; We have a valid socket/TCB, so call the TCB State Machine for that skt.
414
    ; We have a valid socket/TCB, so call the TCB State Machine for that skt.
440
	; socket is pointed to by ebx
415
	; socket is pointed to by ebx
441
	; IP packet is pointed to by edx
416
	; IP packet is pointed to by edx
442
    ; IP buffer number is on stack ( it will be popped at the end)
417
    ; IP buffer number is on stack ( it will be popped at the end)
443
 
418
 
444
	stdcall tcpStateMachine, ebx
419
	stdcall tcpStateMachine, ebx
445
 
420
 
446
  .exit:
421
  .exit:
447
    pop     eax
422
    pop     eax
448
    call    freeBuff
423
    call    freeBuff
449
 
424
 
450
    ret
425
    ret
451
endp
426
endp
452
 
427
 
453
 
428
 
454
;***************************************************************************
429
;***************************************************************************
455
;   Function
430
;   Function
456
;      buildTCPPacket
431
;      buildTCPPacket
457
;
432
;
458
;   Description
433
;   Description
459
;       builds an IP Packet with TCP data fully populated for transmission
434
;       builds an IP Packet with TCP data fully populated for transmission
460
;       You may destroy any and all registers
435
;       You may destroy any and all registers
461
;          TCP control flags specified in bl
436
;          TCP control flags specified in bl
462
;          This TCB is in [sktAddr]
437
;          This TCB is in [sktAddr]
463
;          User data pointed to by esi
438
;          User data pointed to by esi
464
;       Data length in ecx
439
;       Data length in ecx
465
;          Transmit buffer number in eax
440
;          Transmit buffer number in eax
466
;
441
;
467
;***************************************************************************
442
;***************************************************************************
468
 
443
 
469
proc build_tcp_packet stdcall, sockAddr:DWORD
444
proc build_tcp_packet stdcall, sockAddr:DWORD
470
    push    ecx                        ; Save data length
445
    push    ecx                        ; Save data length
471
 
446
 
472
    ; convert buffer pointer eax to the absolute address
447
    ; convert buffer pointer eax to the absolute address
473
    mov     ecx, IPBUFFSIZE
448
    mov     ecx, IPBUFFSIZE
474
    mul     ecx
449
    mul     ecx
475
    add     eax, IPbuffs
450
    add     eax, IPbuffs
476
 
451
 
477
    mov     edx, eax
452
    mov     edx, eax
478
 
453
 
479
	mov	[edx + 20 + TCP_PACKET.Flags], bl		; TCP flags
454
	mov	[edx + 20 + TCP_PACKET.Flags], bl		; TCP flags
480
 
455
 
481
	mov	ebx, [sockAddr]
456
	mov	ebx, [sockAddr]
482
 
457
 
483
    ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
458
    ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
484
 
459
 
485
    ; Fill in the IP header ( some data is in the socket descriptor)
460
    ; Fill in the IP header ( some data is in the socket descriptor)
486
	mov	eax, [ebx + SOCKET.LocalIP]
461
	mov	eax, [ebx + SOCKET.LocalIP]
487
	mov	[edx + IP_PACKET.SourceAddress], eax
462
	mov	[edx + IP_PACKET.SourceAddress], eax
488
	mov	eax, [ebx + SOCKET.RemoteIP]
463
	mov	eax, [ebx + SOCKET.RemoteIP]
489
	mov	[edx + IP_PACKET.DestinationAddress], eax
464
	mov	[edx + IP_PACKET.DestinationAddress], eax
490
 
465
 
491
	mov	[edx + IP_PACKET.VersionAndIHL], 0x45
466
	mov	[edx + IP_PACKET.VersionAndIHL], 0x45
492
	mov	[edx + IP_PACKET.TypeOfService], 0
467
	mov	[edx + IP_PACKET.TypeOfService], 0
493
 
468
 
494
    pop     eax                   ; Get the TCP data length
469
    pop     eax                   ; Get the TCP data length
495
    push    eax
470
    push    eax
496
 
471
 
497
    add     eax, 20 + 20           ; add IP header and TCP header lengths
472
    add     eax, 20 + 20           ; add IP header and TCP header lengths
498
	rol	ax, 8
473
	rol	ax, 8
499
	mov	[edx + IP_PACKET.TotalLength], ax
474
	mov	[edx + IP_PACKET.TotalLength], ax
500
	mov	[edx + IP_PACKET.Identification], 0
475
	mov	[edx + IP_PACKET.Identification], 0
501
	mov	[edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040
476
	mov	[edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040
502
	mov	[edx + IP_PACKET.TimeToLive], 0x20
477
	mov	[edx + IP_PACKET.TimeToLive], 0x20
503
	mov	[edx + IP_PACKET.Protocol], PROTOCOL_TCP
478
	mov	[edx + IP_PACKET.Protocol], PROTOCOL_TCP
504
 
479
 
505
    ; Checksum left unfilled
480
    ; Checksum left unfilled
506
	mov	[edx + IP_PACKET.HeaderChecksum], 0
481
	mov	[edx + IP_PACKET.HeaderChecksum], 0
507
 
482
 
508
	; Fill in the TCP header (some data is in the socket descriptor)
483
	; Fill in the TCP header (some data is in the socket descriptor)
509
	mov	ax, [ebx + SOCKET.LocalPort]
484
	mov	ax, [ebx + SOCKET.LocalPort]
510
	mov	[edx + 20 + TCP_PACKET.SourcePort], ax		; Local Port
485
	mov	[edx + 20 + TCP_PACKET.SourcePort], ax		; Local Port
511
 
486
 
512
	mov	ax, [ebx + SOCKET.RemotePort]
487
	mov	ax, [ebx + SOCKET.RemotePort]
513
	mov	[edx + 20 + TCP_PACKET.DestinationPort], ax	; desitination Port
488
	mov	[edx + 20 + TCP_PACKET.DestinationPort], ax	; desitination Port
514
 
489
 
515
    ; Checksum left unfilled
490
    ; Checksum left unfilled
516
	mov	[edx + 20 + TCP_PACKET.Checksum], 0
491
	mov	[edx + 20 + TCP_PACKET.Checksum], 0
517
 
492
 
518
    ; sequence number
493
    ; sequence number
519
	mov	eax, [ebx + SOCKET.SND_NXT]
494
	mov	eax, [ebx + SOCKET.SND_NXT]
520
	mov	[edx + 20 + TCP_PACKET.SequenceNumber], eax
495
	mov	[edx + 20 + TCP_PACKET.SequenceNumber], eax
521
 
496
 
522
    ; ack number
497
    ; ack number
523
	mov	eax, [ebx + SOCKET.RCV_NXT]
498
	mov	eax, [ebx + SOCKET.RCV_NXT]
524
	mov	[edx + 20 + TCP_PACKET.AckNumber], eax
499
	mov	[edx + 20 + TCP_PACKET.AckNumber], eax
525
 
500
 
526
    ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size)
501
    ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size)
527
    ; 768 bytes seems better
502
    ; 768 bytes seems better
528
	mov	[edx + 20 + TCP_PACKET.Window], 0x0003
503
	mov	[edx + 20 + TCP_PACKET.Window], 0x0003
529
 
504
 
530
    ; Urgent pointer (0)
505
    ; Urgent pointer (0)
531
	mov	[edx + 20 + TCP_PACKET.UrgentPointer], 0
506
	mov	[edx + 20 + TCP_PACKET.UrgentPointer], 0
532
 
507
 
533
    ; data offset ( 0x50 )
508
    ; data offset ( 0x50 )
534
	mov	[edx + 20 + TCP_PACKET.DataOffset], 0x50
509
	mov	[edx + 20 + TCP_PACKET.DataOffset], 0x50
535
 
510
 
536
    pop     ecx                  ; count of bytes to send
511
    pop     ecx                  ; count of bytes to send
537
    mov     ebx, ecx            ; need the length later
512
    mov     ebx, ecx            ; need the length later
538
 
513
 
539
    cmp     ebx, 0
514
    cmp     ebx, 0
540
	jz	@f
515
	jz	@f
541
 
516
 
542
    mov     edi, edx
517
    mov     edi, edx
543
    add     edi, 40
518
    add     edi, 40
544
    cld
519
    cld
545
    rep     movsb               ; copy the data across
520
    rep     movsb               ; copy the data across
546
 
521
 
547
    @@: ; we have edx as IPbuffer ptr.
522
    @@: ; we have edx as IPbuffer ptr.
548
    ; Fill in the TCP checksum
523
    ; Fill in the TCP checksum
549
    ; First, fill in pseudoheader
524
    ; First, fill in pseudoheader
550
	mov	eax, [edx + IP_PACKET.SourceAddress]
525
	mov	eax, [edx + IP_PACKET.SourceAddress]
551
    mov     [pseudoHeader], eax
526
    mov     [pseudoHeader], eax
552
	mov	eax, [edx + IP_PACKET.DestinationAddress]
527
	mov	eax, [edx + IP_PACKET.DestinationAddress]
553
	mov	[pseudoHeader + 4], eax
528
	mov	[pseudoHeader + 4], eax
554
	mov	word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
529
	mov	word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
555
    add     ebx, 20
530
    add     ebx, 20
556
	mov	[pseudoHeader + 10], bh
531
	mov	[pseudoHeader + 10], bh
557
	mov	[pseudoHeader + 11], bl
532
	mov	[pseudoHeader + 11], bl
558
 
533
 
559
    mov     eax, pseudoHeader
534
    mov     eax, pseudoHeader
560
    mov     [checkAdd1], eax
535
    mov     [checkAdd1], eax
561
	mov	word[checkSize1], 12
536
	mov	word[checkSize1], 12
562
    mov     eax, edx
537
    mov     eax, edx
563
    add     eax, 20
538
    add     eax, 20
564
    mov     [checkAdd2], eax
539
    mov     [checkAdd2], eax
565
    mov     eax, ebx
540
    mov     eax, ebx
566
    mov     [checkSize2], ax
541
    mov     [checkSize2], ax
567
 
542
 
568
    call    checksum
543
    call    checksum
569
 
544
 
570
    ; store it in the TCP checksum ( in the correct order! )
545
    ; store it in the TCP checksum ( in the correct order! )
571
    mov     ax, [checkResult]
546
    mov     ax, [checkResult]
572
	rol	ax, 8
547
	rol	ax, 8
573
	mov	[edx + 20 + TCP_PACKET.Checksum], ax
548
	mov	[edx + 20 + TCP_PACKET.Checksum], ax
574
 
549
 
575
    ; Fill in the IP header checksum
550
    ; Fill in the IP header checksum
576
	GET_IHL eax, edx	       ; get IP-Header length
551
	GET_IHL eax, edx	       ; get IP-Header length
577
	stdcall checksum_jb, edx, eax  ; buf_ptr, buf_size
552
	stdcall checksum_jb, edx, eax  ; buf_ptr, buf_size
578
	rol	ax, 8
553
	rol	ax, 8
579
	mov	[edx + IP_PACKET.HeaderChecksum], ax
554
	mov	[edx + IP_PACKET.HeaderChecksum], ax
580
 
555
 
581
    ret
556
    ret
582
endp
557
endp
583
 
558
 
584
 
559
 
585
; Increments the 32 bit value pointed to by esi in internet order
560
; Increments the 32 bit value pointed to by esi in internet order
586
proc inc_inet_esi stdcall
561
proc inc_inet_esi stdcall
587
    push    eax
562
    push    eax
588
	mov	eax, [esi]
563
	mov	eax, [esi]
589
	bswap	eax
564
	bswap	eax
590
	inc	eax
565
	inc	eax
591
	bswap	eax
566
	bswap	eax
592
	mov	[esi], eax
567
	mov	[esi], eax
593
    pop     eax
568
    pop     eax
594
    ret
569
    ret
595
endp
570
endp
596
 
571
 
597
 
572
 
598
; Increments the 32 bit value pointed to by esi in internet order
573
; Increments the 32 bit value pointed to by esi in internet order
599
; by the value in ecx
574
; by the value in ecx
600
proc add_inet_esi stdcall
575
proc add_inet_esi stdcall
601
    push    eax
576
    push    eax
602
	mov	eax, [esi]
577
	mov	eax, [esi]
603
	bswap	eax
578
	bswap	eax
604
    add     eax, ecx
579
    add     eax, ecx
605
	bswap	eax
580
	bswap	eax
606
	mov	[esi], eax
581
	mov	[esi], eax
607
    pop     eax
582
    pop     eax
608
    ret
583
    ret
609
endp
584
endp
610
 
585
 
611
 
586
 
612
iglobal
587
iglobal
613
  TCBStateHandler dd \
588
  TCBStateHandler dd \
614
    stateTCB_LISTEN, \
589
    stateTCB_LISTEN, \
615
    stateTCB_SYN_SENT, \
590
    stateTCB_SYN_SENT, \
616
    stateTCB_SYN_RECEIVED, \
591
    stateTCB_SYN_RECEIVED, \
617
    stateTCB_ESTABLISHED, \
592
    stateTCB_ESTABLISHED, \
618
    stateTCB_FIN_WAIT_1, \
593
    stateTCB_FIN_WAIT_1, \
619
    stateTCB_FIN_WAIT_2, \
594
    stateTCB_FIN_WAIT_2, \
620
    stateTCB_CLOSE_WAIT, \
595
    stateTCB_CLOSE_WAIT, \
621
    stateTCB_CLOSING, \
596
    stateTCB_CLOSING, \
622
    stateTCB_LAST_ACK, \
597
    stateTCB_LAST_ACK, \
623
    stateTCB_TIME_WAIT, \
598
    stateTCB_TIME_WAIT, \
624
    stateTCB_CLOSED
599
    stateTCB_CLOSED
625
endg
600
endg
626
 
601
 
627
;***************************************************************************
602
;***************************************************************************
628
;   Function
603
;   Function
629
;      tcpStateMachine
604
;      tcpStateMachine
630
;
605
;
631
;   Description
606
;   Description
632
;       TCP state machine
607
;       TCP state machine
633
;       This is a kernel function, called by tcp_rx
608
;       This is a kernel function, called by tcp_rx
634
;
609
;
635
;       IP buffer address given in edx
610
;       IP buffer address given in edx
636
;          Socket/TCB address in ebx
611
;          Socket/TCB address in ebx
637
;
612
;
638
;       The IP buffer will be released by the caller
613
;       The IP buffer will be released by the caller
639
;***************************************************************************
614
;***************************************************************************
640
 
615
 
641
proc tcpStateMachine stdcall, sockAddr:DWORD
616
proc tcpStateMachine stdcall, sockAddr:DWORD
642
    ; as a packet has been received, update the TCB timer
617
    ; as a packet has been received, update the TCB timer
643
	mov	[ebx + SOCKET.TCBTimer], TWOMSL
618
	mov	[ebx + SOCKET.TCBTimer], TWOMSL
644
 
619
 
645
    ; If the received packet has an ACK bit set,
620
    ; If the received packet has an ACK bit set,
646
    ; remove any packets in the resend queue that this
621
    ; remove any packets in the resend queue that this
647
    ; received packet acknowledges
622
    ; received packet acknowledges
648
	pushad
623
	pushad
649
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
624
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
650
	jz	.call_handler					; No ACK, so no data yet
625
	jz	.call_handler					; No ACK, so no data yet
651
 
626
 
652
	; get skt number in eax
627
	; get skt number in eax
653
	stdcall net_socket_addr_to_num, ebx
628
	stdcall net_socket_addr_to_num, ebx
654
 
629
 
655
    ; The ack number is in [edx + 28], inet format
630
    ; The ack number is in [edx + 28], inet format
656
	; skt in eax
631
	; skt in eax
657
 
632
 
658
    mov     esi, resendQ
633
    mov     esi, resendQ
659
	xor	ecx, ecx
634
	xor	ecx, ecx
660
 
635
 
661
  .next_resendq:
636
  .next_resendq:
662
    cmp     ecx, NUMRESENDENTRIES
637
    cmp     ecx, NUMRESENDENTRIES
663
	je	.call_handler	  ; None left
638
	je	.call_handler	  ; None left
664
	;cmp     [esi], al                                       ; XTODO: al -> eax
-
 
665
	cmp	[esi + 4], eax
639
	cmp	[esi + 4], eax
666
	je	@f		  ; found one
640
	je	@f		  ; found one
667
    inc     ecx
641
    inc     ecx
668
	add	esi, 8
642
	add	esi, 8
669
	jmp	.next_resendq
643
	jmp	.next_resendq
670
 
644
 
671
    @@: 		  ; Can we delete this buffer?
645
    @@: 		  ; Can we delete this buffer?
672
 
646
 
673
			  ; If yes, goto @@. No, goto .next_resendq
647
			  ; If yes, goto @@. No, goto .next_resendq
674
    ; Get packet data address
648
    ; Get packet data address
675
 
649
 
676
    push    ecx
650
    push    ecx
677
    ; Now get buffer location, and copy buffer across. argh! more copying,,
651
    ; Now get buffer location, and copy buffer across. argh! more copying,,
678
	imul	edi, ecx, IPBUFFSIZE
652
	imul	edi, ecx, IPBUFFSIZE
679
	add	edi, resendBuffer
653
	add	edi, resendBuffer
680
 
654
 
681
    ; we have dest buffer location in edi. incoming packet in edx.
655
    ; we have dest buffer location in edi. incoming packet in edx.
682
    ; Get this packets sequence number
656
    ; Get this packets sequence number
683
    ; preserve al, ecx, esi, edx
657
    ; preserve al, ecx, esi, edx
684
	mov	ecx, [edi + 20 + TCP_PACKET.SequenceNumber]
658
	mov	ecx, [edi + 20 + TCP_PACKET.SequenceNumber]
685
	bswap	ecx
659
	bswap	ecx
686
	movzx	ebx, word[edi + 2]
660
	movzx	ebx, word[edi + 2]
687
	xchg	bl, bh
661
	xchg	bl, bh
688
    sub     ebx, 40
662
    sub     ebx, 40
689
    add     ecx, ebx          ; ecx is now seq# of last byte +1, intel format
663
    add     ecx, ebx          ; ecx is now seq# of last byte +1, intel format
690
 
664
 
691
    ; get recievd ack #, in intel format
665
    ; get recievd ack #, in intel format
692
	mov	ebx, [edx + 20 + TCP_PACKET.AckNumber]
666
	mov	ebx, [edx + 20 + TCP_PACKET.AckNumber]
693
	bswap	ebx
667
	bswap	ebx
694
 
668
 
695
    cmp     ebx, ecx        ; Finally. ecx = rx'ed ack. ebx = last byte in que
669
    cmp     ebx, ecx        ; Finally. ecx = rx'ed ack. ebx = last byte in que
696
                            ; DANGER! need to handle case that we have just
670
                            ; DANGER! need to handle case that we have just
697
                            ; passed the 2**32, and wrapped round!
671
                            ; passed the 2**32, and wrapped round!
698
    pop     ecx
672
    pop     ecx
699
	jae	@f		; if rx > old, delete old
673
	jae	@f		; if rx > old, delete old
700
 
674
 
701
    inc     ecx
675
    inc     ecx
702
	add	esi, 8
676
	add	esi, 8
703
	jmp	.next_resendq
677
	jmp	.next_resendq
704
 
-
 
705
    ;@@: mov     byte[esi], 0xff                                 ; XTODO: 0xff -> 0
678
 
706
    @@: mov	dword[esi + 4], 0
679
    @@: mov	dword[esi + 4], 0
707
    inc     ecx
680
    inc     ecx
708
	add	esi, 8
681
	add	esi, 8
709
	jmp	.next_resendq
682
	jmp	.next_resendq
710
 
683
 
711
  .call_handler:
684
  .call_handler:
712
	popad
685
	popad
713
 
686
 
714
	; Call handler for given TCB state
687
    ; Call handler for given TCB state
715
 
688
 
716
	mov	eax, [ebx + SOCKET.TCBState]
689
	mov	eax, [ebx + SOCKET.TCBState]
717
	cmp	eax, TCB_LISTEN
690
	cmp	eax, TCB_LISTEN
718
	jb	.exit
691
	jb	.exit
719
	cmp	eax, TCB_CLOSED
692
	cmp	eax, TCB_CLOSED
720
	ja	.exit
693
	ja	.exit
721
 
694
 
722
	stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr]
695
	stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr]
723
 
696
 
724
  .exit:
697
  .exit:
725
    ret
698
    ret
726
endp
699
endp
727
 
700
 
728
 
701
 
729
proc stateTCB_LISTEN stdcall, sockAddr:DWORD
702
proc stateTCB_LISTEN stdcall, sockAddr:DWORD
730
    ; In this case, we are expecting a SYN packet
703
    ; In this case, we are expecting a SYN packet
731
    ; For now, if the packet is a SYN, process it, and send a response
704
    ; For now, if the packet is a SYN, process it, and send a response
732
    ; If not, ignore it
705
    ; If not, ignore it
733
 
706
 
734
    ; Look at control flags
707
    ; Look at control flags
735
	test	[edx + 20 + TCP_PACKET.Flags], TH_SYN
708
	test	[edx + 20 + TCP_PACKET.Flags], TH_SYN
736
	jz	.exit
709
	jz	.exit
737
 
710
 
738
    ; We have a SYN. update the socket with this IP packets details,
711
    ; We have a SYN. update the socket with this IP packets details,
739
    ; And send a response
712
    ; And send a response
740
 
713
 
741
	mov	eax, [edx + IP_PACKET.SourceAddress]
714
	mov	eax, [edx + IP_PACKET.SourceAddress]
742
	mov	[ebx + SOCKET.RemoteIP], eax
715
	mov	[ebx + SOCKET.RemoteIP], eax
743
	mov	ax, [edx + 20 + TCP_PACKET.SourcePort]
716
	mov	ax, [edx + 20 + TCP_PACKET.SourcePort]
744
	mov	[ebx + SOCKET.RemotePort], ax
717
	mov	[ebx + SOCKET.RemotePort], ax
745
	mov	eax, [edx + 20 + TCP_PACKET.SequenceNumber]
718
	mov	eax, [edx + 20 + TCP_PACKET.SequenceNumber]
746
	mov	[ebx + SOCKET.IRS], eax
719
	mov	[ebx + SOCKET.IRS], eax
747
	mov	[ebx + SOCKET.RCV_NXT], eax
720
	mov	[ebx + SOCKET.RCV_NXT], eax
748
	lea	esi, [ebx + SOCKET.RCV_NXT]
721
	lea	esi, [ebx + SOCKET.RCV_NXT]
749
    call    inc_inet_esi ; RCV.NXT
722
    call    inc_inet_esi ; RCV.NXT
750
	mov	eax, [ebx + SOCKET.ISS]
723
	mov	eax, [ebx + SOCKET.ISS]
751
	mov	[ebx + SOCKET.SND_NXT], eax
724
	mov	[ebx + SOCKET.SND_NXT], eax
752
 
725
 
753
    ; Now construct the response, and queue for sending by IP
726
    ; Now construct the response, and queue for sending by IP
754
    mov     eax, EMPTY_QUEUE
727
    mov     eax, EMPTY_QUEUE
755
    call    dequeue
728
    call    dequeue
756
    cmp     ax, NO_BUFFER
729
    cmp     ax, NO_BUFFER
757
	je	.exit
730
	je	.exit
758
 
731
 
759
    push    eax
732
    push    eax
760
	mov	bl, TH_SYN + TH_ACK
733
	mov	bl, TH_SYN + TH_ACK
761
	xor	ecx, ecx
734
	xor	ecx, ecx
762
	xor	esi, esi
735
	xor	esi, esi
763
	stdcall build_tcp_packet, [sockAddr]
736
	stdcall build_tcp_packet, [sockAddr]
764
 
737
 
765
    mov     eax, NET1OUT_QUEUE
738
    mov     eax, NET1OUT_QUEUE
766
    mov     edx, [stack_ip]
739
    mov     edx, [stack_ip]
767
	mov	ecx, [sockAddr]
740
	mov	ecx, [sockAddr]
768
	cmp	edx, [ecx + SOCKET.RemoteIP]
741
	cmp	edx, [ecx + SOCKET.RemoteIP]
769
	jne	.not_local
742
	jne	.not_local
770
    mov     eax, IPIN_QUEUE
743
    mov     eax, IPIN_QUEUE
771
 
744
 
772
  .not_local:
745
  .not_local:
773
       ; Send it.
746
       ; Send it.
774
    pop     ebx
747
    pop     ebx
775
    call    queue
748
    call    queue
776
 
749
 
777
	mov	esi, [sockAddr]
750
	mov	esi, [sockAddr]
778
	mov	[esi + SOCKET.TCBState], TCB_SYN_RECEIVED
751
	mov	[esi + SOCKET.TCBState], TCB_SYN_RECEIVED
779
 
752
 
780
	; increment SND.NXT in socket
753
	; increment SND.NXT in socket
781
	add	esi, SOCKET.SND_NXT
754
	add	esi, SOCKET.SND_NXT
782
    call    inc_inet_esi
755
    call    inc_inet_esi
783
 
756
 
784
  .exit:
757
  .exit:
785
    ret
758
    ret
786
endp
759
endp
787
 
760
 
788
 
761
 
789
proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD
762
proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD
790
    ; We are awaiting an ACK to our SYN, with a SYM
763
    ; We are awaiting an ACK to our SYN, with a SYM
791
    ; Look at control flags - expecting an ACK
764
    ; Look at control flags - expecting an ACK
792
 
765
 
793
	mov	al, [edx + 20 + TCP_PACKET.Flags]
766
	mov	al, [edx + 20 + TCP_PACKET.Flags]
794
	and	al, TH_SYN + TH_ACK
767
	and	al, TH_SYN + TH_ACK
795
	cmp	al, TH_SYN + TH_ACK
768
	cmp	al, TH_SYN + TH_ACK
796
	je	.syn_ack
769
	je	.syn_ack
797
 
770
 
798
	test	al, TH_SYN
771
	test	al, TH_SYN
799
	jz	.exit
772
	jz	.exit
800
 
773
 
801
	mov	[ebx + SOCKET.TCBState], TCB_SYN_RECEIVED
774
	mov	[ebx + SOCKET.TCBState], TCB_SYN_RECEIVED
802
	push	TH_SYN + TH_ACK
775
	push	TH_SYN + TH_ACK
803
	jmp	.send
776
	jmp	.send
804
 
777
 
805
  .syn_ack:
778
  .syn_ack:
806
	mov	[ebx + SOCKET.TCBState], TCB_ESTABLISHED
779
	mov	[ebx + SOCKET.TCBState], TCB_ESTABLISHED
807
	push	TH_ACK
780
	push	TH_ACK
808
 
781
 
809
  .send:
782
  .send:
810
    ; Store the recv.nxt field
783
    ; Store the recv.nxt field
811
	mov	eax, [edx + 20 + TCP_PACKET.SequenceNumber]
784
	mov	eax, [edx + 20 + TCP_PACKET.SequenceNumber]
812
 
785
 
813
    ; Update our recv.nxt field
786
    ; Update our recv.nxt field
814
	mov	[ebx + SOCKET.RCV_NXT], eax
787
	mov	[ebx + SOCKET.RCV_NXT], eax
815
	lea	esi, [ebx + SOCKET.RCV_NXT]
788
	lea	esi, [ebx + SOCKET.RCV_NXT]
816
    call    inc_inet_esi
789
    call    inc_inet_esi
817
 
790
 
818
    ; Send an ACK
791
    ; Send an ACK
819
    ; Now construct the response, and queue for sending by IP
792
    ; Now construct the response, and queue for sending by IP
820
    mov     eax, EMPTY_QUEUE
793
    mov     eax, EMPTY_QUEUE
821
    call    dequeue
794
    call    dequeue
822
    cmp     ax, NO_BUFFER
795
    cmp     ax, NO_BUFFER
823
	pop	ebx
796
	pop	ebx
824
	je	.exit
797
	je	.exit
825
 
798
 
826
    push    eax
799
    push    eax
827
 
800
 
828
	xor	ecx, ecx
801
	xor	ecx, ecx
829
	xor	esi, esi
802
	xor	esi, esi
830
	stdcall build_tcp_packet, [sockAddr]
803
	stdcall build_tcp_packet, [sockAddr]
831
 
804
 
832
    mov     eax, NET1OUT_QUEUE
805
    mov     eax, NET1OUT_QUEUE
833
 
806
 
834
    mov     edx, [stack_ip]
807
    mov     edx, [stack_ip]
835
	mov	ecx, [sockAddr]
808
	mov	ecx, [sockAddr]
836
	cmp	edx, [ecx + SOCKET.RemoteIP]
809
	cmp	edx, [ecx + SOCKET.RemoteIP]
837
	jne	.not_local
810
	jne	.not_local
838
    mov     eax, IPIN_QUEUE
811
    mov     eax, IPIN_QUEUE
839
 
812
 
840
  .not_local:
813
  .not_local:
841
       ; Send it.
814
       ; Send it.
842
    pop     ebx
815
    pop     ebx
843
    call    queue
816
    call    queue
844
 
817
 
845
  .exit:
818
  .exit:
846
    ret
819
    ret
847
endp
820
endp
848
 
821
 
849
 
822
 
850
proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
823
proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
851
    ; In this case, we are expecting an ACK packet
824
    ; In this case, we are expecting an ACK packet
852
    ; For now, if the packet is an ACK, process it,
825
    ; For now, if the packet is an ACK, process it,
853
    ; If not, ignore it
826
    ; If not, ignore it
854
 
827
 
855
	test	[edx + 20 + TCP_PACKET.Flags], TH_RST		;xxx
828
	test	[edx + 20 + TCP_PACKET.Flags], TH_RST
856
	jz	.check_ack					;xxx
829
	jz	.check_ack
857
 
830
 
858
	push	[ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP]
831
	push	[ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP]
859
	pop	[ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort]
832
	pop	[ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort]
860
 
833
 
861
	mov	[ebx + SOCKET.TCBState], TCB_LISTEN		;xxx
834
	mov	[ebx + SOCKET.TCBState], TCB_LISTEN
862
	jmp	.exit						;xxx
835
	jmp	.exit
863
 
836
 
864
  .check_ack:							;xxx
837
  .check_ack:
865
    ; Look at control flags - expecting an ACK
838
    ; Look at control flags - expecting an ACK
866
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
839
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
867
	jz	.exit
840
	jz	.exit
868
 
841
 
869
	mov	[ebx + SOCKET.TCBState], TCB_ESTABLISHED
842
	mov	[ebx + SOCKET.TCBState], TCB_ESTABLISHED
870
 
843
 
871
  .exit:
844
  .exit:
872
    ret
845
    ret
873
endp
846
endp
874
 
847
 
875
 
848
 
876
proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
849
proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
877
    ; Here we are expecting data, or a request to close
850
    ; Here we are expecting data, or a request to close
878
    ; OR both...
851
    ; OR both...
879
 
852
 
880
    ; Did we receive a FIN or RST?
853
    ; Did we receive a FIN or RST?
881
;xxx    test    [edx + 20 + TCP_PACKET.Flags], TH_FIN + TH_RST
-
 
882
;xxx    jz      .check_ack
-
 
883
	test	[edx + 20 + TCP_PACKET.Flags], TH_FIN		;xxx
854
	test	[edx + 20 + TCP_PACKET.Flags], TH_FIN
884
	jz	.check_ack					;xxx
855
	jz	.check_ack
885
 
856
 
886
    ; It was a fin or reset.
857
    ; It was a fin or reset.
887
 
858
 
888
    ; Remove resend entries from the queue  - I dont want to send any more data
859
    ; Remove resend entries from the queue  - I dont want to send any more data
889
	pushad
860
	pushad
890
 
861
 
891
	; get skt #
862
	; get skt #
892
	stdcall net_socket_addr_to_num, ebx
863
	stdcall net_socket_addr_to_num, ebx
893
 
864
 
894
    mov     esi, resendQ
865
    mov     esi, resendQ
895
    mov     ecx, 0
866
    mov     ecx, 0
896
 
867
 
897
  .next_resendq:
868
  .next_resendq:
898
    cmp     ecx, NUMRESENDENTRIES
869
    cmp     ecx, NUMRESENDENTRIES
899
	je	.last_resendq	    ; None left
870
	je	.last_resendq	    ; None left
900
	;cmp     [esi], al                                              ; XTODO: al -> eax
-
 
901
	cmp	[esi + 4], eax
871
	cmp	[esi + 4], eax
902
	je	@f		    ; found one
872
	je	@f		    ; found one
903
	inc	ecx
873
	inc	ecx
904
	add	esi, 8
874
	add	esi, 8
905
	jmp	.next_resendq
875
	jmp	.next_resendq
906
 
-
 
907
    ;@@: mov     byte[esi], 0xff                                         ; XTODO: 0xff -> 0
876
 
908
    @@: mov	dword[esi + 4], 0
877
    @@: mov	dword[esi + 4], 0
909
    inc     ecx
878
    inc     ecx
910
	add	esi, 8
879
	add	esi, 8
911
	jmp	.next_resendq
880
	jmp	.next_resendq
912
 
881
 
913
  .last_resendq:
882
  .last_resendq:
914
	popad
883
	popad
915
 
-
 
916
;xxx    ; was it a reset?
-
 
917
;xxx    test    [edx + 20 + TCP_PACKET.Flags], TH_RST
-
 
918
;xxx    jz      @f
-
 
919
 
-
 
920
;xxx    mov     [ebx + SOCKET.TCBState], TCB_CLOSED
-
 
921
;xxx    jmp     .exit
-
 
922
 
884
 
923
    @@: ; Send an ACK to that fin, and enter closewait state
885
    @@: ; Send an ACK to that fin, and enter closewait state
924
 
886
 
925
	mov	[ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
887
	mov	[ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
926
	lea	esi, [ebx + SOCKET.RCV_NXT]
888
	lea	esi, [ebx + SOCKET.RCV_NXT]
927
    mov     eax, [esi]              ; save original
889
    mov     eax, [esi]              ; save original
928
    call    inc_inet_esi
890
    call    inc_inet_esi
929
    ;; jmp    ste_ack - NO, there may be data
891
    ;; jmp    ste_ack - NO, there may be data
930
 
892
 
931
  .check_ack:
893
  .check_ack:
932
    ; Check that we received an ACK
894
    ; Check that we received an ACK
933
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
895
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
934
	jz	.exit
896
	jz	.exit
935
 
897
 
936
    ; TODO - done, I think!
898
    ; TODO - done, I think!
937
    ; First, look at the incoming window. If this is less than or equal to 1024,
899
    ; First, look at the incoming window. If this is less than or equal to 1024,
938
	; Set the socket window timer to 1. This will stop an additional packets being queued.
900
	; Set the socket window timer to 1. This will stop an additional packets being queued.
939
    ; ** I may need to tweak this value, since I do not know how many packets are already queued
901
    ; ** I may need to tweak this value, since I do not know how many packets are already queued
940
	mov	cx, [edx + 20 + TCP_PACKET.Window]
902
	mov	cx, [edx + 20 + TCP_PACKET.Window]
941
	xchg	cl, ch
903
	xchg	cl, ch
942
    cmp     cx, 1024
904
    cmp     cx, 1024
943
	ja	@f
905
	ja	@f
944
 
906
 
945
	mov	[ebx + SOCKET.wndsizeTimer], 1
907
	mov	[ebx + SOCKET.wndsizeTimer], 1
946
 
908
 
947
    @@: ; OK, here is the deal
909
    @@: ; OK, here is the deal
948
    ; My recv.nct field holds the seq of the expected next rec byte
910
    ; My recv.nct field holds the seq of the expected next rec byte
949
    ; if the recevied sequence number is not equal to this, do not
911
    ; if the recevied sequence number is not equal to this, do not
950
    ; increment the recv.nxt field, do not copy data - just send a
912
    ; increment the recv.nxt field, do not copy data - just send a
951
    ; repeat ack.
913
    ; repeat ack.
952
 
914
 
953
	; recv.nxt is in dword [edx+24], in inet format
915
	; recv.nxt is in dword [edx+24], in inet format
954
    ; recv seq is in [sktAddr]+56, in inet format
916
    ; recv seq is in [sktAddr]+56, in inet format
955
    ; just do a comparision
917
    ; just do a comparision
956
	mov	ecx, [ebx + SOCKET.RCV_NXT]
918
	mov	ecx, [ebx + SOCKET.RCV_NXT]
957
	cmp	[ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
919
	cmp	[ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
958
	jne	@f
920
	jne	@f
959
    mov     ecx, eax
921
    mov     ecx, eax
960
 
922
 
961
    @@: cmp	ecx, [edx + 20 + TCP_PACKET.SequenceNumber]
923
    @@: cmp	ecx, [edx + 20 + TCP_PACKET.SequenceNumber]
962
	jne	.ack
924
	jne	.ack
963
 
925
 
964
 
926
 
965
    ; Read the data bytes, store in socket buffer
927
    ; Read the data bytes, store in socket buffer
966
	movzx	ecx, [edx + IP_PACKET.TotalLength]
928
	movzx	ecx, [edx + IP_PACKET.TotalLength]
967
	xchg	cl, ch
929
	xchg	cl, ch
968
    sub     ecx, 40                    ; Discard 40 bytes of header
930
    sub     ecx, 40                    ; Discard 40 bytes of header
969
	jnz	.data			   ; Read data, if any
931
	ja	.data			   ; Read data, if any
970
 
932
 
971
    ; If we had received a fin, we need to ACK it.
933
    ; If we had received a fin, we need to ACK it.
972
	cmp	[ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
934
	cmp	[ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
973
	je	.ack
935
	je	.ack
974
	jmp	.exit
936
	jmp	.exit
975
 
937
 
976
  .data:
938
  .data:
977
    push    ecx
939
	push	ebx
978
 
-
 
979
	add	[ebx + SOCKET.rxDataCount], ecx      ; increment the count of bytes in buffer
940
	add	ebx, SOCKET.lock
-
 
941
	call	wait_mutex
-
 
942
	pop	ebx
-
 
943
 
980
 
944
	push	ecx
-
 
945
	push	[ebx + SOCKET.PID]	; get socket owner PID
981
	mov	eax, [ebx + SOCKET.PID]       ; get socket owner PID
946
	mov	eax, [ebx + SOCKET.rxDataCount]
-
 
947
	add	eax, ecx
-
 
948
	cmp	eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE
982
    push    eax
949
	ja	.overflow
983
 
950
 
984
	mov	eax, [ebx + SOCKET.rxDataCount]      ; get # of bytes already in buffer
951
	mov	[ebx + SOCKET.rxDataCount], eax      ; increment the count of bytes in buffer
985
 
952
 
986
    ; point to the location to store the data
953
    ; point to the location to store the data
987
	lea	edi, [ebx + eax + SOCKETHEADERSIZE]
954
	lea	edi, [ebx + eax + SOCKETHEADERSIZE]
988
	sub	edi, ecx
955
	sub	edi, ecx
989
 
956
 
990
    add     edx, 40        ; edx now points to the data
957
    add     edx, 40        ; edx now points to the data
991
    mov     esi, edx
958
    mov     esi, edx
992
 
959
 
993
    cld
960
    cld
994
    rep     movsb          ; copy the data across
961
    rep     movsb          ; copy the data across
-
 
962
	mov	[ebx + SOCKET.lock], 0	; release mutex
995
 
963
 
996
    ; flag an event to the application
964
    ; flag an event to the application
997
    pop     eax
965
    pop     eax
998
	mov	ecx, 1
966
	mov	ecx, 1
999
	mov	esi, TASK_DATA + TASKDATA.pid
967
	mov	esi, TASK_DATA + TASKDATA.pid
1000
 
968
 
1001
  .next_pid:
969
  .next_pid:
1002
	cmp	[esi], eax
970
	cmp	[esi], eax
1003
	je	.found_pid
971
	je	.found_pid
1004
    inc     ecx
972
    inc     ecx
1005
	add	esi, 0x20
973
	add	esi, 0x20
1006
	cmp	ecx, [TASK_COUNT]
974
	cmp	ecx, [TASK_COUNT]
1007
	jbe	.next_pid
975
	jbe	.next_pid
1008
 
976
 
1009
  .found_pid:
977
  .found_pid:
1010
	shl	ecx, 8
978
	shl	ecx, 8
1011
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
979
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
1012
 
980
 
1013
    pop     ecx
981
    pop     ecx
1014
 
982
 
1015
    ; Update our recv.nxt field
983
    ; Update our recv.nxt field
1016
	lea	esi, [ebx + SOCKET.RCV_NXT]
984
	lea	esi, [ebx + SOCKET.RCV_NXT]
1017
    call    add_inet_esi
985
    call    add_inet_esi
1018
 
986
 
1019
  .ack:
987
  .ack:
1020
    ; Send an ACK
988
    ; Send an ACK
1021
    ; Now construct the response, and queue for sending by IP
989
    ; Now construct the response, and queue for sending by IP
1022
    mov     eax, EMPTY_QUEUE
990
    mov     eax, EMPTY_QUEUE
1023
    call    dequeue
991
    call    dequeue
1024
    cmp     ax, NO_BUFFER
992
    cmp     ax, NO_BUFFER
1025
	je	.exit
993
	je	.exit
1026
 
994
 
1027
    push    eax
995
    push    eax
1028
 
996
 
1029
	mov	bl, TH_ACK
997
	mov	bl, TH_ACK
1030
	xor	ecx, ecx
998
	xor	ecx, ecx
1031
	xor	esi, esi
999
	xor	esi, esi
1032
	stdcall build_tcp_packet, [sockAddr]
1000
	stdcall build_tcp_packet, [sockAddr]
1033
 
1001
 
1034
    mov     eax, NET1OUT_QUEUE
1002
    mov     eax, NET1OUT_QUEUE
1035
 
1003
 
1036
    mov     edx, [stack_ip]
1004
    mov     edx, [stack_ip]
1037
	mov	ecx, [sockAddr]
1005
	mov	ecx, [sockAddr]
1038
	cmp	edx, [ecx + SOCKET.RemoteIP]
1006
	cmp	edx, [ecx + SOCKET.RemoteIP]
1039
	jne	.not_local
1007
	jne	.not_local
1040
    mov     eax, IPIN_QUEUE
1008
    mov     eax, IPIN_QUEUE
1041
 
1009
 
1042
  .not_local:
1010
  .not_local:
1043
       ; Send it.
1011
       ; Send it.
1044
    pop     ebx
1012
    pop     ebx
1045
    call    queue
1013
    call    queue
1046
 
1014
 
1047
  .exit:
1015
  .exit:
1048
    ret
1016
    ret
-
 
1017
  .overflow:
-
 
1018
	; no place in buffer
-
 
1019
	; so simply restore stack and exit
-
 
1020
	pop	eax ecx
-
 
1021
	mov	[ebx + SOCKET.lock], 0
-
 
1022
	ret
1049
endp
1023
endp
1050
 
1024
 
1051
 
1025
 
1052
proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD
1026
proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD
1053
	; We can either receive an ACK of a fin, or a fin
1027
    ; We can either receive an ACK of a fin, or a fin
1054
	mov	al, [edx + 20 + TCP_PACKET.Flags]
1028
	mov	al, [edx + 20 + TCP_PACKET.Flags]
1055
	and	al, TH_FIN + TH_ACK
1029
	and	al, TH_FIN + TH_ACK
1056
 
1030
 
1057
	cmp	al, TH_ACK
1031
	cmp	al, TH_ACK
1058
	jne	@f
1032
	jne	@f
1059
 
1033
 
1060
    ; It was an ACK
1034
    ; It was an ACK
1061
	mov	[ebx + SOCKET.TCBState], TCB_FIN_WAIT_2
1035
	mov	[ebx + SOCKET.TCBState], TCB_FIN_WAIT_2
1062
	jmp	.exit
1036
	jmp	.exit
1063
 
1037
 
1064
    @@: mov	[ebx + SOCKET.TCBState], TCB_CLOSING
1038
    @@: mov	[ebx + SOCKET.TCBState], TCB_CLOSING
1065
	cmp	al, TH_FIN
1039
	cmp	al, TH_FIN
1066
	je	@f
1040
	je	@f
1067
	mov	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1041
	mov	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1068
 
1042
 
1069
    @@: lea	esi, [ebx + SOCKET.RCV_NXT]
1043
    @@: lea	esi, [ebx + SOCKET.RCV_NXT]
1070
    call    inc_inet_esi
1044
    call    inc_inet_esi
1071
 
1045
 
1072
    ; Send an ACK
1046
    ; Send an ACK
1073
    mov     eax, EMPTY_QUEUE
1047
    mov     eax, EMPTY_QUEUE
1074
    call    dequeue
1048
    call    dequeue
1075
    cmp     ax, NO_BUFFER
1049
    cmp     ax, NO_BUFFER
1076
	je	.exit
1050
	je	.exit
1077
 
1051
 
1078
    push    eax
1052
    push    eax
1079
 
1053
 
1080
	mov	bl, TH_ACK
1054
	mov	bl, TH_ACK
1081
	xor	ecx, ecx
1055
	xor	ecx, ecx
1082
	xor	esi, esi
1056
	xor	esi, esi
1083
	stdcall build_tcp_packet, [sockAddr]
1057
	stdcall build_tcp_packet, [sockAddr]
1084
 
1058
 
1085
    mov     eax, NET1OUT_QUEUE
1059
    mov     eax, NET1OUT_QUEUE
1086
 
1060
 
1087
    mov     edx, [stack_ip]
1061
    mov     edx, [stack_ip]
1088
	mov	ecx, [sockAddr]
1062
	mov	ecx, [sockAddr]
1089
	cmp	edx, [ecx + SOCKET.RemoteIP]
1063
	cmp	edx, [ecx + SOCKET.RemoteIP]
1090
	jne	.not_local
1064
	jne	.not_local
1091
    mov     eax, IPIN_QUEUE
1065
    mov     eax, IPIN_QUEUE
1092
 
1066
 
1093
  .not_local:
1067
  .not_local:
1094
    ; Send it.
1068
    ; Send it.
1095
    pop     ebx
1069
    pop     ebx
1096
    call    queue
1070
    call    queue
1097
 
1071
 
1098
  .exit:
1072
  .exit:
1099
    ret
1073
    ret
1100
endp
1074
endp
1101
 
1075
 
1102
 
1076
 
1103
proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD
1077
proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD
1104
	test	[edx + 20 + TCP_PACKET.Flags], TH_FIN
1078
	test	[edx + 20 + TCP_PACKET.Flags], TH_FIN
1105
	jz	.exit
1079
	jz	.exit
1106
 
1080
 
1107
    ; Change state, as we have a fin
1081
    ; Change state, as we have a fin
1108
	mov	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1082
	mov	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1109
 
1083
 
1110
	lea	esi, [ebx + SOCKET.RCV_NXT]
1084
	lea	esi, [ebx + SOCKET.RCV_NXT]
1111
	call	inc_inet_esi
1085
	call	inc_inet_esi
1112
 
1086
 
1113
    ; Send an ACK
1087
    ; Send an ACK
1114
    mov     eax, EMPTY_QUEUE
1088
    mov     eax, EMPTY_QUEUE
1115
    call    dequeue
1089
    call    dequeue
1116
    cmp     ax, NO_BUFFER
1090
    cmp     ax, NO_BUFFER
1117
	je	.exit
1091
	je	.exit
1118
 
1092
 
1119
    push    eax
1093
    push    eax
1120
 
1094
 
1121
	mov	bl, TH_ACK
1095
	mov	bl, TH_ACK
1122
	xor	ecx, ecx
1096
	xor	ecx, ecx
1123
	xor	esi, esi
1097
	xor	esi, esi
1124
	stdcall build_tcp_packet, [sockAddr]
1098
	stdcall build_tcp_packet, [sockAddr]
1125
 
1099
 
1126
    mov     eax, NET1OUT_QUEUE
1100
    mov     eax, NET1OUT_QUEUE
1127
 
1101
 
1128
    mov     edx, [stack_ip]
1102
    mov     edx, [stack_ip]
1129
	mov	ecx, [sockAddr]
1103
	mov	ecx, [sockAddr]
1130
	cmp	edx, [ecx + SOCKET.RemoteIP]
1104
	cmp	edx, [ecx + SOCKET.RemoteIP]
1131
	jne	.not_local
1105
	jne	.not_local
1132
    mov     eax, IPIN_QUEUE
1106
    mov     eax, IPIN_QUEUE
1133
 
1107
 
1134
  .not_local:
1108
  .not_local:
1135
       ; Send it.
1109
       ; Send it.
1136
    pop     ebx
1110
    pop     ebx
1137
    call    queue
1111
    call    queue
1138
 
1112
 
1139
  .exit:
1113
  .exit:
1140
    ret
1114
    ret
1141
endp
1115
endp
1142
 
1116
 
1143
 
1117
 
1144
proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD
1118
proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD
1145
    ; Intentionally left empty
1119
    ; Intentionally left empty
1146
    ; socket_close_tcp handles this
1120
    ; socket_close_tcp handles this
1147
    ret
1121
    ret
1148
endp
1122
endp
1149
 
1123
 
1150
 
1124
 
1151
proc stateTCB_CLOSING stdcall, sockAddr:DWORD
1125
proc stateTCB_CLOSING stdcall, sockAddr:DWORD
1152
    ; We can either receive an ACK of a fin, or a fin
1126
    ; We can either receive an ACK of a fin, or a fin
1153
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
1127
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
1154
	jz	.exit
1128
	jz	.exit
1155
 
1129
 
1156
	mov	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1130
	mov	[ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1157
 
1131
 
1158
  .exit:
1132
  .exit:
1159
    ret
1133
    ret
1160
endp
1134
endp
1161
 
1135
 
1162
 
1136
 
1163
proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD
1137
proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD
1164
    ; Look at control flags - expecting an ACK
1138
    ; Look at control flags - expecting an ACK
1165
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
1139
	test	[edx + 20 + TCP_PACKET.Flags], TH_ACK
1166
	jz	.exit
1140
	jz	.exit
1167
 
1141
 
1168
    ; delete the socket
1142
    ; delete the socket
1169
	stdcall net_socket_free, ebx
1143
	stdcall net_socket_free, ebx
1170
;        mov     edi, ebx
-
 
1171
;        xor     eax, eax
-
 
1172
;        mov     ecx, SOCKETHEADERSIZE
-
 
1173
;        cld
-
 
1174
;        rep     stosb
-
 
1175
 
1144
 
1176
  .exit:
1145
  .exit:
1177
    ret
1146
    ret
1178
endp
1147
endp
1179
 
1148
 
1180
 
1149
 
1181
proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD
1150
proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD
1182
    ret
1151
    ret
1183
endp
1152
endp
1184
 
1153
 
1185
 
1154
 
1186
proc stateTCB_CLOSED stdcall, sockAddr:DWORD
1155
proc stateTCB_CLOSED stdcall, sockAddr:DWORD
1187
    ret
1156
    ret
1188
endp
1157
endp