Subversion Repositories Kolibri OS

Rev

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

Rev 425 Rev 431
1
$Revision: 425 $
1
$Revision: 431 $
2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;
-
 
-
 
3
;;                                                              ;;
-
 
4
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
-
 
5
;; Distributed under terms of the GNU General Public License    ;;
-
 
6
;;                                                              ;;
4
;;  SOCKET.INC
7
;;  SOCKET.INC                                                  ;;
5
;;
-
 
-
 
8
;;                                                              ;;
6
;;  Sockets constants, structures and functions
9
;;  Sockets constants, structures and functions                 ;;
7
;;
-
 
-
 
10
;;                                                              ;;
8
;;  Last revision: 11.11.2006
11
;;  Last revision: 11.11.2006                                   ;;
9
;;
-
 
-
 
12
;;                                                              ;;
10
;;  This file contains the following:
13
;;  This file contains the following:                           ;;
11
;;    is_localport_unused
14
;;    is_localport_unused                                       ;;
12
;;    get_free_socket
15
;;    get_free_socket                                           ;;
13
;;    socket_open
16
;;    socket_open                                               ;;
14
;;    socket_open_tcp
17
;;    socket_open_tcp                                           ;;
15
;;    socket_close
18
;;    socket_close                                              ;;
16
;;    socket_close_tcp
19
;;    socket_close_tcp                                          ;;
17
;;    socket_poll
20
;;    socket_poll                                               ;;
18
;;    socket_status
21
;;    socket_status                                             ;;
19
;;    socket_read
22
;;    socket_read                                               ;;
20
;;    socket_write
23
;;    socket_write                                              ;;
21
;;    socket_write_tcp
24
;;    socket_write_tcp                                          ;;
22
;;
-
 
23
;;
-
 
-
 
25
;;                                                              ;;
-
 
26
;;                                                              ;;
24
;;  Changes history:
27
;;  Changes history:                                            ;;
25
;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net
28
;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
26
;;   11.11.2006 - [Johnny_B] and [smb]
29
;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
27
;;
-
 
-
 
30
;;                                                              ;;
28
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
29
 
32
 
