Subversion Repositories Kolibri OS

Rev

Rev 2288 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2288 Rev 2381
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: 2288 $
19
$Revision: 2381 $
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
    @@:
672
    @@:
673
        mov     dword[esi + 4], 0
673
        mov     dword[esi + 4], 0
674
        inc     ecx
674
        inc     ecx
675
        add     esi, 8
675
        add     esi, 8
676
        jmp     .next_resendq
676
        jmp     .next_resendq
677
 
677
 
678
  .call_handler:
678
  .call_handler:
679
        popad
679
        popad
680
 
680
 
681
        ; Call handler for given TCB state
681
        ; Call handler for given TCB state
682
 
682
 
683
        mov     eax, [ebx + SOCKET.TCBState]
683
        mov     eax, [ebx + SOCKET.TCBState]
684
        cmp     eax, TCB_LISTEN
684
        cmp     eax, TCB_LISTEN
685
        jb      .exit
685
        jb      .exit
686
        cmp     eax, TCB_CLOSED
686
        cmp     eax, TCB_CLOSED
687
        ja      .exit
687
        ja      .exit
688
 
688
 
689
        stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr]
689
        stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr]
690
 
690
 
691
  .exit:
691
  .exit:
692
        ret
692
        ret
693
endp
693
endp
694
 
694
 
695
;***************************************************************************
695
;***************************************************************************
696
;   Function
696
;   Function
697
;      signal_network_event
697
;      signal_network_event
698
;
698
;
699
;   Description
699
;   Description
700
;       Signals about network event to socket owner
700
;       Signals about network event to socket owner
701
;       This is a kernel function, called from TCP handler
701
;       This is a kernel function, called from TCP handler
702
;
702
;
703
;          Socket/TCB address in ebx
703
;          Socket/TCB address in ebx
704
;***************************************************************************
704
;***************************************************************************
705
proc signal_network_event
705
proc signal_network_event
706
        push    ecx esi eax
706
        push    ecx esi eax
707
        mov     eax, [ebx + SOCKET.PID]
707
        mov     eax, [ebx + SOCKET.PID]
708
        mov     ecx, 1
708
        mov     ecx, 1
709
        mov     esi, TASK_DATA + TASKDATA.pid
709
        mov     esi, TASK_DATA + TASKDATA.pid
710
 
710
 
711
  .next_pid:
711
  .next_pid:
712
        cmp     [esi], eax
712
        cmp     [esi], eax
713
        je      .found_pid
713
        je      .found_pid
714
        inc     ecx
714
        inc     ecx
715
        add     esi, 0x20
715
        add     esi, 0x20
716
        cmp     ecx, [TASK_COUNT]
716
        cmp     ecx, [TASK_COUNT]
717
        jbe     .next_pid
717
        jbe     .next_pid
718
 
718
 
719
  .found_pid:
719
  .found_pid:
720
        shl     ecx, 8
720
        shl     ecx, 8
721
        or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
721
        or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
722
        pop     eax esi ecx
722
        pop     eax esi ecx
723
        ret
723
        ret
724
endp
724
endp
725
 
725
 
726
proc stateTCB_LISTEN stdcall, sockAddr:DWORD
726
proc stateTCB_LISTEN stdcall, sockAddr:DWORD
727
        ; In this case, we are expecting a SYN packet
727
        ; In this case, we are expecting a SYN packet
728
        ; For now, if the packet is a SYN, process it, and send a response
728
        ; For now, if the packet is a SYN, process it, and send a response
729
        ; If not, ignore it
729
        ; If not, ignore it
730
 
730
 
731
        ; Look at control flags
731
        ; Look at control flags
732
        test    [edx + 20 + TCP_PACKET.Flags], TH_SYN
732
        test    [edx + 20 + TCP_PACKET.Flags], TH_SYN
733
        jz      .exit
733
        jz      .exit
734
 
734
 
735
        ; We have a SYN. update the socket with this IP packets details,
735
        ; We have a SYN. update the socket with this IP packets details,
736
        ; And send a response
736
        ; And send a response
737
 
737
 
738
        mov     eax, [edx + IP_PACKET.SourceAddress]
738
        mov     eax, [edx + IP_PACKET.SourceAddress]
