Subversion Repositories Kolibri OS

Rev

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

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