30
;
33
;
31
;  Socket Descriptor + Buffer
34
;  Socket Descriptor + Buffer
32
;
35
;
33
;    0                   1                   2                   3
36
;    0                   1                   2                   3
34
;    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
37
;    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
35
;
38
;
36
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37
;  0|                    Status ( of this buffer )                  |
40
;  0|                    Status ( of this buffer )                  |
38
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39
;  4|  Application Process ID                                       |
42
;  4|  Application Process ID                                       |
40
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41
;  8|                  Local IP Address                             |
44
;  8|                  Local IP Address                             |
42
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43
; 12| Local IP Port                 | Unused ( set to 0 )           |
46
; 12| Local IP Port                 | Unused ( set to 0 )           |
44
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45
; 16|                  Remote IP Address                            |
48
; 16|                  Remote IP Address                            |
46
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
; 20| Remote IP Port                | Unused ( set to 0 )           |
50
; 20| Remote IP Port                | Unused ( set to 0 )           |
48
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49
; 24|   Rx Data Count                                   INTEL format|
52
; 24|   Rx Data Count                                   INTEL format|
50
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51
; 28|                 TCB STATE                         INTEL format|
54
; 28|                 TCB STATE                         INTEL format|
52
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53
; 32|   TCB Timer (seconds)                             INTEL format|
56
; 32|   TCB Timer (seconds)                             INTEL format|
54
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55
; 36| ISS (Inital Sequence # used by this connection )   INET format|
58
; 36| ISS (Inital Sequence # used by this connection )   INET format|
56
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57
; 40| IRS ( Inital Receive Sequence # )                  INET format|
60
; 40| IRS ( Inital Receive Sequence # )                  INET format|
58
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
; 44| SND.UNA  Seq # of unack'ed sent packets            INET format|
62
; 44| SND.UNA  Seq # of unack'ed sent packets            INET format|
60
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61
; 48| SND.NXT  Next send seq # to use                    INET format|
64
; 48| SND.NXT  Next send seq # to use                    INET format|
62
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
; 52| SND.WND  Send window                               INET format|
66
; 52| SND.WND  Send window                               INET format|
64
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65
; 56| RCV.NXT  Next expected receive sequence #          INET format|
68
; 56| RCV.NXT  Next expected receive sequence #          INET format|
66
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67
; 60| RCV.WND  Receive window                            INET format|
70
; 60| RCV.WND  Receive window                            INET format|
68
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69
; 64| SEG.LEN  Segment length                           INTEL format|
72
; 64| SEG.LEN  Segment length                           INTEL format|
70
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71
; 68| SEG.WND  Segment window                           INTEL format|
74
; 68| SEG.WND  Segment window                           INTEL format|
72
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73
; 72| Retransmit queue # NOW WINDOW SIZE TIMER          INTEL format|
76
; 72| Retransmit queue # NOW WINDOW SIZE TIMER          INTEL format|
74
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
; 76|      RX offset from
78
; 76|      RX offset from
76
; 76|       RX Data                                                 |
79
; 76|       RX Data                                                 |
77
;   +-+-+-..........                                               -+
80
;   +-+-+-..........                                               -+
78
 
81
 
79
 
82
 
80
; so, define struct
83
; so, define struct
81
struc SOCKET
84
struc SOCKET
82
{  .Status		    dd	 ?  ;+00 - Status ( of this buffer )
85
{  .Status		    dd	 ?  ;+00 - Status ( of this buffer )
83
   .PID 		    dd	 ?  ;+04 - Application Process ID
86
   .PID 		    dd	 ?  ;+04 - Application Process ID
84
   .LocalIP		    dd	 ?  ;+08 -  Local IP Address
87
   .LocalIP		    dd	 ?  ;+08 -  Local IP Address
85
   .LocalPort		    dw	 ?  ;+12 - Local Port
88
   .LocalPort		    dw	 ?  ;+12 - Local Port
86
   .UnusedL		    dw	 ?  ;+14 - may be removed in future
89
   .UnusedL		    dw	 ?  ;+14 - may be removed in future
87
   .RemoteIP		    dd	 ?  ;+16 - Remote IP Address
90
   .RemoteIP		    dd	 ?  ;+16 - Remote IP Address
88
   .RemotePort		    dw	 ?  ;+20 - Remote Port
91
   .RemotePort		    dw	 ?  ;+20 - Remote Port
89
   .UnusedR		    dw	 ?  ;+22 - may be removed in future
92
   .UnusedR		    dw	 ?  ;+22 - may be removed in future
90
   .rxDataCount 	    dd	 ?  ;+24 - Rx Data Count
93
   .rxDataCount 	    dd	 ?  ;+24 - Rx Data Count
91
   .TCBState		    dd	 ?  ;+28 - TCB STATE
94
   .TCBState		    dd	 ?  ;+28 - TCB STATE
92
   .TCBTimer		    dd	 ?  ;+32 - TCB Timer (seconds)
95
   .TCBTimer		    dd	 ?  ;+32 - TCB Timer (seconds)
93
   .ISS 		    dd	 ?  ;+36 - Initial Send Sequence
96
   .ISS 		    dd	 ?  ;+36 - Initial Send Sequence
94
   .IRS 		    dd	 ?  ;+40 - Initial Receive Sequence
97
   .IRS 		    dd	 ?  ;+40 - Initial Receive Sequence
95
   .SND_UNA		    dd	 ?  ;+44 - Sequence number of unack'ed sent packets
98
   .SND_UNA		    dd	 ?  ;+44 - Sequence number of unack'ed sent packets
96
   .SND_NXT		    dd	 ?  ;+48 - Next send sequence number to use
99
   .SND_NXT		    dd	 ?  ;+48 - Next send sequence number to use
97
   .SND_WND		    dd	 ?  ;+52 - Send window
100
   .SND_WND		    dd	 ?  ;+52 - Send window
98
   .RCV_NXT		    dd	 ?  ;+56 - Next receive sequence number to use
101
   .RCV_NXT		    dd	 ?  ;+56 - Next receive sequence number to use
99
   .RCV_WND		    dd	 ?  ;+60 - Receive window
102
   .RCV_WND		    dd	 ?  ;+60 - Receive window
100
   .SEG_LEN		    dd	 ?  ;+64 - Segment length
103
   .SEG_LEN		    dd	 ?  ;+64 - Segment length
101
   .SEG_WND		    dd	 ?  ;+68 - Segment window
104
   .SEG_WND		    dd	 ?  ;+68 - Segment window
102
   .wndsizeTimer	    dd	 ?  ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER
105
   .wndsizeTimer	    dd	 ?  ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER
103
   .rxData		    dd	 ?  ;+76 - receive data buffer here
106
   .rxData		    dd	 ?  ;+76 - receive data buffer here
104
}
107
}
105
 
108
 
106
virtual at 0
109
virtual at 0
107
  SOCKET SOCKET
110
  SOCKET SOCKET
108
end virtual
111
end virtual
109
 
112
 
110
; simple macro calcing real memory address of SOCKET struct by socket's
113
; simple macro calcing real memory address of SOCKET struct by socket's
111
macro	Index2RealAddr reg
114
macro	Index2RealAddr reg
112
{
115
{
113
	shl	reg, 12
116
	shl	reg, 12
114
    add     reg, sockets
117
    add     reg, sockets
115
}
118
}
116
 
119
 
117
;Constants
120
;Constants
118
; current socket statuses
121
; current socket statuses
119
SOCK_EMPTY	   equ	   0	    ; socket not in use
122
SOCK_EMPTY	   equ	   0	    ; socket not in use
120
SOCK_OPEN	   equ	   1	    ; open issued, but no data sent
123
SOCK_OPEN	   equ	   1	    ; open issued, but no data sent
121
 
124
 
122
; TCP opening modes
125
; TCP opening modes
123
SOCKET_PASSIVE	   equ	   0
126
SOCKET_PASSIVE	   equ	   0
124
SOCKET_ACTIVE	   equ	   1
127
SOCKET_ACTIVE	   equ	   1
125
 
128
 
126
;***************************************************************************
129
;***************************************************************************
127
;   Function
130
;   Function
128
;      is_localport_unused
131
;      is_localport_unused
129
;
132
;
130
;   Description
133
;   Description
131
;         scans through all the active sockets , looking to see if the
134
;         scans through all the active sockets , looking to see if the
132
;      port number specified in bx is in use as a localport number.
135
;      port number specified in bx is in use as a localport number.
133
;      This is useful when you want a to generate a unique local port
136
;      This is useful when you want a to generate a unique local port
134
;      number.
137
;      number.
135
;          On return, eax = 1 for free, 0 for in use
138
;          On return, eax = 1 for free, 0 for in use
136
;
139
;
137
;***************************************************************************
140
;***************************************************************************
138
is_localport_unused:
141
is_localport_unused:
139
    mov     al, bh
142
    mov     al, bh
140
    mov     ah, bl
143
    mov     ah, bl
141
    mov     bx, ax
144
    mov     bx, ax
142
 
145
 
143
    mov     edx, SOCKETBUFFSIZE * NUM_SOCKETS
146
    mov     edx, SOCKETBUFFSIZE * NUM_SOCKETS
144
    mov     ecx, NUM_SOCKETS
147
    mov     ecx, NUM_SOCKETS
145
    mov     eax, 0		      ; Assume the return value is 'in use'
148
    mov     eax, 0		      ; Assume the return value is 'in use'
146
 
149
 
147
ilu1:
150
ilu1:
148
    sub     edx, SOCKETBUFFSIZE
151
    sub     edx, SOCKETBUFFSIZE
149
    cmp     [edx + sockets + SOCKET.LocalPort], bx
152
    cmp     [edx + sockets + SOCKET.LocalPort], bx
150
    loopnz  ilu1		  ; Return back if the socket is occupied
153
    loopnz  ilu1		  ; Return back if the socket is occupied
151
 
154
 
152
    jz	    ilu_exit
155
    jz	    ilu_exit
153
    inc     eax 			; return port not in use
156
    inc     eax 			; return port not in use
154
 
157
 
155
ilu_exit:
158
ilu_exit:
156
    ret
159
    ret
157
 
160
 
158
 
161
 
159
 
162
 
160
;***************************************************************************
163
;***************************************************************************
161
;   Function
164
;   Function
162
;      get_free_socket
165
;      get_free_socket
163
;
166
;
164
;   Description
167
;   Description
165
;
168
;
166
;***************************************************************************
169
;***************************************************************************
167
get_free_socket:
170
get_free_socket:
168
    push    ecx
171
    push    ecx
169
    mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
172
    mov     eax, SOCKETBUFFSIZE * NUM_SOCKETS
170
    mov     ecx, NUM_SOCKETS
173
    mov     ecx, NUM_SOCKETS
171
 
174
 
172
gfs1:
175
gfs1:
173
    sub     eax, SOCKETBUFFSIZE
176
    sub     eax, SOCKETBUFFSIZE
174
    cmp     [eax + sockets + SOCKET.Status], dword SOCK_EMPTY
177
    cmp     [eax + sockets + SOCKET.Status], dword SOCK_EMPTY
175
    loopnz  gfs1		  ; Return back if the socket is occupied
178
    loopnz  gfs1		  ; Return back if the socket is occupied
176
    mov     eax, ecx
179
    mov     eax, ecx
177
    pop     ecx
180
    pop     ecx
178
    jz	    gfs_exit
181
    jz	    gfs_exit
179
    mov     eax, 0xFFFFFFFF
182
    mov     eax, 0xFFFFFFFF
180
 
183
 
181
gfs_exit:
184
gfs_exit:
182
    ret
185
    ret
183
 
186
 
184
 
187
 
185
;***************************************************************************
188
;***************************************************************************
186
;   Function
189
;   Function
187
;      socket_open
190
;      socket_open
188
;
191
;
189
;   Description
192
;   Description
190
;       find a free socket
193
;       find a free socket
191
;       local port in ebx
194
;       local port in ebx
192
;       remote port in ecx
195
;       remote port in ecx
193
;       remote ip in edx
196
;       remote ip in edx
194
;       return socket # in eax, -1 if none available
197
;       return socket # in eax, -1 if none available
195
;
198
;
196
;***************************************************************************
199
;***************************************************************************
197
socket_open:
200
socket_open:
198
    call    get_free_socket
201
    call    get_free_socket
199
 
202
 
200
    cmp     eax, 0xFFFFFFFF
203
    cmp     eax, 0xFFFFFFFF
201
    jz	    so_exit
204
    jz	    so_exit
202
 
205
 
203
    ; ax holds the socket number that is free. Get real address
206
    ; ax holds the socket number that is free. Get real address
204
    push    eax
207
    push    eax
205
    Index2RealAddr eax
208
    Index2RealAddr eax
206
 
209
 
207
    mov     [eax + SOCKET.Status], dword SOCK_OPEN
210
    mov     [eax + SOCKET.Status], dword SOCK_OPEN
208
 
211
 
209
    xchg    bh, bl
212
    xchg    bh, bl
210
    mov     [eax + SOCKET.LocalPort], bx
213
    mov     [eax + SOCKET.LocalPort], bx
211
    xchg    ch, cl
214
    xchg    ch, cl
212
    mov     [eax + SOCKET.RemotePort], cx
215
    mov     [eax + SOCKET.RemotePort], cx
213
 
216
 
214
    mov     ebx, [stack_ip]
217
    mov     ebx, [stack_ip]
215
    mov     [eax + SOCKET.LocalIP], ebx
218
    mov     [eax + SOCKET.LocalIP], ebx
216
    mov     [eax + SOCKET.RemoteIP], edx
219
    mov     [eax + SOCKET.RemoteIP], edx
217
    mov     [eax + SOCKET.rxDataCount], dword 0      ; recieved data count
220
    mov     [eax + SOCKET.rxDataCount], dword 0      ; recieved data count
218
 
221
 
219
    mov     esi, [TASK_BASE]
222
    mov     esi, [TASK_BASE]
220
    mov     ebx, [esi+TASKDATA.pid]
223
    mov     ebx, [esi+TASKDATA.pid]
221
    mov     [eax + SOCKET.PID], ebx	    ; save the process ID
224
    mov     [eax + SOCKET.PID], ebx	    ; save the process ID
222
    pop     eax      ; Get the socket number back, so we can return it
225
    pop     eax      ; Get the socket number back, so we can return it
223
 
226
 
224
so_exit:
227
so_exit:
225
    ret
228
    ret
226
 
229
 
227
 
230
 
228
 
231
 
229
;***************************************************************************
232
;***************************************************************************
230
;   Function
233
;   Function
231
;      socket_open_tcp
234
;      socket_open_tcp
232
;
235
;
233
;   Description
236
;   Description
234
;       Opens a TCP socket in PASSIVE or ACTIVE mode
237
;       Opens a TCP socket in PASSIVE or ACTIVE mode
235
;       find a free socket
238
;       find a free socket
236
;       local port in ebx ( intel format )
239
;       local port in ebx ( intel format )
237
;       remote port in ecx ( intel format )
240
;       remote port in ecx ( intel format )
238
;       remote ip in edx ( in Internet byte order )
241
;       remote ip in edx ( in Internet byte order )
239
;       Socket open mode in esi  ( SOCKET_PASSIVE or SOCKET_ACTIVE )
242
;       Socket open mode in esi  ( SOCKET_PASSIVE or SOCKET_ACTIVE )
240
;       return socket # in eax, -1 if none available
243
;       return socket # in eax, -1 if none available
241
;
244
;
242
;***************************************************************************
245
;***************************************************************************
243
socket_open_tcp:
246
socket_open_tcp:
244
    call    get_free_socket
247
    call    get_free_socket
245
 
248
 
246
    cmp     eax, 0xFFFFFFFF
249
    cmp     eax, 0xFFFFFFFF
247
    jz	    so_exit
250
    jz	    so_exit
248
 
251
 
249
    ; ax holds the socket number that is free. Get real address
252
    ; ax holds the socket number that is free. Get real address
250
    push eax
253
    push eax
251
    Index2RealAddr eax
254
    Index2RealAddr eax
252
 
255
 
253
    mov     [sktAddr], eax
256
    mov     [sktAddr], eax
254
    mov     [eax], dword SOCK_OPEN
257
    mov     [eax], dword SOCK_OPEN
255
 
258
 
256
    ; TODO - check this works!
259
    ; TODO - check this works!
257
    mov     [eax + SOCKET.wndsizeTimer], dword 0     ; Reset the window timer.
260
    mov     [eax + SOCKET.wndsizeTimer], dword 0     ; Reset the window timer.
258
 
261
 
259
	xchg	bh, bl
262
	xchg	bh, bl
260
	mov	[eax + SOCKET.LocalPort], bx
263
	mov	[eax + SOCKET.LocalPort], bx
261
;    mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
264
;    mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
262
;    mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
265
;    mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
263
 
266
 
264
	xchg	ch, cl
267
	xchg	ch, cl
265
	mov	[eax + SOCKET.RemotePort], cx
268
	mov	[eax + SOCKET.RemotePort], cx
266
;    mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
269
;    mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
267
;    mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
270
;    mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
268
 
271
 
269
    mov     ebx, [stack_ip]
272
    mov     ebx, [stack_ip]
270
    mov     [eax + SOCKET.LocalIP], ebx
273
    mov     [eax + SOCKET.LocalIP], ebx
271
    mov     [eax + SOCKET.RemoteIP], edx
274
    mov     [eax + SOCKET.RemoteIP], edx
272
    mov     [eax + SOCKET.rxDataCount], dword 0
275
    mov     [eax + SOCKET.rxDataCount], dword 0
273
 
276
 
274
    ; Now fill in TCB state
277
    ; Now fill in TCB state
275
    mov     ebx, TCB_LISTEN
278
    mov     ebx, TCB_LISTEN
276
    cmp     esi, SOCKET_PASSIVE
279
    cmp     esi, SOCKET_PASSIVE
277
    jz	    sot_001
280
    jz	    sot_001
278
    mov     ebx, TCB_SYN_SENT
281
    mov     ebx, TCB_SYN_SENT
279
 
282
 
280
sot_001:
283
sot_001:
281
    mov     [eax + SOCKET.TCBState], ebx	    ; Indicate the state of the TCB
284
    mov     [eax + SOCKET.TCBState], ebx	    ; Indicate the state of the TCB
282
 
285
 
283
    mov     esi, [TASK_BASE]
286
    mov     esi, [TASK_BASE]
284
    mov     ecx, [esi+TASKDATA.pid]
287
    mov     ecx, [esi+TASKDATA.pid]
285
    mov     [eax + SOCKET.PID], ecx	    ; save the process ID
288
    mov     [eax + SOCKET.PID], ecx	    ; save the process ID
286
 
289
 
287
    cmp     ebx, TCB_LISTEN
290
    cmp     ebx, TCB_LISTEN
288
    je	    sot_done
291
    je	    sot_done
289
 
292
 
290
    ; Now, if we are in active mode, then we have to send a SYN to the specified remote port
293
    ; Now, if we are in active mode, then we have to send a SYN to the specified remote port
291
    mov     eax, EMPTY_QUEUE
294
    mov     eax, EMPTY_QUEUE
292
    call    dequeue
295
    call    dequeue
293
    cmp     ax, NO_BUFFER
296
    cmp     ax, NO_BUFFER
294
    je	    sot_done
297
    je	    sot_done
295
 
298
 
296
    push    eax
299
    push    eax
297
 
300
 
298
    mov     bl, 0x02	    ; SYN
301
    mov     bl, 0x02	    ; SYN
299
    mov     ecx, 0
302
    mov     ecx, 0
300
 
303
 
301
    call    buildTCPPacket
304
    call    buildTCPPacket
302
 
305
 
303
    mov     eax, NET1OUT_QUEUE
306
    mov     eax, NET1OUT_QUEUE
304
 
307
 
305
    mov     edx, [stack_ip]
308
    mov     edx, [stack_ip]
306
    mov     ecx, [sktAddr ]
309
    mov     ecx, [sktAddr ]
307
    mov     ecx, [ecx + 16]
310
    mov     ecx, [ecx + 16]
308
    cmp     edx, ecx
311
    cmp     edx, ecx
309
    jne     sot_notlocal
312
    jne     sot_notlocal
310
    mov     eax, IPIN_QUEUE
313
    mov     eax, IPIN_QUEUE
311
 
314
 
312
sot_notlocal:
315
sot_notlocal:
313
       ; Send it.
316
       ; Send it.
314
    pop     ebx
317
    pop     ebx
315
    call    queue
318
    call    queue
316
 
319
 
317
    mov     esi, [sktAddr]
320
    mov     esi, [sktAddr]
318
 
321
 
319
    ; increment SND.NXT in socket
322
    ; increment SND.NXT in socket
320
    add     esi, 48
323
    add     esi, 48
321
    call    inc_inet_esi
324
    call    inc_inet_esi
322
 
325
 
323
sot_done:
326
sot_done:
324
    pop     eax      ; Get the socket number back, so we can return it
327
    pop     eax      ; Get the socket number back, so we can return it
325
 
328
 
326
sot_exit:
329
sot_exit:
327
    ret
330
    ret
328
 
331
 
329
 
332
 
330
 
333
 
331
;***************************************************************************
334
;***************************************************************************
332
;   Function
335
;   Function
333
;      socket_close
336
;      socket_close
334
;
337
;
335
;   Description
338
;   Description
336
;       socket # in ebx
339
;       socket # in ebx
337
;       returns 0 for ok, -1 for socket not open (fail)
340
;       returns 0 for ok, -1 for socket not open (fail)
338
;
341
;
339
;***************************************************************************
342
;***************************************************************************
340
socket_close:
343
socket_close:
341
    Index2RealAddr ebx
344
    Index2RealAddr ebx
342
    mov     eax, 0xFFFFFFFF	    ; assume this operation will fail..
345
    mov     eax, 0xFFFFFFFF	    ; assume this operation will fail..
343
    cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
346
    cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
344
    jz	    sc_exit
347
    jz	    sc_exit
345
 
348
 
346
    ; Clear the socket varaibles
349
    ; Clear the socket varaibles
347
    xor     eax, eax
350
    xor     eax, eax
348
    mov     edi, ebx
351
    mov     edi, ebx
349
    mov     ecx, SOCKETHEADERSIZE
352
    mov     ecx, SOCKETHEADERSIZE
350
    cld
353
    cld
351
    rep     stosb
354
    rep     stosb
352
 
355
 
353
sc_exit:
356
sc_exit:
354
    ret
357
    ret
355
 
358
 
356
 
359
 
357
 
360
 
358
;***************************************************************************
361
;***************************************************************************
359
;   Function
362
;   Function
360
;      socket_close_tcp
363
;      socket_close_tcp
361
;
364
;
362
;   Description
365
;   Description
363
;       socket # in ebx
366
;       socket # in ebx
364
;       returns 0 for ok, -1 for socket not open (fail)
367
;       returns 0 for ok, -1 for socket not open (fail)
365
;
368
;
366
;***************************************************************************
369
;***************************************************************************
367
socket_close_tcp:
370
socket_close_tcp:
368
    ; first, remove any resend entries
371
    ; first, remove any resend entries
369
    pusha
372
    pusha
370
 
373
 
371
    mov     esi, resendQ
374
    mov     esi, resendQ
372
    mov     ecx, 0
375
    mov     ecx, 0
373
 
376
 
374
sct001:
377
sct001:
375
    cmp     ecx, NUMRESENDENTRIES
378
    cmp     ecx, NUMRESENDENTRIES
376
    je	    sct003		; None left
379
    je	    sct003		; None left
377
    cmp     [esi], bl
380
    cmp     [esi], bl
378
    je	    sct002		; found one
381
    je	    sct002		; found one
379
    inc     ecx
382
    inc     ecx
380
    add     esi, 4
383
    add     esi, 4
381
    jmp     sct001
384
    jmp     sct001
382
 
385
 
383
sct002:
386
sct002:
384
 
387
 
385
    mov     [esi], byte 0xFF
388
    mov     [esi], byte 0xFF
386
    jmp     sct001
389
    jmp     sct001
387
 
390
 
388
sct003:
391
sct003:
389
    popa
392
    popa
390
 
393
 
391
    Index2RealAddr ebx
394
    Index2RealAddr ebx
392
    mov     [sktAddr], ebx
395
    mov     [sktAddr], ebx
393
    mov     eax, 0xFFFFFFFF	    ; assume this operation will fail..
396
    mov     eax, 0xFFFFFFFF	    ; assume this operation will fail..
394
    cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
397
    cmp     [ebx + SOCKET.Status], dword SOCK_EMPTY
395
    jz	    sct_exit
398
    jz	    sct_exit
396
 
399
 
397
    ; Now construct the response, and queue for sending by IP
400
    ; Now construct the response, and queue for sending by IP
398
    mov     eax, EMPTY_QUEUE
401
    mov     eax, EMPTY_QUEUE
399
    call    dequeue
402
    call    dequeue
400
    cmp     ax, NO_BUFFER
403
    cmp     ax, NO_BUFFER
401
    je	    stl_exit
404
    je	    stl_exit
402
 
405
 
403
    push    eax
406
    push    eax
404
 
407
 
405
    mov     bl, 0x11	    ; FIN + ACK
408
    mov     bl, 0x11	    ; FIN + ACK
406
    mov     ecx, 0
409
    mov     ecx, 0
407
    mov     esi, 0
410
    mov     esi, 0
408
 
411
 
409
    call    buildTCPPacket
412
    call    buildTCPPacket
410
 
413
 
411
    mov     ebx, [sktAddr]
414
    mov     ebx, [sktAddr]
412
 
415
 
413
    ; increament SND.NXT in socket
416
    ; increament SND.NXT in socket
414
    mov     esi, 48
417
    mov     esi, 48
415
    add     esi, ebx
418
    add     esi, ebx
416
    call    inc_inet_esi
419
    call    inc_inet_esi
417
 
420
 
418
 
421
 
419
    ; Get the socket state
422
    ; Get the socket state
420
    mov     eax, [ebx + SOCKET.TCBState]
423
    mov     eax, [ebx + SOCKET.TCBState]
421
    cmp     eax, TCB_LISTEN
424
    cmp     eax, TCB_LISTEN
422
    je	    destroyTCB
425
    je	    destroyTCB
423
    cmp     eax, TCB_SYN_SENT
426
    cmp     eax, TCB_SYN_SENT
424
    je	    destroyTCB
427
    je	    destroyTCB
425
    cmp     eax, TCB_SYN_RECEIVED
428
    cmp     eax, TCB_SYN_RECEIVED
426
    je	    sct_finwait1
429
    je	    sct_finwait1
427
    cmp     eax, TCB_ESTABLISHED
430
    cmp     eax, TCB_ESTABLISHED
428
    je	    sct_finwait1
431
    je	    sct_finwait1
429
 
432
 
430
    ; assume CLOSE WAIT
433
    ; assume CLOSE WAIT
431
    ; Send a fin, then enter last-ack state
434
    ; Send a fin, then enter last-ack state
432
    mov     eax, TCB_LAST_ACK
435
    mov     eax, TCB_LAST_ACK
433
    mov     [ebx + SOCKET.TCBState], eax
436
    mov     [ebx + SOCKET.TCBState], eax
434
    xor     eax, eax
437
    xor     eax, eax
435
    jmp     sct_send
438
    jmp     sct_send
436
 
439
 
437
sct_finwait1:
440
sct_finwait1:
438
    ; Send a fin, then enter finwait2 state
441
    ; Send a fin, then enter finwait2 state
439
    mov     eax, TCB_FIN_WAIT_1
442
    mov     eax, TCB_FIN_WAIT_1
440
    mov     [ebx + SOCKET.TCBState], eax
443
    mov     [ebx + SOCKET.TCBState], eax
441
    xor     eax, eax
444
    xor     eax, eax
442
 
445
 
443
sct_send:
446
sct_send:
444
    mov     eax, NET1OUT_QUEUE
447
    mov     eax, NET1OUT_QUEUE
445
 
448
 
446
    mov     edx, [stack_ip]
449
    mov     edx, [stack_ip]
447
    mov     ecx, [sktAddr ]
450
    mov     ecx, [sktAddr ]
448
    mov     ecx, [ecx + 16]
451
    mov     ecx, [ecx + 16]
449
    cmp     edx, ecx
452
    cmp     edx, ecx
450
    jne     sct_notlocal
453
    jne     sct_notlocal
451
    mov     eax, IPIN_QUEUE
454
    mov     eax, IPIN_QUEUE
452
 
455
 
453
sct_notlocal:
456
sct_notlocal:
454
       ; Send it.
457
       ; Send it.
455
    pop     ebx
458
    pop     ebx
456
    call    queue
459
    call    queue
457
    jmp     sct_exit
460
    jmp     sct_exit
458
 
461
 
459
destroyTCB:
462
destroyTCB:
460
    pop     eax
463
    pop     eax
461
    ; Clear the socket varaibles
464
    ; Clear the socket varaibles
462
    xor     eax, eax
465
    xor     eax, eax
463
    mov     edi, ebx
466
    mov     edi, ebx
464
    mov     ecx, SOCKETHEADERSIZE
467
    mov     ecx, SOCKETHEADERSIZE
465
    cld
468
    cld
466
    rep     stosb
469
    rep     stosb
467
 
470
 
468
sct_exit:
471
sct_exit:
469
    ret
472
    ret
470
 
473
 
471
 
474
 
472
 
475
 
473
;***************************************************************************
476
;***************************************************************************
474
;   Function
477
;   Function
475
;      socket_poll
478
;      socket_poll
476
;
479
;
477
;   Description
480
;   Description
478
;       socket # in ebx
481
;       socket # in ebx
479
;       returns count in eax.
482
;       returns count in eax.
480
;
483
;
481
;***************************************************************************
484
;***************************************************************************
482
socket_poll:
485
socket_poll:
483
    Index2RealAddr ebx
486
    Index2RealAddr ebx
484
    mov     eax, [ebx + SOCKET.rxDataCount]
487
    mov     eax, [ebx + SOCKET.rxDataCount]
485
 
488
 
486
    ret
489
    ret
487
 
490
 
488
 
491
 
489
 
492
 
490
;***************************************************************************
493
;***************************************************************************
491
;   Function
494
;   Function
492
;      socket_status
495
;      socket_status
493
;
496
;
494
;   Description
497
;   Description
495
;       socket # in ebx
498
;       socket # in ebx
496
;       returns TCB state in eax.
499
;       returns TCB state in eax.
497
;
500
;
498
;***************************************************************************
501
;***************************************************************************
499
socket_status:
502
socket_status:
500
    Index2RealAddr ebx
503
    Index2RealAddr ebx
501
    mov     eax, [ebx + SOCKET.TCBState]
504
    mov     eax, [ebx + SOCKET.TCBState]
502
 
505
 
503
    ret
506
    ret
504
 
507
 
505
 
508
 
506
 
509
 
507
;***************************************************************************
510
;***************************************************************************
508
;   Function
511
;   Function
509
;      socket_read
512
;      socket_read
510
;
513
;
511
;   Description
514
;   Description
512
;       socket # in ebx
515
;       socket # in ebx
513
;       returns # of bytes remaining in eax, data in bl
516
;       returns # of bytes remaining in eax, data in bl
514
;
517
;
515
;***************************************************************************
518
;***************************************************************************
516
socket_read:
519
socket_read:
517
    Index2RealAddr ebx
520
    Index2RealAddr ebx
518
    mov     eax, [ebx + SOCKET.rxDataCount]	    ; get count of bytes
521
    mov     eax, [ebx + SOCKET.rxDataCount]	    ; get count of bytes
519
    mov     ecx, 1
522
    mov     ecx, 1
520
    test    eax, eax
523
    test    eax, eax
521
    jz	    sr2
524
    jz	    sr2
522
 
525
 
523
    dec     eax
526
    dec     eax
524
    mov     esi, ebx		; esi is address of socket
527
    mov     esi, ebx		; esi is address of socket
525
    mov     [ebx + SOCKET.rxDataCount], eax	    ; store new count
528
    mov     [ebx + SOCKET.rxDataCount], eax	    ; store new count
526
    ;movzx   ebx, byte [ebx + SOCKET.rxData]  ; get the byte
529
    ;movzx   ebx, byte [ebx + SOCKET.rxData]  ; get the byte
527
    movzx   ebx, byte [ebx + SOCKETHEADERSIZE]	; get the byte
530
    movzx   ebx, byte [ebx + SOCKETHEADERSIZE]	; get the byte
528
    add     esi, SOCKETHEADERSIZE
531
    add     esi, SOCKETHEADERSIZE
529
    mov     edi, esi
532
    mov     edi, esi
530
    inc     esi
533
    inc     esi
531
 
534
 
532
    mov     ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
535
    mov     ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
533
    cld
536
    cld
534
    rep     movsd
537
    rep     movsd
535
    xor     ecx, ecx
538
    xor     ecx, ecx
536
 
539
 
537
sr1:
540
sr1:
538
    jmp     sor_exit
541
    jmp     sor_exit
539
 
542
 
540
sr2:
543
sr2:
541
    xor     bl, bl
544
    xor     bl, bl
542
 
545
 
543
sor_exit:
546
sor_exit:
544
    ret
547
    ret
545
 
548
 
546
 
549
 
547
;***************************************************************************
550
;***************************************************************************
548
;   Function
551
;   Function
549
;      socket_read_packet
552
;      socket_read_packet
550
;
553
;
551
;   Description
554
;   Description
552
;       socket # in ebx
555
;       socket # in ebx
553
;       datapointer # in ecx
556
;       datapointer # in ecx
554
;       buffer size in edx
557
;       buffer size in edx
555
;       returns # of bytes copied in eax
558
;       returns # of bytes copied in eax
556
;
559
;
557
;***************************************************************************
560
;***************************************************************************
558
socket_read_packet:
561
socket_read_packet:
559
    Index2RealAddr ebx					   ; get real socket address
562
    Index2RealAddr ebx					   ; get real socket address
560
    mov     eax, [ebx + SOCKET.rxDataCount]		   ; get count of bytes
563
    mov     eax, [ebx + SOCKET.rxDataCount]		   ; get count of bytes
561
    test    eax, eax					   ; if count of bytes is zero..
564
    test    eax, eax					   ; if count of bytes is zero..
562
    jz	    .exit					   ; exit function (eax will be zero)
565
    jz	    .exit					   ; exit function (eax will be zero)
563
 
566
 
564
    test    edx, edx					   ; if buffer size is zero, copy all data
567
    test    edx, edx					   ; if buffer size is zero, copy all data
565
    jz	    .copyallbytes
568
    jz	    .copyallbytes
566
    cmp     edx, eax					   ; if buffer size is larger then the bytes of data, copy all data
569
    cmp     edx, eax					   ; if buffer size is larger then the bytes of data, copy all data
567
    jge     .copyallbytes
570
    jge     .copyallbytes
568
 
571
 
569
    sub     eax, edx					   ; store new count (data bytes in buffer - bytes we're about to copy)
572
    sub     eax, edx					   ; store new count (data bytes in buffer - bytes we're about to copy)
570
    mov     [ebx + SOCKET.rxDataCount], eax		   ;
573
    mov     [ebx + SOCKET.rxDataCount], eax		   ;
571
    push    eax
574
    push    eax
572
    mov     eax, edx					   ; number of bytes we want to copy must be in eax
575
    mov     eax, edx					   ; number of bytes we want to copy must be in eax
573
    call    .startcopy					   ; copy to the application
576
    call    .startcopy					   ; copy to the application
574
 
577
 
575
    mov     esi, ebx					   ; now we're going to copy the remaining bytes to the beginning
578
    mov     esi, ebx					   ; now we're going to copy the remaining bytes to the beginning
576
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
579
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
577
    mov     edi, esi					   ; edi is where we're going to copy to
580
    mov     edi, esi					   ; edi is where we're going to copy to
578
    add     esi, edx					   ; esi is from where we copy
581
    add     esi, edx					   ; esi is from where we copy
579
    pop     ecx 					   ; count of bytes we have left
582
    pop     ecx 					   ; count of bytes we have left
580
    push    ecx 					   ; push it again so we can re-use it later
583
    push    ecx 					   ; push it again so we can re-use it later
581
    shr     ecx, 2					   ; divide eax by 4
584
    shr     ecx, 2					   ; divide eax by 4
582
    cld
585
    cld
583
    rep     movsd					   ; copy all full dwords
586
    rep     movsd					   ; copy all full dwords
584
    pop     ecx
587
    pop     ecx
585
    and     ecx, 3
588
    and     ecx, 3
586
    rep     movsb					   ; copy remaining bytes
589
    rep     movsb					   ; copy remaining bytes
587
 
590
 
588
    ret 						   ; at last, exit
591
    ret 						   ; at last, exit
589
 
592
 
590
.copyallbytes:
593
.copyallbytes:
591
    xor     esi, esi
594
    xor     esi, esi
592
    mov     [ebx + SOCKET.rxDataCount], esi		   ; store new count (zero)
595
    mov     [ebx + SOCKET.rxDataCount], esi		   ; store new count (zero)
593
 
596
 
594
.startcopy:
597
.startcopy:
595
    mov     edi, ecx					   ;
598
    mov     edi, ecx					   ;
596
    add     edi, std_application_base_address		   ; get data pointer to buffer in application
599
    add     edi, std_application_base_address		   ; get data pointer to buffer in application
597
 
600
 
598
    mov     esi, ebx					   ;
601
    mov     esi, ebx					   ;
599
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
602
    add     esi, SOCKETHEADERSIZE			   ; we dont need to copy the header
600
    mov     ecx, eax					   ; eax is count of bytes
603
    mov     ecx, eax					   ; eax is count of bytes
601
    push    ecx
604
    push    ecx
602
    shr     ecx, 2					   ; divide eax by 4
605
    shr     ecx, 2					   ; divide eax by 4
603
    cld 						   ; copy all full dwords
606
    cld 						   ; copy all full dwords
604
    rep     movsd					   ;
607
    rep     movsd					   ;
605
    pop     ecx
608
    pop     ecx
606
    and     ecx, 3
609
    and     ecx, 3
607
    rep     movsb					   ; copy the rest bytes
610
    rep     movsb					   ; copy the rest bytes
608
 
611
 
609
.exit:
612
.exit:
610
    ret 						   ; exit, or go back to shift remaining bytes if any
613
    ret 						   ; exit, or go back to shift remaining bytes if any
611
 
614
 
612
 
615
 
613
 
616
 
614
 
617
 
615
;***************************************************************************
618
;***************************************************************************
616
;   Function
619
;   Function
617
;      socket_write
620
;      socket_write
618
;
621
;
619
;   Description
622
;   Description
620
;       socket in ebx
623
;       socket in ebx
621
;       # of bytes to write in ecx
624
;       # of bytes to write in ecx
622
;       pointer to data in edx
625
;       pointer to data in edx
623
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
626
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
624
;       could not queue IP packet )
627
;       could not queue IP packet )
625
;
628
;
626
;***************************************************************************
629
;***************************************************************************
627
socket_write:
630
socket_write:
628
    Index2RealAddr ebx
631
    Index2RealAddr ebx
629
 
632
 
630
    mov     eax, 0xFFFFFFFF
633
    mov     eax, 0xFFFFFFFF
631
    ; If the socket is invalid, return with an error code
634
    ; If the socket is invalid, return with an error code
632
    cmp     [ebx], dword SOCK_EMPTY
635
    cmp     [ebx], dword SOCK_EMPTY
633
    je	    sw_exit
636
    je	    sw_exit
634
 
637
 
635
 
638
 
636
    mov     eax, EMPTY_QUEUE
639
    mov     eax, EMPTY_QUEUE
637
    call    dequeue
640
    call    dequeue
638
    cmp     ax, NO_BUFFER
641
    cmp     ax, NO_BUFFER
639
    je	    sw_exit
642
    je	    sw_exit
640
 
643
 
641
    ; Save the queue entry number
644
    ; Save the queue entry number
642
    push    eax
645
    push    eax
643
 
646
 
644
    ; save the pointers to the data buffer & size
647
    ; save the pointers to the data buffer & size
645
    push    edx
648
    push    edx
646
    push    ecx
649
    push    ecx
647
 
650
 
648
    ; convert buffer pointer eax to the absolute address
651
    ; convert buffer pointer eax to the absolute address
649
    mov     ecx, IPBUFFSIZE
652
    mov     ecx, IPBUFFSIZE
650
    mul     ecx
653
    mul     ecx
651
    add     eax, IPbuffs
654
    add     eax, IPbuffs
652
 
655
 
653
    mov     edx, eax
656
    mov     edx, eax
654
 
657
 
655
    ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
658
    ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
656
 
659
 
657
    ; Fill in the IP header ( some data is in the socket descriptor)
660
    ; Fill in the IP header ( some data is in the socket descriptor)
658
    mov     eax, [ebx + 8]
661
    mov     eax, [ebx + 8]
659
    mov     [edx + 12], eax	 ; source IP
662
    mov     [edx + 12], eax	 ; source IP
660
    mov     eax, [ebx + 16]
663
    mov     eax, [ebx + 16]
661
    mov     [edx + 16], eax	 ; Destination IP
664
    mov     [edx + 16], eax	 ; Destination IP
662
 
665
 
663
    mov     al, 0x45
666
    mov     al, 0x45
664
    mov     [edx], al	      ; Version, IHL
667
    mov     [edx], al	      ; Version, IHL
665
    xor     al, al
668
    xor     al, al
666
    mov     [edx + 1], al     ; Type of service
669
    mov     [edx + 1], al     ; Type of service
667
 
670
 
668
    pop     eax 		  ; Get the UDP data length
671
    pop     eax 		  ; Get the UDP data length
669
    push    eax
672
    push    eax
670
 
673
 
671
    add     eax, 20 + 8 	  ; add IP header and UDP header lengths
674
    add     eax, 20 + 8 	  ; add IP header and UDP header lengths
672
    mov     [edx + 2], ah
675
    mov     [edx + 2], ah
673
    mov     [edx + 3], al
676
    mov     [edx + 3], al
674
    xor     al, al
677
    xor     al, al
675
    mov     [edx + 4], al
678
    mov     [edx + 4], al
676
    mov     [edx + 5], al
679
    mov     [edx + 5], al
677
    mov     al, 0x40
680
    mov     al, 0x40
678
    mov     [edx + 6], al
681
    mov     [edx + 6], al
679
    xor     al, al
682
    xor     al, al
680
    mov     [edx + 7], al
683
    mov     [edx + 7], al
681
    mov     al, 0x20
684
    mov     al, 0x20
682
    mov     [edx + 8], al
685
    mov     [edx + 8], al
683
    mov     al, 17
686
    mov     al, 17
684
    mov     [edx + 9], al
687
    mov     [edx + 9], al
685
 
688
 
686
    ; Checksum left unfilled
689
    ; Checksum left unfilled
687
    xor     ax, ax
690
    xor     ax, ax
688
    mov     [edx + 10], ax
691
    mov     [edx + 10], ax
689
 
692
 
690
    ; Fill in the UDP header ( some data is in the socket descriptor)
693
    ; Fill in the UDP header ( some data is in the socket descriptor)
691
    mov     ax, [ebx + 12]
694
    mov     ax, [ebx + 12]
692
    mov     [edx + 20], ax
695
    mov     [edx + 20], ax
693
 
696
 
694
    mov     ax, [ebx + 20]
697
    mov     ax, [ebx + 20]
695
    mov     [edx + 20 + 2], ax
698
    mov     [edx + 20 + 2], ax
696
 
699
 
697
    pop     eax
700
    pop     eax
698
    push    eax
701
    push    eax
699
 
702
 
700
    add     eax, 8
703
    add     eax, 8
701
    mov     [edx + 20 + 4], ah
704
    mov     [edx + 20 + 4], ah
702
    mov     [edx + 20 + 5], al
705
    mov     [edx + 20 + 5], al
703
 
706
 
704
    ; Checksum left unfilled
707
    ; Checksum left unfilled
705
    xor     ax, ax
708
    xor     ax, ax
706
    mov     [edx + 20 + 6], ax
709
    mov     [edx + 20 + 6], ax
707
 
710
 
708
    pop     ecx 		 ; count of bytes to send
711
    pop     ecx 		 ; count of bytes to send
709
    mov     ebx, ecx		; need the length later
712
    mov     ebx, ecx		; need the length later
710
    pop     eax 		 ; get callers ptr to data to send
713
    pop     eax 		 ; get callers ptr to data to send
711
 
714
 
712
    ; Get the address of the callers data
715
    ; Get the address of the callers data
713
    mov     edi, [TASK_BASE]
716
    mov     edi, [TASK_BASE]
714
    add     edi, TASKDATA.mem_start
717
    add     edi, TASKDATA.mem_start
715
    add     eax, [edi]
718
    add     eax, [edi]
716
    mov     esi, eax
719
    mov     esi, eax
717
 
720
 
718
    mov     edi, edx
721
    mov     edi, edx
719
    add     edi, 28
722
    add     edi, 28
720
    cld
723
    cld
721
    rep     movsb		; copy the data across
724
    rep     movsb		; copy the data across
722
 
725
 
723
    ; we have edx as IPbuffer ptr.
726
    ; we have edx as IPbuffer ptr.
724
    ; Fill in the UDP checksum
727
    ; Fill in the UDP checksum
725
    ; First, fill in pseudoheader
728
    ; First, fill in pseudoheader
726
    mov     eax, [edx + 12]
729
    mov     eax, [edx + 12]
727
    mov     [pseudoHeader], eax
730
    mov     [pseudoHeader], eax
728
    mov     eax, [edx + 16]
731
    mov     eax, [edx + 16]
729
    mov     [pseudoHeader+4], eax
732
    mov     [pseudoHeader+4], eax
730
    mov     ax, 0x1100		  ; 0 + protocol
733
    mov     ax, 0x1100		  ; 0 + protocol
731
    mov     [pseudoHeader+8], ax
734
    mov     [pseudoHeader+8], ax
732
    add     ebx, 8
735
    add     ebx, 8
733
    mov     eax, ebx
736
    mov     eax, ebx
734
    mov     [pseudoHeader+10], ah
737
    mov     [pseudoHeader+10], ah
735
    mov     [pseudoHeader+11], al
738
    mov     [pseudoHeader+11], al
736
 
739
 
737
    mov     eax, pseudoHeader
740
    mov     eax, pseudoHeader
738
    mov     [checkAdd1], eax
741
    mov     [checkAdd1], eax
739
    mov     [checkSize1], word 12
742
    mov     [checkSize1], word 12
740
    mov     eax, edx
743
    mov     eax, edx
741
    add     eax, 20
744
    add     eax, 20
742
    mov     [checkAdd2], eax
745
    mov     [checkAdd2], eax
743
    mov     eax, ebx
746
    mov     eax, ebx
744
    mov     [checkSize2], ax	  ; was eax!! mjh 8/7/02
747
    mov     [checkSize2], ax	  ; was eax!! mjh 8/7/02
745
 
748
 
746
    call    checksum
749
    call    checksum
747
 
750
 
748
    ; store it in the UDP checksum ( in the correct order! )
751
    ; store it in the UDP checksum ( in the correct order! )
749
    mov     ax, [checkResult]
752
    mov     ax, [checkResult]
750
 
753
 
751
    ; If the UDP checksum computes to 0, we must make it 0xffff
754
    ; If the UDP checksum computes to 0, we must make it 0xffff
752
    ; (0 is reserved for 'not used')
755
    ; (0 is reserved for 'not used')
753
    cmp     ax, 0
756
    cmp     ax, 0
754
    jne     sw_001
757
    jne     sw_001
755
    mov     ax, 0xffff
758
    mov     ax, 0xffff
756
 
759
 
757
sw_001:
760
sw_001:
758
    mov     [edx + 20 + 6], ah
761
    mov     [edx + 20 + 6], ah
759
    mov     [edx + 20 + 7], al
762
    mov     [edx + 20 + 7], al
760
 
763
 
761
    ; Fill in the IP header checksum
764
    ; Fill in the IP header checksum
762
    GET_IHL ecx,edx		 ; get IP-Header length
765
    GET_IHL ecx,edx		 ; get IP-Header length
763
    stdcall checksum_jb,edx,ecx  ; buf_ptr, buf_size
766
    stdcall checksum_jb,edx,ecx  ; buf_ptr, buf_size
764
 
767
 
765
    mov     [edx + 10], ah
768
    mov     [edx + 10], ah
766
    mov     [edx + 11], al
769
    mov     [edx + 11], al
767
 
770
 
768
    ; Check destination IP address.
771
    ; Check destination IP address.
769
    ; If it is the local host IP, route it back to IP_RX
772
    ; If it is the local host IP, route it back to IP_RX
770
 
773
 
771
    pop     ebx
774
    pop     ebx
772
    mov     eax, NET1OUT_QUEUE
775
    mov     eax, NET1OUT_QUEUE
773
 
776
 
774
    mov     ecx, [ edx + 16]
777
    mov     ecx, [ edx + 16]
775
    mov     edx, [stack_ip]
778
    mov     edx, [stack_ip]
776
    cmp     edx, ecx
779
    cmp     edx, ecx
777
    jne     sw_notlocal
780
    jne     sw_notlocal
778
    mov     eax, IPIN_QUEUE
781
    mov     eax, IPIN_QUEUE
779
 
782
 
780
sw_notlocal:
783
sw_notlocal:
781
    ; Send it.
784
    ; Send it.
782
    call    queue
785
    call    queue
783
 
786
 
784
    xor     eax, eax
787
    xor     eax, eax
785
 
788
 
786
sw_exit:
789
sw_exit:
787
    ret
790
    ret
788
 
791
 
789
 
792
 
790
 
793
 
791
;***************************************************************************
794
;***************************************************************************
792
;   Function
795
;   Function
793
;      socket_write_tcp
796
;      socket_write_tcp
794
;
797
;
795
;   Description
798
;   Description
796
;       socket in ebx
799
;       socket in ebx
797
;       # of bytes to write in ecx
800
;       # of bytes to write in ecx
798
;       pointer to data in edx
801
;       pointer to data in edx
799
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
802
;       returns 0 in eax ok, -1 == failed ( invalid socket, or
800
;       could not queue IP packet )
803
;       could not queue IP packet )
801
;
804
;
802
;***************************************************************************
805
;***************************************************************************
803
socket_write_tcp:
806
socket_write_tcp:
804
	Index2RealAddr ebx
807
	Index2RealAddr ebx
805
 
808
 
806
    mov     [sktAddr], ebx
809
    mov     [sktAddr], ebx
807
 
810
 
808
    mov     eax, 0xFFFFFFFF
811
    mov     eax, 0xFFFFFFFF
809
    ; If the socket is invalid, return with an error code
812
    ; If the socket is invalid, return with an error code
810
    cmp     [ebx], dword SOCK_EMPTY
813
    cmp     [ebx], dword SOCK_EMPTY
811
    je	    swt_exit
814
    je	    swt_exit
812
 
815
 
813
    ; If the sockets window timer is nonzero, do not queue packet
816
    ; If the sockets window timer is nonzero, do not queue packet
814
    ; TODO - done
817
    ; TODO - done
815
    cmp     [ebx + SOCKET.wndsizeTimer], dword 0
818
    cmp     [ebx + SOCKET.wndsizeTimer], dword 0
816
    jne     swt_exit
819
    jne     swt_exit
817
 
820
 
818
    mov     eax, EMPTY_QUEUE
821
    mov     eax, EMPTY_QUEUE
819
    call    dequeue
822
    call    dequeue
820
    cmp     ax, NO_BUFFER
823
    cmp     ax, NO_BUFFER
821
    je	    swt_exit
824
    je	    swt_exit
822
 
825
 
823
    push    eax
826
    push    eax
824
 
827
 
825
    mov     bl, 0x10	    ; ACK
828
    mov     bl, 0x10	    ; ACK
826
 
829
 
827
    ; Get the address of the callers data
830
    ; Get the address of the callers data
828
    mov     edi, [TASK_BASE]
831
    mov     edi, [TASK_BASE]
829
    add     edi, TASKDATA.mem_start
832
    add     edi, TASKDATA.mem_start
830
    add     edx, [edi]
833
    add     edx, [edi]
831
    mov     esi, edx
834
    mov     esi, edx
832
 
835
 
833
    pop     eax
836
    pop     eax
834
    push    eax
837
    push    eax
835
 
838
 
836
    push    ecx
839
    push    ecx
837
    call    buildTCPPacket
840
    call    buildTCPPacket
838
    pop     ecx
841
    pop     ecx
839
 
842
 
840
    ; Check destination IP address.
843
    ; Check destination IP address.
841
    ; If it is the local host IP, route it back to IP_RX
844
    ; If it is the local host IP, route it back to IP_RX
842
 
845
 
843
    pop     ebx
846
    pop     ebx
844
    push    ecx
847
    push    ecx
845
    mov     eax, NET1OUT_QUEUE
848
    mov     eax, NET1OUT_QUEUE
846
 
849
 
847
    mov     edx, [stack_ip]
850
    mov     edx, [stack_ip]
848
    mov     ecx, [sktAddr ]
851
    mov     ecx, [sktAddr ]
849
    mov     ecx, [ecx + 16]
852
    mov     ecx, [ecx + 16]
850
    cmp     edx, ecx
853
    cmp     edx, ecx
851
    jne     swt_notlocal
854
    jne     swt_notlocal
852
    mov     eax, IPIN_QUEUE
855
    mov     eax, IPIN_QUEUE
853
 
856
 
854
swt_notlocal:
857
swt_notlocal:
855
    pop     ecx
858
    pop     ecx
856
 
859
 
857
    push    ebx 		; save ipbuffer number
860
    push    ebx 		; save ipbuffer number
858
 
861
 
859
    call    queue
862
    call    queue
860
 
863
 
861
    mov     esi, [sktAddr]
864
    mov     esi, [sktAddr]
862
 
865
 
863
    ; increament SND.NXT in socket
866
    ; increament SND.NXT in socket
864
    ; Amount to increment by is in ecx
867
    ; Amount to increment by is in ecx
865
    add     esi, 48
868
    add     esi, 48
866
    call    add_inet_esi
869
    call    add_inet_esi
867
 
870
 
868
    pop     ebx
871
    pop     ebx
869
 
872
 
870
    ; Copy the IP buffer to a resend queue
873
    ; Copy the IP buffer to a resend queue
871
    ; If there isn't one, dont worry about it for now
874
    ; If there isn't one, dont worry about it for now
872
    mov     esi, resendQ
875
    mov     esi, resendQ
873
    mov     ecx, 0
876
    mov     ecx, 0
874
 
877
 
875
swt003:
878
swt003:
876
    cmp     ecx, NUMRESENDENTRIES
879
    cmp     ecx, NUMRESENDENTRIES
877
    je	    swt001		; None found
880
    je	    swt001		; None found
878
    cmp     [esi], byte 0xFF
881
    cmp     [esi], byte 0xFF
879
    je	    swt002		; found one
882
    je	    swt002		; found one
880
    inc     ecx
883
    inc     ecx
881
    add     esi, 4
884
    add     esi, 4
882
    jmp     swt003
885
    jmp     swt003
883
 
886
 
884
swt002:
887
swt002:
885
    push    ebx
888
    push    ebx
886
 
889
 
887
    ; OK, we have a buffer descriptor ptr in esi.
890
    ; OK, we have a buffer descriptor ptr in esi.
888
    ; resend entry # in ecx
891
    ; resend entry # in ecx
889
    ;  Populate it
892
    ;  Populate it
890
    ;  socket #
893
    ;  socket #
891
    ;  retries count
894
    ;  retries count
892
    ;  retry time
895
    ;  retry time
893
    ;  fill IP buffer associated with this descriptor
896
    ;  fill IP buffer associated with this descriptor
894
 
897
 
895
    mov     eax, [sktAddr]
898
    mov     eax, [sktAddr]
896
    sub     eax, sockets
899
    sub     eax, sockets
897
    shr     eax, 12		; get skt #
900
    shr     eax, 12		; get skt #
898
    mov     [esi], al
901
    mov     [esi], al
899
    mov     [esi + 1], byte TCP_RETRIES
902
    mov     [esi + 1], byte TCP_RETRIES
900
    mov     [esi + 2], word TCP_TIMEOUT
903
    mov     [esi + 2], word TCP_TIMEOUT
901
 
904
 
902
    inc     ecx
905
    inc     ecx
903
    ; Now get buffer location, and copy buffer across. argh! more copying,,
906
    ; Now get buffer location, and copy buffer across. argh! more copying,,
904
    mov     edi, resendBuffer - IPBUFFSIZE
907
    mov     edi, resendBuffer - IPBUFFSIZE
905
swt002a:
908
swt002a:
906
    add     edi, IPBUFFSIZE
909
    add     edi, IPBUFFSIZE
907
    loop    swt002a
910
    loop    swt002a
908
 
911
 
909
    ; we have dest buffer location in edi
912
    ; we have dest buffer location in edi
910
    pop     eax
913
    pop     eax
911
    ; convert source buffer pointer eax to the absolute address
914
    ; convert source buffer pointer eax to the absolute address
912
    mov     ecx, IPBUFFSIZE
915
    mov     ecx, IPBUFFSIZE
913
    mul     ecx
916
    mul     ecx
914
    add     eax, IPbuffs
917
    add     eax, IPbuffs
915
    mov     esi, eax
918
    mov     esi, eax
916
 
919
 
917
    ; do copy
920
    ; do copy
918
    mov     ecx, IPBUFFSIZE
921
    mov     ecx, IPBUFFSIZE
919
    cld
922
    cld
920
    rep     movsb
923
    rep     movsb
921
 
924
 
922
swt001:
925
swt001:
923
    xor     eax, eax
926
    xor     eax, eax
924
 
927
 
925
swt_exit:
928
swt_exit:
926
    ret
929
    ret