739
        mov     [ebx + SOCKET.RemoteIP], eax
739
        mov     [ebx + SOCKET.RemoteIP], eax
740
        mov     ax, [edx + 20 + TCP_PACKET.SourcePort]
740
        mov     ax, [edx + 20 + TCP_PACKET.SourcePort]
741
        mov     [ebx + SOCKET.RemotePort], ax
741
        mov     [ebx + SOCKET.RemotePort], ax
742
        mov     eax, [edx + 20 + TCP_PACKET.SequenceNumber]
742
        mov     eax, [edx + 20 + TCP_PACKET.SequenceNumber]
743
        mov     [ebx + SOCKET.IRS], eax
743
        mov     [ebx + SOCKET.IRS], eax
744
        mov     [ebx + SOCKET.RCV_NXT], eax
744
        mov     [ebx + SOCKET.RCV_NXT], eax
745
        lea     esi, [ebx + SOCKET.RCV_NXT]
745
        lea     esi, [ebx + SOCKET.RCV_NXT]
746
        call    inc_inet_esi ; RCV.NXT
746
        call    inc_inet_esi ; RCV.NXT
747
        mov     eax, [ebx + SOCKET.ISS]
747
        mov     eax, [ebx + SOCKET.ISS]
748
        mov     [ebx + SOCKET.SND_NXT], eax
748
        mov     [ebx + SOCKET.SND_NXT], eax
749
 
749
 
750
        ; Now construct the response, and queue for sending by IP
750
        ; Now construct the response, and queue for sending by IP
751
        mov     eax, EMPTY_QUEUE
751
        mov     eax, EMPTY_QUEUE
752
        call    dequeue
752
        call    dequeue
753
        cmp     ax, NO_BUFFER
753
        cmp     ax, NO_BUFFER
754
        je      .exit
754
        je      .exit
755
 
755
 
756
        push    ebx
756
        push    ebx
757
        push    eax
757
        push    eax
758
        mov     bl, TH_SYN + TH_ACK
758
        mov     bl, TH_SYN + TH_ACK
759
        xor     ecx, ecx
759
        xor     ecx, ecx
760
        xor     esi, esi
760
        xor     esi, esi
761
        stdcall build_tcp_packet, [sockAddr]
761
        stdcall build_tcp_packet, [sockAddr]
762
 
762
 
763
        mov     eax, NET1OUT_QUEUE
763
        mov     eax, NET1OUT_QUEUE
764
        mov     edx, [stack_ip]
764
        mov     edx, [stack_ip]
765
        mov     ecx, [sockAddr]
765
        mov     ecx, [sockAddr]
766
        cmp     edx, [ecx + SOCKET.RemoteIP]
766
        cmp     edx, [ecx + SOCKET.RemoteIP]
767
        jne     .not_local
767
        jne     .not_local
768
        mov     eax, IPIN_QUEUE
768
        mov     eax, IPIN_QUEUE
769
 
769
 
770
  .not_local:
770
  .not_local:
771
        ; Send it.
771
        ; Send it.
772
        pop     ebx
772
        pop     ebx
773
        call    queue
773
        call    queue
774
 
774
 
775
        pop     ebx
775
        pop     ebx
776
        mov     esi, [sockAddr]
776
        mov     esi, [sockAddr]
777
        mov     [esi + SOCKET.TCBState], TCB_SYN_RECEIVED
777
        mov     [esi + SOCKET.TCBState], TCB_SYN_RECEIVED
778
        call    signal_network_event
778
        call    signal_network_event
779
 
779
 
780
        ; increment SND.NXT in socket
780
        ; increment SND.NXT in socket
781
        add     esi, SOCKET.SND_NXT
781
        add     esi, SOCKET.SND_NXT
782
        call    inc_inet_esi
782
        call    inc_inet_esi
783
 
783
 
784
  .exit:
784
  .exit:
785
        ret
785
        ret
786
endp
786
endp
787
 
787
 
788
 
788
 
789
proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD
789
proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD
790
        ; We are awaiting an ACK to our SYN, with a SYM
790
        ; We are awaiting an ACK to our SYN, with a SYM
791
        ; Look at control flags - expecting an ACK
791
        ; Look at control flags - expecting an ACK
