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