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 |