792
 
792
 
793
        mov     al, [edx + 20 + TCP_PACKET.Flags]
793
        mov     al, [edx + 20 + TCP_PACKET.Flags]
794
        and     al, TH_SYN + TH_ACK
794
        and     al, TH_SYN + TH_ACK
795
        cmp     al, TH_SYN + TH_ACK
795
        cmp     al, TH_SYN + TH_ACK
796
        je      .syn_ack
796
        je      .syn_ack
797
 
797
 
798
        test    al, TH_SYN
798
        test    al, TH_SYN
799
        jz      .exit
799
        jz      .exit
800
 
800
 
801
        mov     [ebx + SOCKET.TCBState], TCB_SYN_RECEIVED
801
        mov     [ebx + SOCKET.TCBState], TCB_SYN_RECEIVED
802
        push    TH_SYN + TH_ACK
802
        push    TH_SYN + TH_ACK
803
        jmp     .send
803
        jmp     .send
804
 
804
 
805
  .syn_ack:
805
  .syn_ack:
806
        mov     [ebx + SOCKET.TCBState], TCB_ESTABLISHED
806
        mov     [ebx + SOCKET.TCBState], TCB_ESTABLISHED
807
        push    TH_ACK
807
        push    TH_ACK
808
 
808
 
809
  .send:
809
  .send:
810
        call    signal_network_event
810
        call    signal_network_event
811
        ; Store the recv.nxt field
811
        ; Store the recv.nxt field
812
        mov     eax, [edx + 20 + TCP_PACKET.SequenceNumber]
812
        mov     eax, [edx + 20 + TCP_PACKET.SequenceNumber]
813
 
813
 
814
        ; Update our recv.nxt field
814
        ; Update our recv.nxt field
815
        mov     [ebx + SOCKET.RCV_NXT], eax
815
        mov     [ebx + SOCKET.RCV_NXT], eax
816
        lea     esi, [ebx + SOCKET.RCV_NXT]
816
        lea     esi, [ebx + SOCKET.RCV_NXT]
817
        call    inc_inet_esi
817
        call    inc_inet_esi
818
 
818
 
819
        ; Send an ACK
819
        ; Send an ACK
820
        ; Now construct the response, and queue for sending by IP
820
        ; Now construct the response, and queue for sending by IP
821
        mov     eax, EMPTY_QUEUE
821
        mov     eax, EMPTY_QUEUE
822
        call    dequeue
822
        call    dequeue
823
        cmp     ax, NO_BUFFER
823
        cmp     ax, NO_BUFFER
824
        pop     ebx
824
        pop     ebx
825
        je      .exit
825
        je      .exit
826
 
826
 
827
        push    eax
827
        push    eax
828
 
828
 
829
        xor     ecx, ecx
829
        xor     ecx, ecx
830
        xor     esi, esi
830
        xor     esi, esi
831
        stdcall build_tcp_packet, [sockAddr]
831
        stdcall build_tcp_packet, [sockAddr]
832
 
832
 
833
        mov     eax, NET1OUT_QUEUE
833
        mov     eax, NET1OUT_QUEUE
834
        mov     edx, [stack_ip]
834
        mov     edx, [stack_ip]
835
        mov     ecx, [sockAddr]
835
        mov     ecx, [sockAddr]
836
        cmp     edx, [ecx + SOCKET.RemoteIP]
836
        cmp     edx, [ecx + SOCKET.RemoteIP]
837
        jne     .not_local
837
        jne     .not_local
838
        mov     eax, IPIN_QUEUE
838
        mov     eax, IPIN_QUEUE
839
 
839
 
840
  .not_local:
840
  .not_local:
841
        ; Send it.
841
        ; Send it.
842
        pop     ebx
842
        pop     ebx
843
        call    queue
843
        call    queue
844
 
844
 
845
  .exit:
845
  .exit:
846
        ret
846
        ret
847
endp
847
endp
848
 
848
 
849
 
849
 
850
proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
850
proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
851
        ; In this case, we are expecting an ACK packet
851
        ; In this case, we are expecting an ACK packet
852
        ; For now, if the packet is an ACK, process it,
852
        ; For now, if the packet is an ACK, process it,
