Rev 914 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 914 | Rev 2971 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; SOCKET.INC ;; |
6 | ;; SOCKET.INC ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Sockets constants, structures and functions ;; |
8 | ;; Sockets constants, structures and functions ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; Last revision: 11.11.2006 ;; |
- | |
11 | ;; ;; |
- | |
12 | ;; This file contains the following: ;; |
10 | ;; This file contains the following: ;; |
13 | ;; is_localport_unused ;; |
11 | ;; is_localport_unused ;; |
14 | ;; get_free_socket ;; |
12 | ;; get_free_socket ;; |
15 | ;; socket_open ;; |
13 | ;; socket_open ;; |
16 | ;; socket_open_tcp ;; |
14 | ;; socket_open_tcp ;; |
Line 27... | Line 25... | ||
27 | ;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
25 | ;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
28 | ;; 11.11.2006 - [Johnny_B] and [smb] ;; |
26 | ;; 11.11.2006 - [Johnny_B] and [smb] ;; |
29 | ;; ;; |
27 | ;; ;; |
30 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
28 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 31... | Line 29... | ||
31 | 29 | ||
32 | $Revision: 914 $ |
- | |
Line 33... | Line -... | ||
33 | - | ||
34 | - | ||
35 | ; |
- | |
36 | ; Socket Descriptor + Buffer |
- | |
37 | ; |
- | |
38 | ; 0 1 2 3 |
- | |
39 | ; 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 |
- | |
40 | ; |
- | |
41 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
42 | ; 0| Status ( of this buffer ) | |
- | |
43 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
44 | ; 4| Application Process ID | |
- | |
45 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
46 | ; 8| Local IP Address | |
- | |
47 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
48 | ; 12| Local IP Port | Unused ( set to 0 ) | |
- | |
49 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
50 | ; 16| Remote IP Address | |
- | |
51 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
52 | ; 20| Remote IP Port | Unused ( set to 0 ) | |
- | |
53 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
54 | ; 24| Rx Data Count INTEL format| |
- | |
55 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
56 | ; 28| TCB STATE INTEL format| |
- | |
57 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
58 | ; 32| TCB Timer (seconds) INTEL format| |
- | |
59 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
60 | ; 36| ISS (Inital Sequence # used by this connection ) INET format| |
- | |
61 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
62 | ; 40| IRS ( Inital Receive Sequence # ) INET format| |
- | |
63 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
64 | ; 44| SND.UNA Seq # of unack'ed sent packets INET format| |
- | |
65 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
66 | ; 48| SND.NXT Next send seq # to use INET format| |
- | |
67 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
68 | ; 52| SND.WND Send window INET format| |
- | |
69 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
70 | ; 56| RCV.NXT Next expected receive sequence # INET format| |
- | |
71 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
72 | ; 60| RCV.WND Receive window INET format| |
- | |
73 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
74 | ; 64| SEG.LEN Segment length INTEL format| |
- | |
75 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
76 | ; 68| SEG.WND Segment window INTEL format| |
- | |
77 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
78 | ; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format| |
- | |
79 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- | |
80 | ; 76| RX Data Buffer | |
- | |
81 | ; +-+-+-.......... -+ |
- | |
82 | 30 | $Revision: 2971 $ |
|
83 | 31 | ||
84 | ; so, define struct |
- | |
85 | struc SOCKET |
32 | ; socket data structure |
86 | { |
33 | struct SOCKET |
87 | .PrevPtr dd ? |
34 | .PrevPtr dd ? ; pointer to previous socket in list |
88 | .NextPtr dd ? |
35 | .NextPtr dd ? ; pointer to next socket in list |
89 | .Status dd ? ;+00 - Status ( of this buffer ) |
36 | .Number dd ? ; socket number (unique within single process) |
90 | .PID dd ? ;+04 - Application Process ID |
37 | .PID dd ? ; application process id |
91 | .LocalIP dd ? ;+08 - Local IP Address |
38 | .LocalIP dd ? ; local IP address |
92 | .LocalPort dw ? ;+12 - Local Port |
39 | .LocalPort dw ? ; local port |
93 | .RemoteIP dd ? ;+16 - Remote IP Address |
40 | .RemoteIP dd ? ; remote IP address |
94 | .RemotePort dw ? ;+20 - Remote Port |
41 | .RemotePort dw ? ; remote port |
95 | .OrigRemoteIP dd ? |
42 | .OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state) |
96 | .OrigRemotePort dw ? |
43 | .OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state) |
97 | .rxDataCount dd ? ;+24 - Rx Data Count |
44 | .rxDataCount dd ? ; rx data count |
98 | .TCBState dd ? ;+28 - TCB STATE |
45 | .TCBState dd ? ; TCB state |
99 | .TCBTimer dd ? ;+32 - TCB Timer (seconds) |
46 | .TCBTimer dd ? ; TCB timer (seconds) |
100 | .ISS dd ? ;+36 - Initial Send Sequence |
47 | .ISS dd ? ; initial send sequence |
101 | .IRS dd ? ;+40 - Initial Receive Sequence |
48 | .IRS dd ? ; initial receive sequence |
102 | .SND_UNA dd ? ;+44 - Sequence number of unack'ed sent packets |
49 | .SND_UNA dd ? ; sequence number of unack'ed sent packets |
103 | .SND_NXT dd ? ;+48 - Next send sequence number to use |
50 | .SND_NXT dd ? ; bext send sequence number to use |
104 | .SND_WND dd ? ;+52 - Send window |
51 | .SND_WND dd ? ; send window |
105 | .RCV_NXT dd ? ;+56 - Next receive sequence number to use |
52 | .RCV_NXT dd ? ; next receive sequence number to use |
106 | .RCV_WND dd ? ;+60 - Receive window |
53 | .RCV_WND dd ? ; receive window |
107 | .SEG_LEN dd ? ;+64 - Segment length |
54 | .SEG_LEN dd ? ; segment length |
108 | .SEG_WND dd ? ;+68 - Segment window |
- | |
109 | .wndsizeTimer dd ? ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER |
- | |
110 | .rxData dd ? ;+76 - receive data buffer here |
- | |
111 | } |
- | |
112 | - | ||
113 | virtual at 0 |
- | |
114 | SOCKET SOCKET |
- | |
115 | end virtual |
- | |
116 | - | ||
117 | ; simple macro calcing real memory address of SOCKET struct by socket's |
- | |
118 | ;macro Index2RealAddr reg |
55 | .SEG_WND dd ? ; segment window |
119 | ;{ |
56 | .wndsizeTimer dd ? ; window size timer |
120 | ; shl reg, 12 |
57 | .lock dd ? ; lock mutex |
121 | ; add reg, sockets |
- | |
122 | ;} |
- | |
123 | - | ||
124 | ;Constants |
- | |
125 | ; current socket statuses |
- | |
Line 126... | Line 58... | ||
126 | SOCK_EMPTY = 0 ; socket not in use |
58 | .rxData dd ? ; receive data buffer here |
127 | SOCK_OPEN = 1 ; open issued, but no data sent |
59 | ends |
128 | 60 | ||
Line -... | Line 61... | ||
- | 61 | ; TCP opening modes |
|
- | 62 | SOCKET_PASSIVE = 0 |
|
- | 63 | SOCKET_ACTIVE = 1 |
|
- | 64 | ||
- | 65 | ; socket types |
|
- | 66 | SOCK_STREAM = 1 |
|
- | 67 | SOCK_DGRAM = 2 |
|
- | 68 | ||
- | 69 | ;; Allocate memory for socket data and put new socket into the list |
|
- | 70 | ; Newly created socket is initialized with calling PID and number and |
|
129 | ; TCP opening modes |
71 | ; put into beginning of list (which is a fastest way). |
130 | SOCKET_PASSIVE equ 0 |
72 | ; |
131 | SOCKET_ACTIVE equ 1 |
73 | ; @return socket structure address in EAX |
132 | 74 | ;; |
|
133 | proc net_socket_alloc stdcall uses ebx ecx edx edi |
75 | proc net_socket_alloc stdcall uses ebx ecx edx edi |
- | 76 | mov ecx, SOCKETBUFFSIZE |
|
134 | mov ecx, SOCKETBUFFSIZE |
77 | mov edx, PG_SW |
135 | mov edx, PG_SW |
78 | call @mem_alloc@8 |
Line -... | Line 79... | ||
- | 79 | DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax |
|
136 | call @mem_alloc@8 |
80 | ; check if we can allocate needed amount of memory |
137 | DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax |
81 | or eax, eax |
138 | or eax, eax |
82 | jz .exit |
139 | jz .exit |
83 | |
140 | 84 | ; zero-initialize allocated memory |
|
141 | push eax |
85 | push eax |
142 | mov edi, eax |
86 | mov edi, eax |
Line -... | Line 87... | ||
- | 87 | mov ecx, SOCKETBUFFSIZE / 4 |
|
143 | mov ecx, SOCKETBUFFSIZE / 4 |
88 | cld |
144 | cld |
89 | xor eax, eax |
145 | xor eax, eax |
90 | rep stosd |
146 | rep stosd |
91 | pop eax |
147 | pop eax |
92 | |
148 | 93 | ; add socket to the list by changing pointers |
|
149 | mov ebx, net_sockets |
94 | mov ebx, net_sockets |
150 | push [ebx + SOCKET.NextPtr] |
95 | push [ebx + SOCKET.NextPtr] |
151 | mov [ebx + SOCKET.NextPtr], eax |
96 | mov [ebx + SOCKET.NextPtr], eax |
Line -... | Line 97... | ||
- | 97 | mov [eax + SOCKET.PrevPtr], ebx |
|
152 | mov [eax + SOCKET.PrevPtr], ebx |
98 | pop ebx |
153 | pop ebx |
99 | mov [eax + SOCKET.NextPtr], ebx |
154 | mov [eax + SOCKET.NextPtr], ebx |
100 | or ebx, ebx |
Line -... | Line 101... | ||
- | 101 | jz @f |
|
- | 102 | mov [ebx + SOCKET.PrevPtr], eax |
|
- | 103 | ||
- | 104 | @@: ; set socket owner PID to the one of calling process |
|
- | 105 | mov ebx, [TASK_BASE] |
|
- | 106 | mov ebx, [ebx + TASKDATA.pid] |
|
- | 107 | mov [eax + SOCKET.PID], ebx |
|
- | 108 | ||
- | 109 | ; find first free socket number and use it |
|
- | 110 | ;mov edx, ebx |
|
- | 111 | mov ebx, net_sockets |
|
- | 112 | xor ecx, ecx |
|
- | 113 | .next_socket_number: |
|
- | 114 | inc ecx |
|
- | 115 | .next_socket: |
|
- | 116 | mov ebx, [ebx + SOCKET.NextPtr] |
|
- | 117 | or ebx, ebx |
|
- | 118 | jz .last_socket_number |
|
- | 119 | cmp [ebx + SOCKET.Number], ecx |
|
- | 120 | jne .next_socket |
|
155 | or ebx, ebx |
121 | ;cmp [ebx + SOCKET.PID], edx |
156 | jz @f |
122 | ;jne .next_socket |
157 | mov [ebx + SOCKET.PrevPtr], eax |
123 | mov ebx, net_sockets |
Line -... | Line 124... | ||
- | 124 | jmp .next_socket_number |
|
- | 125 | ||
- | 126 | .last_socket_number: |
|
- | 127 | mov [eax + SOCKET.Number], ecx |
|
158 | 128 | ||
159 | @@: mov ebx, [TASK_BASE] |
129 | .exit: |
160 | mov ebx, [ebx + TASKDATA.pid] |
130 | ret |
- | 131 | endp |
|
161 | mov [eax + SOCKET.PID], ebx |
132 | |
162 | 133 | ;; Free socket data memory and pop socket off the list |
|
Line -... | Line 134... | ||
- | 134 | ; |
|
163 | .exit: |
135 | ; @param sockAddr is a socket structure address |
164 | ret |
136 | ;; |
165 | endp |
137 | proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD |
166 | 138 | mov eax, [sockAddr] |
|
167 | proc net_socket_free stdcall uses ebx ecx edx, sock:DWORD |
139 | DEBUGF 1, "K : net_socket_free (0x%x)\n", eax |
168 | mov eax, [sock] |
140 | ; check if we got something similar to socket structure address |
169 | DEBUGF 1, "K : net_socket_free (0x%x)\n", eax |
141 | or eax, eax |
170 | or eax, eax |
142 | jz .error |
171 | jz .error |
143 | |
172 | 144 | ; make sure sockAddr is one of the socket addresses in the list |
|
173 | mov ebx, net_sockets |
145 | mov ebx, net_sockets |
Line -... | Line 146... | ||
- | 146 | ;mov ecx, [TASK_BASE] |
|
- | 147 | ;mov ecx, [ecx + TASKDATA.pid] |
|
174 | mov ecx, [TASK_BASE] |
148 | .next_socket: |
175 | mov ecx, [ecx + TASKDATA.pid] |
149 | mov ebx, [ebx + SOCKET.NextPtr] |
176 | .next_socket: |
150 | or ebx, ebx |
177 | mov ebx, [ebx + SOCKET.NextPtr] |
151 | jz .error |
178 | or ebx, ebx |
152 | cmp ebx, eax |
Line 197... | Line 171... | ||
197 | .error: |
171 | .error: |
198 | DEBUGF 1, "K : failed\n" |
172 | DEBUGF 1, "K : failed\n" |
199 | ret |
173 | ret |
200 | endp |
174 | endp |
Line -... | Line 175... | ||
- | 175 | ||
- | 176 | ;; Get socket structure address by its number |
|
- | 177 | ; Scan through sockets list to find the socket with specified number. |
|
- | 178 | ; This proc uses SOCKET.PID indirectly to check if socket is owned by |
|
- | 179 | ; calling process. |
|
- | 180 | ; |
|
- | 181 | ; @param sockNum is a socket number |
|
- | 182 | ; @return socket structure address or 0 (not found) in EAX |
|
201 | 183 | ;; |
|
202 | proc net_socket_num_to_addr stdcall uses ebx ecx, x:DWORD |
184 | proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD |
- | 185 | mov eax, [sockNum] |
|
203 | ; FIXME: do real transform |
186 | ; check if we got something similar to socket number |
- | 187 | or eax, eax |
|
- | 188 | jz .error |
|
- | 189 | ||
204 | mov eax, [x] |
190 | ; scan through sockets list |
205 | mov ebx, net_sockets |
191 | mov ebx, net_sockets |
206 | mov ecx, [TASK_BASE] |
192 | ;mov ecx, [TASK_BASE] |
207 | mov ecx, [ecx + TASKDATA.pid] |
193 | ;mov ecx, [ecx + TASKDATA.pid] |
208 | .next_socket: |
194 | .next_socket: |
209 | mov ebx, [ebx + SOCKET.NextPtr] |
195 | mov ebx, [ebx + SOCKET.NextPtr] |
210 | or ebx, ebx |
196 | or ebx, ebx |
211 | jz .error |
197 | jz .error |
212 | cmp ebx, eax |
198 | cmp [ebx + SOCKET.Number], eax |
213 | jne .next_socket |
199 | jne .next_socket |
214 | ;cmp [ebx + SOCKET.PID], ecx |
200 | ;cmp [ebx + SOCKET.PID], ecx |
- | 201 | ;jne .next_socket |
|
- | 202 | ||
- | 203 | ; okay, we found the correct one |
|
215 | ;jne .next_socket |
204 | mov eax, ebx |
Line 216... | Line 205... | ||
216 | ret |
205 | ret |
217 | 206 | ||
218 | .error: |
207 | .error: |
219 | xor eax, eax |
208 | xor eax, eax |
Line -... | Line 209... | ||
- | 209 | ret |
|
- | 210 | endp |
|
- | 211 | ||
- | 212 | ;; Get socket number by its structure address |
|
- | 213 | ; Scan through sockets list to find the socket with specified address. |
|
- | 214 | ; This proc uses SOCKET.PID indirectly to check if socket is owned by |
|
- | 215 | ; calling process. |
|
- | 216 | ; |
|
220 | ret |
217 | ; @param sockAddr is a socket structure address |
221 | endp |
218 | ; @return socket number (SOCKET.Number) or 0 (not found) in EAX |
- | 219 | ;; |
|
222 | 220 | proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD |
|
- | 221 | mov eax, [sockAddr] |
|
- | 222 | ; check if we got something similar to socket structure address |
|
- | 223 | or eax, eax |
|
223 | proc net_socket_addr_to_num stdcall uses ebx ecx, x:DWORD |
224 | jz .error |
224 | ; FIXME: do real transform |
225 | |
225 | mov eax, [x] |
226 | ; scan through sockets list |
226 | mov ebx, net_sockets |
227 | mov ebx, net_sockets |
227 | mov ecx, [TASK_BASE] |
228 | ;mov ecx, [TASK_BASE] |
228 | mov ecx, [ecx + TASKDATA.pid] |
229 | ;mov ecx, [ecx + TASKDATA.pid] |
229 | .next_socket: |
230 | .next_socket: |
230 | mov ebx, [ebx + SOCKET.NextPtr] |
231 | mov ebx, [ebx + SOCKET.NextPtr] |
231 | or ebx, ebx |
232 | or ebx, ebx |
232 | jz .error |
233 | jz .error |
233 | cmp ebx, eax |
234 | cmp ebx, eax |
- | 235 | jne .next_socket |
|
- | 236 | ;cmp [ebx + SOCKET.PID], ecx |
|
- | 237 | ;jne .next_socket |
|
234 | jne .next_socket |
238 | |
Line 235... | Line 239... | ||
235 | ;cmp [ebx + SOCKET.PID], ecx |
239 | ; okay, we found the correct one |
236 | ;jne .next_socket |
240 | mov eax, [ebx + SOCKET.Number] |
237 | ret |
241 | ret |
238 | 242 | ||
Line 239... | Line 243... | ||
239 | .error: |
243 | .error: |
240 | xor eax, eax |
- | |
241 | ret |
244 | xor eax, eax |
242 | endp |
- | |
243 | - | ||
244 | ;*************************************************************************** |
245 | ret |
245 | ; Function |
246 | endp |
246 | ; is_localport_unused |
247 | |
247 | ; |
- | |
248 | ; Description |
248 | ;; [53.9] Check if local port is used by any socket in the system. |
249 | ; scans through all the active sockets , looking to see if the |
249 | ; Scan through sockets list, checking SOCKET.LocalPort. |
- | 250 | ; Useful when you want a to generate a unique local port number. |
|
250 | ; port number specified in bx is in use as a localport number. |
251 | ; This proc doesn't guarantee that after calling it and trying to use |
- | 252 | ; the port reported being free in calls to socket_open/socket_open_tcp it'll |
|
251 | ; This is useful when you want a to generate a unique local port |
253 | ; still be free or otherwise it'll still be used if reported being in use. |
Line 252... | Line 254... | ||
252 | ; number. |
254 | ; |
Line 253... | Line 255... | ||
253 | ; On return, eax = 1 for free, 0 for in use |
255 | ; @param BX is a port number |
- | 256 | ; @return 1 (port is free) or 0 (port is in use) in EAX |
|
254 | ; |
257 | ;; |
255 | ;*************************************************************************** |
258 | proc is_localport_unused stdcall |
Line 256... | Line 259... | ||
256 | proc is_localport_unused stdcall |
259 | |
257 | 260 | xchg bl, bh |
|
258 | xchg bl, bh |
261 | |
259 | 262 | ; assume the return value is 'free' |
|
260 | xor eax, eax ; Assume the return value is 'free' |
263 | xor eax, eax |
261 | inc al |
264 | inc al |
Line 262... | Line 265... | ||
262 | mov edx, net_sockets |
265 | mov edx, net_sockets |
- | 266 | ||
Line 263... | Line 267... | ||
263 | 267 | .next_socket: |
|
264 | .next_socket: |
268 | mov edx, [edx + SOCKET.NextPtr] |
265 | mov edx, [edx + SOCKET.NextPtr] |
269 | or edx, edx |
Line 266... | Line -... | ||
266 | or edx, edx |
- | |
267 | jz .exit |
- | |
268 | cmp [edx + SOCKET.LocalPort], bx |
- | |
269 | jne .next_socket ; Return back if the port is not occupied |
270 | jz .exit |
270 | 271 | cmp [edx + SOCKET.LocalPort], bx |
|
271 | dec al ; return 'in use' |
- | |
272 | - | ||
273 | .exit: |
272 | jne .next_socket |
274 | ret |
273 | |
275 | endp |
274 | ; return 'in use' |
276 | 275 | dec al |
|
277 | 276 | ||
278 | ;*************************************************************************** |
- | |
279 | ; Function |
277 | .exit: |
280 | ; socket_open |
278 | ret |
281 | ; |
279 | endp |
282 | ; Description |
280 | |
Line 283... | Line 281... | ||
283 | ; find a free socket |
281 | ;; [53.0] Open DGRAM socket (connectionless, unreliable) |
Line 284... | Line 282... | ||
284 | ; local port in ebx |
282 | ; |
Line 285... | Line -... | ||
285 | ; remote port in ecx |
- | |
286 | ; remote ip in edx |
283 | ; @param BX is local port number |
287 | ; return socket # in eax, -1 if none available |
284 | ; @param CX is remote port number |
288 | ; |
285 | ; @param EDX is remote IP address |
289 | ;*************************************************************************** |
286 | ; @return socket number or -1 (error) in EAX |
Line 314... | Line 311... | ||
314 | DEBUGF 1, "K : socket_open (fail)\n" |
311 | DEBUGF 1, "K : socket_open (fail)\n" |
315 | or eax, -1 |
312 | or eax, -1 |
316 | ret |
313 | ret |
317 | endp |
314 | endp |
Line 318... | Line -... | ||
318 | - | ||
319 | 315 | ||
320 | ;*************************************************************************** |
- | |
321 | ; Function |
- | |
322 | ; socket_open_tcp |
316 | ;; [53.5] Open STREAM socket (connection-based, sequenced, reliable, two-way) |
323 | ; |
- | |
324 | ; Description |
- | |
325 | ; Opens a TCP socket in PASSIVE or ACTIVE mode |
- | |
326 | ; find a free socket |
317 | ; |
327 | ; local port in ebx ( intel format ) |
318 | ; @param BX is local port number |
328 | ; remote port in ecx ( intel format ) |
319 | ; @param CX is remote port number |
329 | ; remote ip in edx ( in Internet byte order ) |
320 | ; @param EDX is remote IP address |
330 | ; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE ) |
321 | ; @param ESI is open mode (SOCKET_ACTIVE, SOCKET_PASSIVE) |
331 | ; return socket # in eax, -1 if none available |
322 | ; @return socket number or -1 (error) in EAX |
332 | ; |
- | |
333 | ;*************************************************************************** |
323 | ;; |
334 | proc socket_open_tcp stdcall |
324 | proc socket_open_tcp stdcall |
Line 335... | Line 325... | ||
335 | local sockAddr dd ? |
325 | local sockAddr dd ? |
336 | 326 | ||
Line 367... | Line 357... | ||
367 | DEBUGF 1, "K : socket_open_tcp (0x%x)\n", eax |
357 | DEBUGF 1, "K : socket_open_tcp (0x%x)\n", eax |
Line 368... | Line 358... | ||
368 | 358 | ||
Line 369... | Line 359... | ||
369 | mov [sockAddr], eax |
359 | mov [sockAddr], eax |
370 | - | ||
371 | ; TODO - check this works! |
360 | |
Line 372... | Line 361... | ||
372 | ;xxx: already 0 (intialized by net_socket_alloc) |
361 | ; TODO - check this works! |
373 | ;mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer. |
362 | ;mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer. |
374 | 363 | ||
Line 421... | Line 410... | ||
421 | ; increment SND.NXT in socket |
410 | ; increment SND.NXT in socket |
422 | add esi, SOCKET.SND_NXT |
411 | add esi, SOCKET.SND_NXT |
423 | call inc_inet_esi |
412 | call inc_inet_esi |
Line 424... | Line 413... | ||
424 | 413 | ||
425 | .exit: |
- | |
426 | mov ebx, [sockAddr] |
- | |
427 | mov [ebx + SOCKET.Status], SOCK_OPEN |
414 | .exit: |
428 | ;pop eax ; Get the socket number back, so we can return it |
415 | ; Get the socket number back, so we can return it |
429 | stdcall net_socket_addr_to_num, ebx |
416 | stdcall net_socket_addr_to_num, [sockAddr] |
Line 430... | Line 417... | ||
430 | ret |
417 | ret |
431 | 418 | ||
432 | .error: |
419 | .error: |
433 | DEBUGF 1, "K : socket_open_tcp (fail)\n" |
420 | DEBUGF 1, "K : socket_open_tcp (fail)\n" |
434 | or eax, -1 |
421 | or eax, -1 |
Line 435... | Line -... | ||
435 | ret |
- | |
436 | endp |
- | |
437 | - | ||
438 | 422 | ret |
|
439 | ;*************************************************************************** |
423 | endp |
440 | ; Function |
- | |
441 | ; socket_close |
424 | |
442 | ; |
425 | ;; [53.1] Close DGRAM socket |
443 | ; Description |
426 | ; |
444 | ; socket # in ebx |
- | |
445 | ; returns 0 for ok, -1 for socket not open (fail) |
427 | ; @param EBX is socket number |
446 | ; |
428 | ; @return 0 (closed successfully) or -1 (error) in EAX |
447 | ;*************************************************************************** |
429 | ;; |
448 | proc socket_close stdcall |
430 | proc socket_close stdcall |
449 | DEBUGF 1, "K : socket_close (0x%x)\n", ebx |
431 | DEBUGF 1, "K : socket_close (0x%x)\n", ebx |
Line 450... | Line -... | ||
450 | stdcall net_socket_num_to_addr, ebx |
- | |
451 | or eax, eax |
- | |
452 | jz .error |
- | |
453 | - | ||
454 | cmp [eax + SOCKET.Status], dword SOCK_EMPTY |
432 | stdcall net_socket_num_to_addr, ebx |
455 | jz .error |
- | |
456 | - | ||
457 | ; Clear the socket varaibles |
- | |
458 | stdcall net_socket_free, eax |
- | |
459 | ; mov edi, eax |
- | |
Line 460... | Line 433... | ||
460 | ; xor eax, eax |
433 | or eax, eax |
461 | ; mov ecx, SOCKETHEADERSIZE |
434 | jz .error |
Line 462... | Line 435... | ||
462 | ; cld |
435 | |
463 | ; rep stosb |
436 | stdcall net_socket_free, eax |
464 | 437 | ||
465 | xor eax, eax |
438 | xor eax, eax |
466 | ret |
439 | ret |
Line 467... | Line -... | ||
467 | - | ||
- | 440 | ||
468 | .error: |
441 | .error: |
469 | DEBUGF 1, "K : socket_close (fail)\n" |
- | |
470 | or eax, -1 |
442 | DEBUGF 1, "K : socket_close (fail)\n" |
471 | ret |
443 | or eax, -1 |
472 | endp |
- | |
473 | 444 | ret |
|
474 | 445 | endp |
|
475 | ;*************************************************************************** |
446 | |
476 | ; Function |
- | |
477 | ; socket_close_tcp |
447 | ;; [53.8] Close STREAM socket |
478 | ; |
448 | ; Closing TCP sockets takes time, so when you get successful return code |
479 | ; Description |
449 | ; from this function doesn't always mean that socket is actually closed. |
480 | ; socket # in ebx |
450 | ; |
481 | ; returns 0 for ok, -1 for socket not open (fail) |
451 | ; @param EBX is socket number |
Line 491... | Line 461... | ||
491 | mov ecx, 0 |
461 | mov ecx, 0 |
Line 492... | Line 462... | ||
492 | 462 | ||
493 | .next_resendq: |
463 | .next_resendq: |
494 | cmp ecx, NUMRESENDENTRIES |
464 | cmp ecx, NUMRESENDENTRIES |
495 | je .last_resendq ; None left |
- | |
496 | ;cmp [esi], bl ; XTODO: bl -> ebx |
465 | je .last_resendq ; None left |
497 | cmp [esi + 4], ebx |
466 | cmp [esi + 4], ebx |
498 | je @f ; found one |
467 | je @f ; found one |
499 | inc ecx |
468 | inc ecx |
500 | add esi, 8 |
469 | add esi, 8 |
Line 501... | Line -... | ||
501 | jmp .next_resendq |
- | |
502 | 470 | jmp .next_resendq |
|
503 | ;@@: mov byte[esi], 0xff ; XTODO: 0xff -> 0 |
471 | |
504 | @@: mov dword[esi + 4], 0 |
472 | @@: mov dword[esi + 4], 0 |
505 | inc ecx |
473 | inc ecx |
Line 513... | Line 481... | ||
513 | or eax, eax |
481 | or eax, eax |
514 | jz .error |
482 | jz .error |
Line 515... | Line 483... | ||
515 | 483 | ||
516 | mov ebx, eax |
484 | mov ebx, eax |
517 | mov [sockAddr], eax |
- | |
518 | cmp [ebx + SOCKET.Status], SOCK_EMPTY |
- | |
Line 519... | Line 485... | ||
519 | je .error |
485 | mov [sockAddr], eax |
520 | 486 | ||
521 | cmp [ebx + SOCKET.TCBState], TCB_LISTEN ;xxx |
487 | cmp [ebx + SOCKET.TCBState], TCB_LISTEN |
522 | je .destroy_tcb ;xxx |
488 | je .destroy_tcb |
Line 523... | Line 489... | ||
523 | cmp [ebx + SOCKET.TCBState], TCB_SYN_SENT ;xxx |
489 | cmp [ebx + SOCKET.TCBState], TCB_SYN_SENT |
524 | je .destroy_tcb ;xxx |
490 | je .destroy_tcb |
525 | 491 | ||
526 | ; Now construct the response, and queue for sending by IP |
492 | ; Now construct the response, and queue for sending by IP |
527 | mov eax, EMPTY_QUEUE |
493 | mov eax, EMPTY_QUEUE |
Line 528... | Line 494... | ||
528 | call dequeue |
494 | call dequeue |
Line 529... | Line -... | ||
529 | cmp ax, NO_BUFFER |
- | |
530 | je .error |
495 | cmp ax, NO_BUFFER |
531 | 496 | je .error |
|
532 | push eax |
497 | |
533 | 498 | push eax |
|
Line 534... | Line 499... | ||
534 | ;xxx mov bl, TH_FIN + TH_ACK |
499 | |
Line 543... | Line 508... | ||
543 | call inc_inet_esi |
508 | call inc_inet_esi |
Line 544... | Line 509... | ||
544 | 509 | ||
545 | 510 | ||
546 | ; Get the socket state |
- | |
547 | mov eax, [ebx + SOCKET.TCBState] |
- | |
548 | ;xxx cmp eax, TCB_LISTEN |
- | |
549 | ;xxx je .destroy_tcb |
- | |
550 | ;xxx cmp eax, TCB_SYN_SENT |
511 | ; Get the socket state |
551 | ;xxx je .destroy_tcb |
512 | mov eax, [ebx + SOCKET.TCBState] |
552 | cmp eax, TCB_SYN_RECEIVED |
513 | cmp eax, TCB_SYN_RECEIVED |
553 | je .fin_wait_1 |
514 | je .fin_wait_1 |
Line 554... | Line 515... | ||
554 | cmp eax, TCB_ESTABLISHED |
515 | cmp eax, TCB_ESTABLISHED |
555 | je .fin_wait_1 |
516 | je .fin_wait_1 |
556 | - | ||
557 | ; assume CLOSE WAIT |
517 | |
558 | ; Send a fin, then enter last-ack state |
518 | ; assume CLOSE WAIT |
Line 559... | Line 519... | ||
559 | ; TODO: check if it's really a TCB_CLOSE_WAIT |
519 | ; Send a fin, then enter last-ack state |
560 | mov [ebx + SOCKET.TCBState], TCB_LAST_ACK |
520 | mov [ebx + SOCKET.TCBState], TCB_LAST_ACK |
Line 578... | Line 538... | ||
578 | pop ebx |
538 | pop ebx |
579 | call queue |
539 | call queue |
580 | jmp .exit |
540 | jmp .exit |
Line 581... | Line 541... | ||
581 | 541 | ||
582 | .destroy_tcb: |
- | |
Line 583... | Line 542... | ||
583 | ;xxx pop eax |
542 | .destroy_tcb: |
584 | - | ||
585 | ; Clear the socket variables |
543 | |
Line 586... | Line 544... | ||
586 | ;xxx stdcall net_socket_free, [sockAddr] |
544 | ; Clear the socket variables |
587 | stdcall net_socket_free, ebx |
545 | stdcall net_socket_free, ebx |
588 | 546 | ||
Line 594... | Line 552... | ||
594 | DEBUGF 1, "K : socket_close_tcp (fail)\n" |
552 | DEBUGF 1, "K : socket_close_tcp (fail)\n" |
595 | or eax, -1 |
553 | or eax, -1 |
596 | ret |
554 | ret |
597 | endp |
555 | endp |
Line 598... | Line -... | ||
598 | - | ||
599 | - | ||
600 | ;*************************************************************************** |
- | |
601 | ; Function |
556 | |
602 | ; socket_poll |
- | |
603 | ; |
- | |
604 | ; Description |
- | |
605 | ; socket # in ebx |
- | |
606 | ; returns count in eax. |
557 | ;; [53.2] Poll socket |
- | 558 | ; |
|
607 | ; |
559 | ; @param EBX is socket number |
- | 560 | ; @return count or bytes in rx buffer or 0 (error) in EAX |
|
608 | ;*************************************************************************** |
561 | ;; |
609 | proc socket_poll stdcall |
562 | proc socket_poll stdcall |
610 | ; DEBUGF 1, "socket_poll(0x%x)\n", ebx |
563 | ; DEBUGF 1, "socket_poll(0x%x)\n", ebx |
611 | stdcall net_socket_num_to_addr, ebx |
564 | stdcall net_socket_num_to_addr, ebx |
612 | or eax, eax |
565 | or eax, eax |
Line 613... | Line 566... | ||
613 | jz .error |
566 | jz .error |
614 | 567 | ||
Line 615... | Line 568... | ||
615 | mov eax, [eax + SOCKET.rxDataCount] |
568 | mov eax, [eax + SOCKET.rxDataCount] |
616 | ret |
- | |
617 | 569 | ret |
|
618 | .error: |
570 | |
619 | ;or eax, -1 |
571 | .error: |
Line 620... | Line -... | ||
620 | xor eax, eax |
- | |
621 | ret |
- | |
622 | endp |
- | |
623 | 572 | xor eax, eax |
|
624 | - | ||
625 | ;*************************************************************************** |
- | |
626 | ; Function |
- | |
627 | ; socket_status |
- | |
628 | ; |
573 | ret |
- | 574 | endp |
|
629 | ; Description |
575 | |
- | 576 | ;; [53.6] Get socket TCB state |
|
630 | ; socket # in ebx |
577 | ; |
631 | ; returns TCB state in eax. |
578 | ; @param EBX is socket number |
632 | ; |
579 | ; @return socket TCB state or 0 (error) in EAX |
633 | ;*************************************************************************** |
580 | ;; |
634 | proc socket_status stdcall |
581 | proc socket_status stdcall |
Line 635... | Line 582... | ||
635 | ;; DEBUGF 1, "socket_status(0x%x)\n", ebx |
582 | ;; DEBUGF 1, "socket_status(0x%x)\n", ebx |
636 | stdcall net_socket_num_to_addr, ebx |
583 | stdcall net_socket_num_to_addr, ebx |
Line 637... | Line 584... | ||
637 | or eax, eax |
584 | or eax, eax |
638 | jz .error |
- | |
639 | 585 | jz .error |
|
640 | mov eax, [eax + SOCKET.TCBState] |
586 | |
641 | ret |
587 | mov eax, [eax + SOCKET.TCBState] |
Line 642... | Line 588... | ||
642 | 588 | ret |
|
643 | .error: |
589 | |
644 | ;or eax, -1 |
- | |
645 | xor eax, eax |
- | |
646 | ret |
- | |
647 | endp |
- | |
648 | 590 | .error: |
|
649 | ; Index2RealAddr ebx |
- | |
650 | ; mov eax, [ebx + SOCKET.TCBState] |
591 | xor eax, eax |
651 | ; |
592 | ret |
652 | ; ret |
593 | endp |
653 | 594 | ||
654 | 595 | ;; [53.3] Get one byte from rx buffer |
|
655 | ;*************************************************************************** |
596 | ; This function can return 0 in two cases: if there's one byte read and |
656 | ; Function |
- | |
657 | ; socket_read |
597 | ; non left, and if an error occured. Behavior should be changed and function |
658 | ; |
598 | ; shouldn't be used for now. Consider using [53.11] instead. |
659 | ; Description |
599 | ; |
660 | ; socket # in ebx |
600 | ; @param EBX is socket number |
661 | ; returns # of bytes remaining in eax, data in bl |
601 | ; @return number of bytes left in rx buffer or 0 (error) in EAX |
Line -... | Line 602... | ||
- | 602 | ; @return byte read in BL |
|
- | 603 | ;; |
|
- | 604 | proc socket_read stdcall |
|
662 | ; |
605 | ; DEBUGF 1, "socket_read(0x%x)\n", ebx |
663 | ;*************************************************************************** |
606 | stdcall net_socket_num_to_addr, ebx |
664 | proc socket_read stdcall |
607 | or eax, eax |
665 | ; DEBUGF 1, "socket_read(0x%x)\n", ebx |
608 | jz .error |
Line 666... | Line 609... | ||
666 | stdcall net_socket_num_to_addr, ebx |
609 | |
667 | or eax, eax |
610 | lea ebx, [eax + SOCKET.lock] |
668 | jz .error |
611 | call wait_mutex |
669 | 612 | ||
670 | mov ebx, eax |
- | |
671 | mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
- | |
672 | test eax, eax |
- | |
673 | jz .error |
- | |
Line 674... | Line 613... | ||
674 | 613 | mov ebx, eax |
|
675 | dec eax |
614 | mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
676 | mov esi, ebx ; esi is address of socket |
615 | test eax, eax |
677 | mov [ebx + SOCKET.rxDataCount], eax ; store new count |
616 | jz .error_release |
- | 617 | ||
- | 618 | dec eax |
|
678 | ;movzx ebx, byte[ebx + SOCKET.rxData] ; get the byte |
619 | mov esi, ebx ; esi is address of socket |
- | 620 | mov [ebx + SOCKET.rxDataCount], eax ; store new count |
|
- | 621 | movzx eax, byte[ebx + SOCKET.rxData] ; get the byte |
|
- | 622 | ||
- | 623 | mov ecx, SOCKETBUFFSIZE - SOCKET.rxData - 1 |
|
- | 624 | lea edi, [esi + SOCKET.rxData] |
|
- | 625 | lea esi, [edi + 1] |
|
Line 679... | Line 626... | ||
679 | movzx ebx, byte[ebx + SOCKETHEADERSIZE] ; get the byte |
626 | cld |
Line -... | Line 627... | ||
- | 627 | push ecx |
|
- | 628 | shr ecx, 2 |
|
680 | add esi, SOCKETHEADERSIZE |
629 | rep movsd |
681 | mov edi, esi |
- | |
682 | inc esi |
- | |
683 | 630 | pop ecx |
|
684 | mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4 |
631 | and ecx, 3 |
685 | lea edi, [ebx + SOCKETHEADERSIZE] |
632 | rep movsb |
Line 686... | Line -... | ||
686 | lea esi, [edi + 1] |
- | |
- | 633 | ||
687 | cld |
634 | mov [ebx + SOCKET.lock], 0 |
688 | rep movsd |
635 | mov ebx, eax |
- | 636 | ||
689 | 637 | ret |
|
690 | ret |
638 | |
691 | - | ||
692 | .error: |
639 | .error_release: |
693 | ;or eax, -1 |
640 | mov [ebx + SOCKET.lock], 0 |
694 | xor eax, eax |
641 | .error: |
695 | xor ebx, ebx |
642 | xor ebx, ebx |
696 | ret |
643 | ret |
697 | endp |
- | |
698 | 644 | endp |
|
699 | 645 | ||
700 | ;*************************************************************************** |
646 | ;; [53.11] Get specified number of bytes from rx buffer |
701 | ; Function |
647 | ; Number of bytes in rx buffer can be less than requested size. In this case, |
702 | ; socket_read_packet |
648 | ; only available number of bytes is read. |
Line -... | Line 649... | ||
- | 649 | ; This function can return 0 in two cases: if there's no data to read, and if |
|
- | 650 | ; an error occured. Behavior should be changed. |
|
- | 651 | ; |
|
703 | ; |
652 | ; @param EBX is socket number |
704 | ; Description |
653 | ; @param ECX is pointer to application buffer |
705 | ; socket # in ebx |
654 | ; @param EDX is application buffer size (number of bytes to read) |
706 | ; datapointer # in ecx |
655 | ; @return number of bytes read or 0 (error) in EAX |
Line 729... | Line 678... | ||
729 | push eax |
678 | push eax |
730 | mov eax, edx ; number of bytes we want to copy must be in eax |
679 | mov eax, edx ; number of bytes we want to copy must be in eax |
731 | call .start_copy ; copy to the application |
680 | call .start_copy ; copy to the application |
Line 732... | Line 681... | ||
732 | 681 | ||
733 | mov esi, ebx ; now we're going to copy the remaining bytes to the beginning |
682 | mov esi, ebx ; now we're going to copy the remaining bytes to the beginning |
734 | add esi, SOCKETHEADERSIZE ; we dont need to copy the header |
683 | add esi, SOCKET.rxData ; we dont need to copy the header |
735 | mov edi, esi ; edi is where we're going to copy to |
684 | mov edi, esi ; edi is where we're going to copy to |
736 | add esi, edx ; esi is from where we copy |
685 | add esi, edx ; esi is from where we copy |
737 | pop ecx ; count of bytes we have left |
686 | pop ecx ; count of bytes we have left |
738 | push ecx ; push it again so we can re-use it later |
687 | push ecx ; push it again so we can re-use it later |
Line 742... | Line 691... | ||
742 | pop ecx |
691 | pop ecx |
743 | and ecx, 3 |
692 | and ecx, 3 |
744 | rep movsb ; copy remaining bytes |
693 | rep movsb ; copy remaining bytes |
Line 745... | Line 694... | ||
745 | 694 | ||
- | 695 | .exit: |
|
746 | .exit: |
696 | mov [ebx + SOCKET.lock], 0 |
Line 747... | Line 697... | ||
747 | ret ; at last, exit |
697 | ret ; at last, exit |
748 | - | ||
749 | .error: |
698 | |
750 | ;or eax, -1 |
699 | .error: |
Line 751... | Line 700... | ||
751 | xor eax, eax |
700 | xor eax, eax |
752 | ret |
701 | ret |
753 | 702 | ||
754 | .copy_all_bytes: |
703 | .copy_all_bytes: |
- | 704 | xor esi, esi |
|
755 | xor esi, esi |
705 | mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) |
Line 756... | Line 706... | ||
756 | mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) |
706 | call .start_copy |
757 | call .start_copy |
707 | mov [ebx + SOCKET.lock], 0 |
758 | ret |
708 | ret |
759 | 709 | ||
760 | .start_copy: |
710 | .start_copy: |
761 | mov edi, ecx |
711 | mov edi, ecx |
762 | mov esi, ebx |
712 | mov esi, ebx |
763 | add esi, SOCKETHEADERSIZE ; we dont need to copy the header |
713 | add esi, SOCKET.rxData ; we dont need to copy the header |
764 | mov ecx, eax ; eax is count of bytes |
714 | mov ecx, eax ; eax is count of bytes |
Line 770... | Line 720... | ||
770 | and ecx, 3 |
720 | and ecx, 3 |
771 | rep movsb ; copy the rest bytes |
721 | rep movsb ; copy the rest bytes |
772 | retn ; exit, or go back to shift remaining bytes if any |
722 | retn ; exit, or go back to shift remaining bytes if any |
773 | endp |
723 | endp |
Line 774... | Line -... | ||
774 | - | ||
775 | - | ||
776 | ;*************************************************************************** |
- | |
777 | ; Function |
- | |
778 | ; socket_write |
- | |
779 | ; |
- | |
780 | ; Description |
- | |
781 | ; socket in ebx |
- | |
782 | ; # of bytes to write in ecx |
- | |
783 | ; pointer to data in edx |
- | |
784 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
724 | |
785 | ; could not queue IP packet ) |
725 | ;; [53.4] Send data through DGRAM socket |
- | 726 | ; |
|
786 | ; |
727 | ; @param EBX is socket number |
- | 728 | ; @param ECX is application data size (number of bytes to send) |
|
- | 729 | ; @param EDX is pointer to application data buffer |
|
- | 730 | ; @return 0 (sent successfully) or -1 (error) in EAX |
|
787 | ;*************************************************************************** |
731 | ;; |
788 | proc socket_write stdcall |
732 | proc socket_write stdcall |
789 | ; DEBUGF 1, "socket_write(0x%x)\n", ebx |
733 | ; DEBUGF 1, "socket_write(0x%x)\n", ebx |
790 | stdcall net_socket_num_to_addr, ebx ; get real socket address |
734 | stdcall net_socket_num_to_addr, ebx ; get real socket address |
791 | or eax, eax |
735 | or eax, eax |
Line 792... | Line 736... | ||
792 | jz .error |
736 | jz .error |
Line 793... | Line -... | ||
793 | - | ||
794 | mov ebx, eax |
- | |
795 | - | ||
796 | ; If the socket is invalid, return with an error code |
- | |
797 | cmp [ebx + SOCKET.Status], SOCK_EMPTY |
737 | |
798 | je .error |
738 | mov ebx, eax |
799 | 739 | ||
800 | mov eax, EMPTY_QUEUE |
740 | mov eax, EMPTY_QUEUE |
Line 938... | Line 878... | ||
938 | .error: |
878 | .error: |
939 | or eax, -1 |
879 | or eax, -1 |
940 | ret |
880 | ret |
941 | endp |
881 | endp |
Line 942... | Line -... | ||
942 | - | ||
943 | - | ||
944 | ;*************************************************************************** |
- | |
945 | ; Function |
882 | |
946 | ; socket_write_tcp |
883 | ;; [53.7] Send data through STREAM socket |
947 | ; |
- | |
948 | ; Description |
884 | ; |
949 | ; socket in ebx |
885 | ; @param EBX is socket number |
950 | ; # of bytes to write in ecx |
886 | ; @param ECX is application data size (number of bytes to send) |
951 | ; pointer to data in edx |
887 | ; @param EDX is pointer to application data buffer |
952 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
- | |
953 | ; could not queue IP packet ) |
888 | ; @return 0 (sent successfully) or -1 (error) in EAX |
954 | ; |
- | |
955 | ;*************************************************************************** |
889 | ;; |
956 | proc socket_write_tcp stdcall |
890 | proc socket_write_tcp stdcall |
Line 957... | Line 891... | ||
957 | local sockAddr dd ? |
891 | local sockAddr dd ? |
958 | 892 | ||
Line 962... | Line 896... | ||
962 | jz .error |
896 | jz .error |
Line 963... | Line 897... | ||
963 | 897 | ||
964 | mov ebx, eax |
898 | mov ebx, eax |
Line 965... | Line -... | ||
965 | mov [sockAddr], ebx |
- | |
966 | - | ||
967 | ; If the socket is invalid, return with an error code |
- | |
968 | cmp [ebx + SOCKET.Status], SOCK_EMPTY |
- | |
969 | je .error |
899 | mov [sockAddr], ebx |
970 | - | ||
971 | ; If the sockets window timer is nonzero, do not queue packet |
900 | |
972 | ; TODO - done |
901 | ; If the sockets window timer is nonzero, do not queue packet |
Line 973... | Line 902... | ||
973 | cmp [ebx + SOCKET.wndsizeTimer], 0 |
902 | cmp [ebx + SOCKET.wndsizeTimer], 0 |
974 | jne .error |
903 | jne .error |
Line 997... | Line 926... | ||
997 | ; Check destination IP address. |
926 | ; Check destination IP address. |
998 | ; If it is the local host IP, route it back to IP_RX |
927 | ; If it is the local host IP, route it back to IP_RX |
Line 999... | Line 928... | ||
999 | 928 | ||
1000 | pop ebx |
929 | pop ebx |
1001 | push ecx |
- | |
Line -... | Line 930... | ||
- | 930 | push ecx |
|
1002 | mov eax, NET1OUT_QUEUE |
931 | |
1003 | 932 | mov eax, NET1OUT_QUEUE |
|
1004 | mov edx, [stack_ip] |
933 | mov edx, [stack_ip] |
1005 | mov ecx, [sockAddr] |
934 | mov ecx, [sockAddr] |
1006 | cmp edx, [ecx + SOCKET.RemoteIP] |
935 | cmp edx, [ecx + SOCKET.RemoteIP] |
Line 1029... | Line 958... | ||
1029 | mov ecx, 0 |
958 | mov ecx, 0 |
Line 1030... | Line 959... | ||
1030 | 959 | ||
1031 | .next_resendq: |
960 | .next_resendq: |
1032 | cmp ecx, NUMRESENDENTRIES |
961 | cmp ecx, NUMRESENDENTRIES |
1033 | je .exit ; None found |
- | |
1034 | ;cmp byte[esi], 0xff ; XTODO: 0xff -> 0 |
962 | je .exit ; None found |
1035 | cmp dword[esi + 4], 0 |
963 | cmp dword[esi + 4], 0 |
1036 | je @f ; found one |
964 | je @f ; found one |
1037 | inc ecx |
965 | inc ecx |
1038 | add esi, 8 |
966 | add esi, 8 |
Line 1047... | Line 975... | ||
1047 | ; retries count |
975 | ; retries count |
1048 | ; retry time |
976 | ; retry time |
1049 | ; fill IP buffer associated with this descriptor |
977 | ; fill IP buffer associated with this descriptor |
Line 1050... | Line 978... | ||
1050 | 978 | ||
1051 | stdcall net_socket_addr_to_num, [sockAddr] |
- | |
1052 | ;mov [esi], al ; XTODO: al -> eax |
979 | stdcall net_socket_addr_to_num, [sockAddr] |
1053 | mov [esi + 4], eax |
980 | mov [esi + 4], eax |
1054 | mov byte[esi + 1], TCP_RETRIES |
981 | mov byte[esi + 1], TCP_RETRIES |
Line 1055... | Line 982... | ||
1055 | mov word[esi + 2], TCP_TIMEOUT |
982 | mov word[esi + 2], TCP_TIMEOUT |