853
        ; If not, ignore it
853
        ; If not, ignore it
854
 
854
 
855
        test    [edx + 20 + TCP_PACKET.Flags], TH_RST
855
        test    [edx + 20 + TCP_PACKET.Flags], TH_RST
856
        jz      .check_ack
856
        jz      .check_ack
857
 
857
 
858
        push    [ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP]
858
        push    [ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP]
859
        pop     [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort]
859
        pop     [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort]
860
 
860
 
861
        mov     [ebx + SOCKET.TCBState], TCB_LISTEN
861
        mov     [ebx + SOCKET.TCBState], TCB_LISTEN
862
        jmp     .signal
862
        jmp     .signal
863
 
863
 
864
  .check_ack:
864
  .check_ack:
865
        ; Look at control flags - expecting an ACK
865
        ; Look at control flags - expecting an ACK
866
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
866
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
867
        jz      .exit
867
        jz      .exit
868
 
868
 
869
        mov     [ebx + SOCKET.TCBState], TCB_ESTABLISHED
869
        mov     [ebx + SOCKET.TCBState], TCB_ESTABLISHED
870
  .signal:
870
  .signal:
871
        call    signal_network_event
871
        call    signal_network_event
872
 
872
 
873
  .exit:
873
  .exit:
874
        ret
874
        ret
875
endp
875
endp
876
 
876
 
877
 
877
 
878
proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
878
proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
879
        ; Here we are expecting data, or a request to close
879
        ; Here we are expecting data, or a request to close
880
        ; OR both...
880
        ; OR both...
881
 
881
 
882
        ; Ignore all packets with sequnce number other than next expected
882
        ; Ignore all packets with sequnce number other than next expected
883
 
883
 
884
        ; recv.nxt is in dword [edx+24], in inet format
884
        ; recv.nxt is in dword [edx+24], in inet format
885
        ; recv seq is in [sktAddr]+56, in inet format
885
        ; recv seq is in [sktAddr]+56, in inet format
886
        ; just do a comparision
886
        ; just do a comparision
887
        mov     eax, [ebx + SOCKET.RCV_NXT]
887
        mov     eax, [ebx + SOCKET.RCV_NXT]
888
        cmp     eax, [edx + 20 + TCP_PACKET.SequenceNumber]
888
        cmp     eax, [edx + 20 + TCP_PACKET.SequenceNumber]
889
        jne     .exit
889
        jne     .exit
890
 
890
 
891
        ; Did we receive a FIN or RST?
891
        ; Did we receive a FIN or RST?
892
        test    [edx + 20 + TCP_PACKET.Flags], TH_FIN+TH_RST
892
        test    [edx + 20 + TCP_PACKET.Flags], TH_FIN+TH_RST
893
        jz      .check_ack
893
        jz      .check_ack
894
 
894
 
895
        ; It was a fin or reset.
895
        ; It was a fin or reset.
896
 
896
 
897
        ; Remove resend entries from the queue  - I dont want to send any more data
897
        ; Remove resend entries from the queue  - I dont want to send any more data
898
        pushad
898
        pushad
899
 
899
 
900
        ; get skt #
900
        ; get skt #
901
        stdcall net_socket_addr_to_num, ebx
901
        stdcall net_socket_addr_to_num, ebx
902
 
902
 
903
        mov     esi, resendQ
903
        mov     esi, resendQ
904
        mov     ecx, 0
904
        mov     ecx, 0
905
 
905
 
906
  .next_resendq:
906
  .next_resendq:
907
        cmp     ecx, NUMRESENDENTRIES
907
        cmp     ecx, NUMRESENDENTRIES
908
        je      .last_resendq       ; None left
908
        je      .last_resendq       ; None left
909
        cmp     [esi + 4], eax
909
        cmp     [esi + 4], eax
910
        je      @f                  ; found one
910
        je      @f                  ; found one
911
        inc     ecx
911
        inc     ecx
912
        add     esi, 8
912
        add     esi, 8
913
        jmp     .next_resendq
913
        jmp     .next_resendq
914
 
914
 
915
    @@:
915
    @@:
916
        mov     dword[esi + 4], 0
916
        mov     dword[esi + 4], 0
917
        inc     ecx
917
        inc     ecx
918
        add     esi, 8
918
        add     esi, 8
919
        jmp     .next_resendq
919
        jmp     .next_resendq
920
 
920
 
921
  .last_resendq:
921
  .last_resendq:
922
        popad
922
        popad
923
 
923
 
924
    @@: ; Send an ACK to that fin, and enter closewait state
924
    @@: ; Send an ACK to that fin, and enter closewait state
925
 
925
 
926
        mov     [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
926
        mov     [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
927
        test    [edx + 20 + TCP_PACKET.Flags], TH_RST
927
        test    [edx + 20 + TCP_PACKET.Flags], TH_RST
928
        je      @f
928
        je      @f
929
        mov     [ebx + SOCKET.TCBState], TCB_CLOSED
929
        mov     [ebx + SOCKET.TCBState], TCB_CLOSED
930
    @@:
930
    @@:
931
        call    signal_network_event
931
        call    signal_network_event
932
        lea     esi, [ebx + SOCKET.RCV_NXT]
932
        lea     esi, [ebx + SOCKET.RCV_NXT]
933
        mov     eax, [esi]              ; save original
933
        mov     eax, [esi]              ; save original
934
        call    inc_inet_esi
934
        call    inc_inet_esi
935
        ;; jmp    ste_ack - NO, there may be data
935
        ;; jmp    ste_ack - NO, there may be data
936
 
936
 
937
  .check_ack:
937
  .check_ack:
938
        ; Check that we received an ACK
938
        ; Check that we received an ACK
939
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
939
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
940
        jz      .exit
940
        jz      .exit
941
 
941
 
942
        ; TODO - done, I think!
942
        ; TODO - done, I think!
943
        ; First, look at the incoming window. If this is less than or equal to 1024,
943
        ; First, look at the incoming window. If this is less than or equal to 1024,
944
        ; Set the socket window timer to 1. This will stop an additional packets being queued.
944
        ; Set the socket window timer to 1. This will stop an additional packets being queued.
945
        ; ** I may need to tweak this value, since I do not know how many packets are already queued
945
        ; ** I may need to tweak this value, since I do not know how many packets are already queued
946
        mov     cx, [edx + 20 + TCP_PACKET.Window]
946
        mov     cx, [edx + 20 + TCP_PACKET.Window]
947
        xchg    cl, ch
947
        xchg    cl, ch
948
        cmp     cx, 1024
948
        cmp     cx, 1024
949
        ja      @f
949
        ja      @f
950
 
950
 
951
        mov     [ebx + SOCKET.wndsizeTimer], 1
951
        mov     [ebx + SOCKET.wndsizeTimer], 1
952
 
952
 
953
    @@: ; OK, here is the deal
953
    @@: ; OK, here is the deal
954
 
954
 
955
 
955
 
956
        ; Read the data bytes, store in socket buffer
956
        ; Read the data bytes, store in socket buffer
957
        movzx   ecx, [edx + IP_PACKET.TotalLength]
957
        movzx   ecx, [edx + IP_PACKET.TotalLength]
958
        xchg    cl, ch
958
        xchg    cl, ch
959
        sub     ecx, 40                    ; Discard 40 bytes of header
959
        sub     ecx, 40                    ; Discard 40 bytes of header
960
        ja      .data                      ; Read data, if any
960
        ja      .data                      ; Read data, if any
961
 
961
 
962
        ; If we had received a fin, we need to ACK it.
962
        ; If we had received a fin, we need to ACK it.
963
        cmp     [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
963
        cmp     [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
964
        je      .ack
964
        je      .ack
965
        jmp     .exit
965
        jmp     .exit
966
 
966
 
967
  .data:
967
  .data:
968
        push    ecx
968
        push    ecx
969
        push    ecx edx
969
        push    ecx edx
970
        lea     ecx, [ebx+SOCKET.lock]
970
        lea     ecx, [ebx+SOCKET.mutex]
971
        call    mutex_lock
971
        call    mutex_lock
972
        pop     edx ecx
972
        pop     edx ecx
973
 
973
 
974
        push    ebx
974
        push    ebx
975
        mov     eax, [ebx + SOCKET.rxDataCount]
975
        mov     eax, [ebx + SOCKET.rxDataCount]
976
        add     eax, ecx
976
        add     eax, ecx
977
        cmp     eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE
977
        cmp     eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE
978
        ja      .overflow
978
        ja      .overflow
979
 
979
 
980
        mov     [ebx + SOCKET.rxDataCount], eax      ; increment the count of bytes in buffer
980
        mov     [ebx + SOCKET.rxDataCount], eax      ; increment the count of bytes in buffer
981
 
981
 
982
        ; point to the location to store the data
982
        ; point to the location to store the data
983
        lea     edi, [ebx + eax + SOCKETHEADERSIZE]
983
        lea     edi, [ebx + eax + SOCKETHEADERSIZE]
984
        sub     edi, ecx
984
        sub     edi, ecx
985
 
985
 
986
        add     edx, 40        ; edx now points to the data
986
        add     edx, 40        ; edx now points to the data
987
        mov     esi, edx
987
        mov     esi, edx
988
 
988
 
989
        cld
989
        cld
990
        rep movsb              ; copy the data across
990
        rep movsb              ; copy the data across
991
 
991
 
992
        lea     ecx, [ebx + SOCKET.lock]
992
        lea     ecx, [ebx + SOCKET.mutex]
993
        call    mutex_unlock
993
        call    mutex_unlock
994
 
994
 
995
        ; flag an event to the application
995
        ; flag an event to the application
996
        pop     ebx
996
        pop     ebx
997
        call    signal_network_event
997
        call    signal_network_event
998
 
998
 
999
        pop     ecx
999
        pop     ecx
1000
 
1000
 
1001
        ; Update our recv.nxt field
1001
        ; Update our recv.nxt field
1002
        lea     esi, [ebx + SOCKET.RCV_NXT]
1002
        lea     esi, [ebx + SOCKET.RCV_NXT]
1003
        call    add_inet_esi
1003
        call    add_inet_esi
1004
 
1004
 
1005
  .ack:
1005
  .ack:
1006
        ; Send an ACK
1006
        ; Send an ACK
1007
        ; Now construct the response, and queue for sending by IP
1007
        ; Now construct the response, and queue for sending by IP
1008
        mov     eax, EMPTY_QUEUE
1008
        mov     eax, EMPTY_QUEUE
1009
        call    dequeue
1009
        call    dequeue
1010
        cmp     ax, NO_BUFFER
1010
        cmp     ax, NO_BUFFER
1011
        je      .exit
1011
        je      .exit
1012
 
1012
 
1013
        push    eax
1013
        push    eax
1014
 
1014
 
1015
        mov     bl, TH_ACK
1015
        mov     bl, TH_ACK
1016
        xor     ecx, ecx
1016
        xor     ecx, ecx
1017
        xor     esi, esi
1017
        xor     esi, esi
1018
        stdcall build_tcp_packet, [sockAddr]
1018
        stdcall build_tcp_packet, [sockAddr]
1019
 
1019
 
1020
        mov     eax, NET1OUT_QUEUE
1020
        mov     eax, NET1OUT_QUEUE
1021
 
1021
 
1022
        mov     edx, [stack_ip]
1022
        mov     edx, [stack_ip]
1023
        mov     ecx, [sockAddr]
1023
        mov     ecx, [sockAddr]
1024
        cmp     edx, [ecx + SOCKET.RemoteIP]
1024
        cmp     edx, [ecx + SOCKET.RemoteIP]
1025
        jne     .not_local
1025
        jne     .not_local
1026
        mov     eax, IPIN_QUEUE
1026
        mov     eax, IPIN_QUEUE
1027
 
1027
 
1028
  .not_local:
1028
  .not_local:
1029
        ; Send it.
1029
        ; Send it.
1030
        pop     ebx
1030
        pop     ebx
1031
        call    queue
1031
        call    queue
1032
 
1032
 
1033
  .exit:
1033
  .exit:
1034
        ret
1034
        ret
1035
  .overflow:
1035
  .overflow:
1036
        ; no place in buffer
1036
        ; no place in buffer
1037
        ; so simply restore stack and exit
1037
        ; so simply restore stack and exit
1038
        lea     ecx, [ebx + SOCKET.lock]
1038
        lea     ecx, [ebx + SOCKET.mutex]
1039
        call    mutex_unlock
1039
        call    mutex_unlock
1040
        pop     eax ecx
1040
        pop     eax ecx
1041
        ret
1041
        ret
1042
endp
1042
endp
1043
 
1043
 
1044
 
1044
 
1045
proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD
1045
proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD
1046
        ; We can either receive an ACK of a fin, or a fin
1046
        ; We can either receive an ACK of a fin, or a fin
1047
        mov     al, [edx + 20 + TCP_PACKET.Flags]
1047
        mov     al, [edx + 20 + TCP_PACKET.Flags]
1048
        and     al, TH_FIN + TH_ACK
1048
        and     al, TH_FIN + TH_ACK
1049
 
1049
 
1050
        cmp     al, TH_ACK
1050
        cmp     al, TH_ACK
1051
        jne     @f
1051
        jne     @f
1052
 
1052
 
1053
        ; It was an ACK
1053
        ; It was an ACK
1054
        mov     [ebx + SOCKET.TCBState], TCB_FIN_WAIT_2
1054
        mov     [ebx + SOCKET.TCBState], TCB_FIN_WAIT_2
1055
        jmp     .exit
1055
        jmp     .exit
1056
 
1056
 
1057
    @@:
1057
    @@:
1058
        mov     [ebx + SOCKET.TCBState], TCB_CLOSING
1058
        mov     [ebx + SOCKET.TCBState], TCB_CLOSING
1059
        cmp     al, TH_FIN
1059
        cmp     al, TH_FIN
1060
        je      @f
1060
        je      @f
1061
        mov     [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1061
        mov     [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1062
 
1062
 
1063
    @@:
1063
    @@:
1064
        lea     esi, [ebx + SOCKET.RCV_NXT]
1064
        lea     esi, [ebx + SOCKET.RCV_NXT]
1065
        call    inc_inet_esi
1065
        call    inc_inet_esi
1066
 
1066
 
1067
        ; Send an ACK
1067
        ; Send an ACK
1068
        mov     eax, EMPTY_QUEUE
1068
        mov     eax, EMPTY_QUEUE
1069
        call    dequeue
1069
        call    dequeue
1070
        cmp     ax, NO_BUFFER
1070
        cmp     ax, NO_BUFFER
1071
        je      .exit
1071
        je      .exit
1072
 
1072
 
1073
        push    eax
1073
        push    eax
1074
 
1074
 
1075
        mov     bl, TH_ACK
1075
        mov     bl, TH_ACK
1076
        xor     ecx, ecx
1076
        xor     ecx, ecx
1077
        xor     esi, esi
1077
        xor     esi, esi
1078
        stdcall build_tcp_packet, [sockAddr]
1078
        stdcall build_tcp_packet, [sockAddr]
1079
 
1079
 
1080
        mov     eax, NET1OUT_QUEUE
1080
        mov     eax, NET1OUT_QUEUE
1081
        mov     edx, [stack_ip]
1081
        mov     edx, [stack_ip]
1082
        mov     ecx, [sockAddr]
1082
        mov     ecx, [sockAddr]
1083
        cmp     edx, [ecx + SOCKET.RemoteIP]
1083
        cmp     edx, [ecx + SOCKET.RemoteIP]
1084
        jne     .not_local
1084
        jne     .not_local
1085
        mov     eax, IPIN_QUEUE
1085
        mov     eax, IPIN_QUEUE
1086
 
1086
 
1087
  .not_local:
1087
  .not_local:
1088
        ; Send it.
1088
        ; Send it.
1089
        pop     ebx
1089
        pop     ebx
1090
        call    queue
1090
        call    queue
1091
 
1091
 
1092
  .exit:
1092
  .exit:
1093
        ret
1093
        ret
1094
endp
1094
endp
1095
 
1095
 
1096
 
1096
 
1097
proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD
1097
proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD
1098
        test    [edx + 20 + TCP_PACKET.Flags], TH_FIN
1098
        test    [edx + 20 + TCP_PACKET.Flags], TH_FIN
1099
        jz      .exit
1099
        jz      .exit
1100
 
1100
 
1101
        ; Change state, as we have a fin
1101
        ; Change state, as we have a fin
1102
        mov     [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1102
        mov     [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1103
 
1103
 
1104
        lea     esi, [ebx + SOCKET.RCV_NXT]
1104
        lea     esi, [ebx + SOCKET.RCV_NXT]
1105
        call    inc_inet_esi
1105
        call    inc_inet_esi
1106
 
1106
 
1107
        ; Send an ACK
1107
        ; Send an ACK
1108
        mov     eax, EMPTY_QUEUE
1108
        mov     eax, EMPTY_QUEUE
1109
        call    dequeue
1109
        call    dequeue
1110
        cmp     ax, NO_BUFFER
1110
        cmp     ax, NO_BUFFER
1111
        je      .exit
1111
        je      .exit
1112
 
1112
 
1113
        push    eax
1113
        push    eax
1114
 
1114
 
1115
        mov     bl, TH_ACK
1115
        mov     bl, TH_ACK
1116
        xor     ecx, ecx
1116
        xor     ecx, ecx
1117
        xor     esi, esi
1117
        xor     esi, esi
1118
        stdcall build_tcp_packet, [sockAddr]
1118
        stdcall build_tcp_packet, [sockAddr]
1119
 
1119
 
1120
        mov     eax, NET1OUT_QUEUE
1120
        mov     eax, NET1OUT_QUEUE
1121
        mov     edx, [stack_ip]
1121
        mov     edx, [stack_ip]
1122
        mov     ecx, [sockAddr]
1122
        mov     ecx, [sockAddr]
1123
        cmp     edx, [ecx + SOCKET.RemoteIP]
1123
        cmp     edx, [ecx + SOCKET.RemoteIP]
1124
        jne     .not_local
1124
        jne     .not_local
1125
        mov     eax, IPIN_QUEUE
1125
        mov     eax, IPIN_QUEUE
1126
 
1126
 
1127
  .not_local:
1127
  .not_local:
1128
        ; Send it.
1128
        ; Send it.
1129
        pop     ebx
1129
        pop     ebx
1130
        call    queue
1130
        call    queue
1131
 
1131
 
1132
  .exit:
1132
  .exit:
1133
        ret
1133
        ret
1134
endp
1134
endp
1135
 
1135
 
1136
 
1136
 
1137
proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD
1137
proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD
1138
        ; Intentionally left empty
1138
        ; Intentionally left empty
1139
        ; socket_close_tcp handles this
1139
        ; socket_close_tcp handles this
1140
        ret
1140
        ret
1141
endp
1141
endp
1142
 
1142
 
1143
 
1143
 
1144
proc stateTCB_CLOSING stdcall, sockAddr:DWORD
1144
proc stateTCB_CLOSING stdcall, sockAddr:DWORD
1145
        ; We can either receive an ACK of a fin, or a fin
1145
        ; We can either receive an ACK of a fin, or a fin
1146
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
1146
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
1147
        jz      .exit
1147
        jz      .exit
1148
 
1148
 
1149
        mov     [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1149
        mov     [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
1150
 
1150
 
1151
  .exit:
1151
  .exit:
1152
        ret
1152
        ret
1153
endp
1153
endp
1154
 
1154
 
1155
 
1155
 
1156
proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD
1156
proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD
1157
        ; Look at control flags - expecting an ACK
1157
        ; Look at control flags - expecting an ACK
1158
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
1158
        test    [edx + 20 + TCP_PACKET.Flags], TH_ACK
1159
        jz      .exit
1159
        jz      .exit
1160
 
1160
 
1161
        ; delete the socket
1161
        ; delete the socket
1162
        stdcall net_socket_free, ebx
1162
        stdcall net_socket_free, ebx
1163
 
1163
 
1164
  .exit:
1164
  .exit:
1165
        ret
1165
        ret
1166
endp
1166
endp
1167
 
1167
 
1168
 
1168
 
1169
proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD
1169
proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD
1170
        ret
1170
        ret
1171
endp
1171
endp
1172
 
1172
 
1173
 
1173
 
1174
proc stateTCB_CLOSED stdcall, sockAddr:DWORD
1174
proc stateTCB_CLOSED stdcall, sockAddr:DWORD
1175
        ret
1175
        ret
1176
endp
1176
endp