Rev 261 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 261 | Rev 323 | ||
---|---|---|---|
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 | ; mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
- | |
211 | ; mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
- | |
212 | xchg ch, cl |
210 | xchg ch, cl |
213 | mov [eax + SOCKET.RemotePort], cx |
211 | mov [eax + SOCKET.RemotePort], cx |
214 | ; mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
- | |
215 | ; mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
- | |
216 | 212 | ||
217 | mov ebx, [stack_ip] |
213 | mov ebx, [stack_ip] |
218 | mov [eax + SOCKET.LocalIP], ebx |
214 | mov [eax + SOCKET.LocalIP], ebx |
219 | mov [eax + SOCKET.RemoteIP], edx |
215 | mov [eax + SOCKET.RemoteIP], edx |
220 | mov [eax + SOCKET.rxDataCount], dword 0 ; recieved data count |
216 | mov [eax + SOCKET.rxDataCount], dword 0 ; recieved data count |
221 | 217 | ||
222 | mov esi, [0x3010] |
218 | mov esi, [0x3010] |
223 | mov ebx, [esi+TASKDATA.pid] |
219 | mov ebx, [esi+TASKDATA.pid] |
224 | mov [eax + SOCKET.PID], ebx ; save the process ID |
220 | mov [eax + SOCKET.PID], ebx ; save the process ID |
225 | 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 |
226 | 222 | ||
227 | so_exit: |
223 | so_exit: |
228 | ret |
224 | ret |
229 | 225 | ||
230 | 226 | ||
231 | 227 | ||
232 | ;*************************************************************************** |
228 | ;*************************************************************************** |
233 | ; Function |
229 | ; Function |
234 | ; socket_open_tcp |
230 | ; socket_open_tcp |
235 | ; |
231 | ; |
236 | ; Description |
232 | ; Description |
237 | ; Opens a TCP socket in PASSIVE or ACTIVE mode |
233 | ; Opens a TCP socket in PASSIVE or ACTIVE mode |
238 | ; find a free socket |
234 | ; find a free socket |
239 | ; local port in ebx ( intel format ) |
235 | ; local port in ebx ( intel format ) |
240 | ; remote port in ecx ( intel format ) |
236 | ; remote port in ecx ( intel format ) |
241 | ; remote ip in edx ( in Internet byte order ) |
237 | ; remote ip in edx ( in Internet byte order ) |
242 | ; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE ) |
238 | ; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE ) |
243 | ; return socket # in eax, -1 if none available |
239 | ; return socket # in eax, -1 if none available |
244 | ; |
240 | ; |
245 | ;*************************************************************************** |
241 | ;*************************************************************************** |
246 | socket_open_tcp: |
242 | socket_open_tcp: |
247 | call get_free_socket |
243 | call get_free_socket |
248 | 244 | ||
249 | cmp eax, 0xFFFFFFFF |
245 | cmp eax, 0xFFFFFFFF |
250 | jz so_exit |
246 | jz so_exit |
251 | 247 | ||
252 | ; ax holds the socket number that is free. Get real address |
248 | ; ax holds the socket number that is free. Get real address |
253 | push eax |
249 | push eax |
254 | Index2RealAddr eax |
250 | Index2RealAddr eax |
255 | 251 | ||
256 | mov [sktAddr], eax |
252 | mov [sktAddr], eax |
257 | mov [eax], dword SOCK_OPEN |
253 | mov [eax], dword SOCK_OPEN |
258 | 254 | ||
259 | ; TODO - check this works! |
255 | ; TODO - check this works! |
260 | mov [eax + SOCKET.wndsizeTimer], dword 0 ; Reset the window timer. |
256 | mov [eax + SOCKET.wndsizeTimer], dword 0 ; Reset the window timer. |
261 | 257 | ||
262 | xchg bh, bl |
258 | xchg bh, bl |
263 | mov [eax + SOCKET.LocalPort], bx |
259 | mov [eax + SOCKET.LocalPort], bx |
264 | ; mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
260 | ; mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
265 | ; mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
261 | ; mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
266 | 262 | ||
267 | xchg ch, cl |
263 | xchg ch, cl |
268 | mov [eax + SOCKET.RemotePort], cx |
264 | mov [eax + SOCKET.RemotePort], cx |
269 | ; mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
265 | ; mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
270 | ; mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
266 | ; mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
271 | 267 | ||
272 | mov ebx, [stack_ip] |
268 | mov ebx, [stack_ip] |
273 | mov [eax + SOCKET.LocalIP], ebx |
269 | mov [eax + SOCKET.LocalIP], ebx |
274 | mov [eax + SOCKET.RemoteIP], edx |
270 | mov [eax + SOCKET.RemoteIP], edx |
275 | mov [eax + SOCKET.rxDataCount], dword 0 |
271 | mov [eax + SOCKET.rxDataCount], dword 0 |
276 | 272 | ||
277 | ; Now fill in TCB state |
273 | ; Now fill in TCB state |
278 | mov ebx, TCB_LISTEN |
274 | mov ebx, TCB_LISTEN |
279 | cmp esi, SOCKET_PASSIVE |
275 | cmp esi, SOCKET_PASSIVE |
280 | jz sot_001 |
276 | jz sot_001 |
281 | mov ebx, TCB_SYN_SENT |
277 | mov ebx, TCB_SYN_SENT |
282 | 278 | ||
283 | sot_001: |
279 | sot_001: |
284 | mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB |
280 | mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB |
285 | 281 | ||
286 | mov esi, [0x3010] |
282 | mov esi, [0x3010] |
287 | mov ecx, [esi+TASKDATA.pid] |
283 | mov ecx, [esi+TASKDATA.pid] |
288 | mov [eax + SOCKET.PID], ecx ; save the process ID |
284 | mov [eax + SOCKET.PID], ecx ; save the process ID |
289 | 285 | ||
290 | cmp ebx, TCB_LISTEN |
286 | cmp ebx, TCB_LISTEN |
291 | je sot_done |
287 | je sot_done |
292 | 288 | ||
293 | ; 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 |
294 | mov eax, EMPTY_QUEUE |
290 | mov eax, EMPTY_QUEUE |
295 | call dequeue |
291 | call dequeue |
296 | cmp ax, NO_BUFFER |
292 | cmp ax, NO_BUFFER |
297 | je sot_done |
293 | je sot_done |
298 | 294 | ||
299 | push eax |
295 | push eax |
300 | 296 | ||
301 | mov bl, 0x02 ; SYN |
297 | mov bl, 0x02 ; SYN |
302 | mov ecx, 0 |
298 | mov ecx, 0 |
303 | 299 | ||
304 | call buildTCPPacket |
300 | call buildTCPPacket |
305 | 301 | ||
306 | mov eax, NET1OUT_QUEUE |
302 | mov eax, NET1OUT_QUEUE |
307 | 303 | ||
308 | mov edx, [stack_ip] |
304 | mov edx, [stack_ip] |
309 | mov ecx, [sktAddr ] |
305 | mov ecx, [sktAddr ] |
310 | mov ecx, [ecx + 16] |
306 | mov ecx, [ecx + 16] |
311 | cmp edx, ecx |
307 | cmp edx, ecx |
312 | jne sot_notlocal |
308 | jne sot_notlocal |
313 | mov eax, IPIN_QUEUE |
309 | mov eax, IPIN_QUEUE |
314 | 310 | ||
315 | sot_notlocal: |
311 | sot_notlocal: |
316 | ; Send it. |
312 | ; Send it. |
317 | pop ebx |
313 | pop ebx |
318 | call queue |
314 | call queue |
319 | 315 | ||
320 | mov esi, [sktAddr] |
316 | mov esi, [sktAddr] |
321 | 317 | ||
322 | ; increment SND.NXT in socket |
318 | ; increment SND.NXT in socket |
323 | add esi, 48 |
319 | add esi, 48 |
324 | call inc_inet_esi |
320 | call inc_inet_esi |
325 | 321 | ||
326 | sot_done: |
322 | sot_done: |
327 | 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 |
328 | 324 | ||
329 | sot_exit: |
325 | sot_exit: |
330 | ret |
326 | ret |
331 | 327 | ||
332 | 328 | ||
333 | 329 | ||
334 | ;*************************************************************************** |
330 | ;*************************************************************************** |
335 | ; Function |
331 | ; Function |
336 | ; socket_close |
332 | ; socket_close |
337 | ; |
333 | ; |
338 | ; Description |
334 | ; Description |
339 | ; socket # in ebx |
335 | ; socket # in ebx |
340 | ; returns 0 for ok, -1 for socket not open (fail) |
336 | ; returns 0 for ok, -1 for socket not open (fail) |
341 | ; |
337 | ; |
342 | ;*************************************************************************** |
338 | ;*************************************************************************** |
343 | socket_close: |
339 | socket_close: |
344 | Index2RealAddr ebx |
340 | Index2RealAddr ebx |
345 | mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
341 | mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
346 | cmp [ebx + SOCKET.Status], dword SOCK_EMPTY |
342 | cmp [ebx + SOCKET.Status], dword SOCK_EMPTY |
347 | jz sc_exit |
343 | jz sc_exit |
348 | 344 | ||
349 | ; Clear the socket varaibles |
345 | ; Clear the socket varaibles |
350 | xor eax, eax |
346 | xor eax, eax |
351 | mov edi, ebx |
347 | mov edi, ebx |
352 | mov ecx, SOCKETHEADERSIZE |
348 | mov ecx, SOCKETHEADERSIZE |
353 | cld |
349 | cld |
354 | rep stosb |
350 | rep stosb |
355 | 351 | ||
356 | sc_exit: |
352 | sc_exit: |
357 | ret |
353 | ret |
358 | 354 | ||
359 | 355 | ||
360 | 356 | ||
361 | ;*************************************************************************** |
357 | ;*************************************************************************** |
362 | ; Function |
358 | ; Function |
363 | ; socket_close_tcp |
359 | ; socket_close_tcp |
364 | ; |
360 | ; |
365 | ; Description |
361 | ; Description |
366 | ; socket # in ebx |
362 | ; socket # in ebx |
367 | ; returns 0 for ok, -1 for socket not open (fail) |
363 | ; returns 0 for ok, -1 for socket not open (fail) |
368 | ; |
364 | ; |
369 | ;*************************************************************************** |
365 | ;*************************************************************************** |
370 | socket_close_tcp: |
366 | socket_close_tcp: |
371 | ; first, remove any resend entries |
367 | ; first, remove any resend entries |
372 | pusha |
368 | pusha |
373 | 369 | ||
374 | mov esi, resendQ |
370 | mov esi, resendQ |
375 | mov ecx, 0 |
371 | mov ecx, 0 |
376 | 372 | ||
377 | sct001: |
373 | sct001: |
378 | cmp ecx, NUMRESENDENTRIES |
374 | cmp ecx, NUMRESENDENTRIES |
379 | je sct003 ; None left |
375 | je sct003 ; None left |
380 | cmp [esi], bl |
376 | cmp [esi], bl |
381 | je sct002 ; found one |
377 | je sct002 ; found one |
382 | inc ecx |
378 | inc ecx |
383 | add esi, 4 |
379 | add esi, 4 |
384 | jmp sct001 |
380 | jmp sct001 |
385 | 381 | ||
386 | sct002: |
382 | sct002: |
387 | 383 | ||
388 | mov [esi], byte 0xFF |
384 | mov [esi], byte 0xFF |
389 | jmp sct001 |
385 | jmp sct001 |
390 | 386 | ||
391 | sct003: |
387 | sct003: |
392 | popa |
388 | popa |
393 | 389 | ||
394 | Index2RealAddr ebx |
390 | Index2RealAddr ebx |
395 | mov [sktAddr], ebx |
391 | mov [sktAddr], ebx |
396 | mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
392 | mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
397 | cmp [ebx + SOCKET.Status], dword SOCK_EMPTY |
393 | cmp [ebx + SOCKET.Status], dword SOCK_EMPTY |
398 | jz sct_exit |
394 | jz sct_exit |
399 | 395 | ||
400 | ; Now construct the response, and queue for sending by IP |
396 | ; Now construct the response, and queue for sending by IP |
401 | mov eax, EMPTY_QUEUE |
397 | mov eax, EMPTY_QUEUE |
402 | call dequeue |
398 | call dequeue |
403 | cmp ax, NO_BUFFER |
399 | cmp ax, NO_BUFFER |
404 | je stl_exit |
400 | je stl_exit |
405 | 401 | ||
406 | push eax |
402 | push eax |
407 | 403 | ||
408 | mov bl, 0x11 ; FIN + ACK |
404 | mov bl, 0x11 ; FIN + ACK |
409 | mov ecx, 0 |
405 | mov ecx, 0 |
410 | mov esi, 0 |
406 | mov esi, 0 |
411 | 407 | ||
412 | call buildTCPPacket |
408 | call buildTCPPacket |
413 | 409 | ||
414 | mov ebx, [sktAddr] |
410 | mov ebx, [sktAddr] |
415 | 411 | ||
416 | ; increament SND.NXT in socket |
412 | ; increament SND.NXT in socket |
417 | mov esi, 48 |
413 | mov esi, 48 |
418 | add esi, ebx |
414 | add esi, ebx |
419 | call inc_inet_esi |
415 | call inc_inet_esi |
420 | 416 | ||
421 | 417 | ||
422 | ; Get the socket state |
418 | ; Get the socket state |
423 | mov eax, [ebx + SOCKET.TCBState] |
419 | mov eax, [ebx + SOCKET.TCBState] |
424 | cmp eax, TCB_LISTEN |
420 | cmp eax, TCB_LISTEN |
425 | je destroyTCB |
421 | je destroyTCB |
426 | cmp eax, TCB_SYN_SENT |
422 | cmp eax, TCB_SYN_SENT |
427 | je destroyTCB |
423 | je destroyTCB |
428 | cmp eax, TCB_SYN_RECEIVED |
424 | cmp eax, TCB_SYN_RECEIVED |
429 | je sct_finwait1 |
425 | je sct_finwait1 |
430 | cmp eax, TCB_ESTABLISHED |
426 | cmp eax, TCB_ESTABLISHED |
431 | je sct_finwait1 |
427 | je sct_finwait1 |
432 | 428 | ||
433 | ; assume CLOSE WAIT |
429 | ; assume CLOSE WAIT |
434 | ; Send a fin, then enter last-ack state |
430 | ; Send a fin, then enter last-ack state |
435 | mov eax, TCB_LAST_ACK |
431 | mov eax, TCB_LAST_ACK |
436 | mov [ebx + SOCKET.TCBState], eax |
432 | mov [ebx + SOCKET.TCBState], eax |
437 | xor eax, eax |
433 | xor eax, eax |
438 | jmp sct_send |
434 | jmp sct_send |
439 | 435 | ||
440 | sct_finwait1: |
436 | sct_finwait1: |
441 | ; Send a fin, then enter finwait2 state |
437 | ; Send a fin, then enter finwait2 state |
442 | mov eax, TCB_FIN_WAIT_1 |
438 | mov eax, TCB_FIN_WAIT_1 |
443 | mov [ebx + SOCKET.TCBState], eax |
439 | mov [ebx + SOCKET.TCBState], eax |
444 | xor eax, eax |
440 | xor eax, eax |
445 | 441 | ||
446 | sct_send: |
442 | sct_send: |
447 | mov eax, NET1OUT_QUEUE |
443 | mov eax, NET1OUT_QUEUE |
448 | 444 | ||
449 | mov edx, [stack_ip] |
445 | mov edx, [stack_ip] |
450 | mov ecx, [sktAddr ] |
446 | mov ecx, [sktAddr ] |
451 | mov ecx, [ecx + 16] |
447 | mov ecx, [ecx + 16] |
452 | cmp edx, ecx |
448 | cmp edx, ecx |
453 | jne sct_notlocal |
449 | jne sct_notlocal |
454 | mov eax, IPIN_QUEUE |
450 | mov eax, IPIN_QUEUE |
455 | 451 | ||
456 | sct_notlocal: |
452 | sct_notlocal: |
457 | ; Send it. |
453 | ; Send it. |
458 | pop ebx |
454 | pop ebx |
459 | call queue |
455 | call queue |
460 | jmp sct_exit |
456 | jmp sct_exit |
461 | 457 | ||
462 | destroyTCB: |
458 | destroyTCB: |
463 | pop eax |
459 | pop eax |
464 | ; Clear the socket varaibles |
460 | ; Clear the socket varaibles |
465 | xor eax, eax |
461 | xor eax, eax |
466 | mov edi, ebx |
462 | mov edi, ebx |
467 | mov ecx, SOCKETHEADERSIZE |
463 | mov ecx, SOCKETHEADERSIZE |
468 | cld |
464 | cld |
469 | rep stosb |
465 | rep stosb |
470 | 466 | ||
471 | sct_exit: |
467 | sct_exit: |
472 | ret |
468 | ret |
473 | 469 | ||
474 | 470 | ||
475 | 471 | ||
476 | ;*************************************************************************** |
472 | ;*************************************************************************** |
477 | ; Function |
473 | ; Function |
478 | ; socket_poll |
474 | ; socket_poll |
479 | ; |
475 | ; |
480 | ; Description |
476 | ; Description |
481 | ; socket # in ebx |
477 | ; socket # in ebx |
482 | ; returns count in eax. |
478 | ; returns count in eax. |
483 | ; |
479 | ; |
484 | ;*************************************************************************** |
480 | ;*************************************************************************** |
485 | socket_poll: |
481 | socket_poll: |
486 | Index2RealAddr ebx |
482 | Index2RealAddr ebx |
487 | mov eax, [ebx + SOCKET.rxDataCount] |
483 | mov eax, [ebx + SOCKET.rxDataCount] |
488 | 484 | ||
489 | ret |
485 | ret |
490 | 486 | ||
491 | 487 | ||
492 | 488 | ||
493 | ;*************************************************************************** |
489 | ;*************************************************************************** |
494 | ; Function |
490 | ; Function |
495 | ; socket_status |
491 | ; socket_status |
496 | ; |
492 | ; |
497 | ; Description |
493 | ; Description |
498 | ; socket # in ebx |
494 | ; socket # in ebx |
499 | ; returns TCB state in eax. |
495 | ; returns TCB state in eax. |
500 | ; |
496 | ; |
501 | ;*************************************************************************** |
497 | ;*************************************************************************** |
502 | socket_status: |
498 | socket_status: |
503 | Index2RealAddr ebx |
499 | Index2RealAddr ebx |
504 | mov eax, [ebx + SOCKET.TCBState] |
500 | mov eax, [ebx + SOCKET.TCBState] |
505 | 501 | ||
506 | ret |
502 | ret |
507 | 503 | ||
508 | 504 | ||
509 | 505 | ||
510 | ;*************************************************************************** |
506 | ;*************************************************************************** |
511 | ; Function |
507 | ; Function |
512 | ; socket_read |
508 | ; socket_read |
513 | ; |
509 | ; |
514 | ; Description |
510 | ; Description |
515 | ; socket # in ebx |
511 | ; socket # in ebx |
516 | ; returns # of bytes remaining in eax, data in bl |
512 | ; returns # of bytes remaining in eax, data in bl |
517 | ; |
513 | ; |
518 | ;*************************************************************************** |
514 | ;*************************************************************************** |
519 | socket_read: |
515 | socket_read: |
520 | Index2RealAddr ebx |
516 | Index2RealAddr ebx |
521 | mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
517 | mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
522 | mov ecx, 1 |
518 | mov ecx, 1 |
523 | test eax, eax |
519 | test eax, eax |
524 | jz sr2 |
520 | jz sr2 |
525 | 521 | ||
526 | dec eax |
522 | dec eax |
527 | mov esi, ebx ; esi is address of socket |
523 | mov esi, ebx ; esi is address of socket |
528 | mov [ebx + SOCKET.rxDataCount], eax ; store new count |
524 | mov [ebx + SOCKET.rxDataCount], eax ; store new count |
529 | ;movzx ebx, byte [ebx + SOCKET.rxData] ; get the byte |
525 | ;movzx ebx, byte [ebx + SOCKET.rxData] ; get the byte |
530 | movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte |
526 | movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte |
531 | add esi, SOCKETHEADERSIZE |
527 | add esi, SOCKETHEADERSIZE |
532 | mov edi, esi |
528 | mov edi, esi |
533 | inc esi |
529 | inc esi |
534 | 530 | ||
535 | mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4 |
531 | mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4 |
536 | cld |
532 | cld |
537 | rep movsd |
533 | rep movsd |
538 | xor ecx, ecx |
534 | xor ecx, ecx |
539 | 535 | ||
540 | sr1: |
536 | sr1: |
541 | jmp sor_exit |
537 | jmp sor_exit |
542 | 538 | ||
543 | sr2: |
539 | sr2: |
544 | xor bl, bl |
540 | xor bl, bl |
545 | 541 | ||
546 | sor_exit: |
542 | sor_exit: |
547 | ret |
543 | ret |
548 | 544 | ||
- | 545 | ||
- | 546 | ;*************************************************************************** |
|
- | 547 | ; Function |
|
- | 548 | ; socket_read_packet |
|
- | 549 | ; |
|
- | 550 | ; Description |
|
- | 551 | ; socket # in ebx |
|
- | 552 | ; datapointer # in ecx |
|
- | 553 | ; buffer size in edx |
|
- | 554 | ; returns # of bytes copied in eax |
|
- | 555 | ; |
|
- | 556 | ;*************************************************************************** |
|
- | 557 | socket_read_packet: |
|
- | 558 | Index2RealAddr ebx ; get real socket address |
|
- | 559 | mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
|
- | 560 | test eax, eax ; if count of bytes is zero.. |
|
- | 561 | jz .exit ; exit function (eax will be zero) |
|
- | 562 | ||
- | 563 | test edx, edx ; if buffer size is zero, copy all data |
|
- | 564 | jz .copyallbytes |
|
- | 565 | cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data |
|
- | 566 | jge .copyallbytes |
|
- | 567 | ||
- | 568 | sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy) |
|
- | 569 | mov [ebx + SOCKET.rxDataCount], eax ; |
|
- | 570 | push eax |
|
- | 571 | mov eax, edx ; number of bytes we want to copy must be in eax |
|
- | 572 | call .startcopy ; copy to the application |
|
- | 573 | ||
- | 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 |
|
- | 576 | mov edi, esi ; edi is where we're going to copy to |
|
- | 577 | add esi, edx ; esi is from where we copy |
|
- | 578 | pop ecx ; count of bytes we have left |
|
- | 579 | push ecx ; push it again so we can re-use it later |
|
- | 580 | shr ecx, 2 ; divide eax by 4 |
|
- | 581 | cld |
|
- | 582 | rep movsd ; copy all full dwords |
|
- | 583 | pop ecx |
|
- | 584 | and ecx, 3 |
|
- | 585 | rep movsb ; copy remaining bytes |
|
- | 586 | ||
- | 587 | ret ; at last, exit |
|
- | 588 | ||
- | 589 | .copyallbytes: |
|
- | 590 | xor esi, esi |
|
- | 591 | mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) |
|
- | 592 | ||
- | 593 | .startcopy: |
|
- | 594 | mov edi, ecx ; |
|
- | 595 | add edi, std_application_base_address ; get data pointer to buffer in application |
|
- | 596 | ||
- | 597 | mov esi, ebx ; |
|
- | 598 | add esi, SOCKETHEADERSIZE ; we dont need to copy the header |
|
- | 599 | mov ecx, eax ; eax is count of bytes |
|
- | 600 | push ecx |
|
- | 601 | shr ecx, 2 ; divide eax by 4 |
|
- | 602 | cld ; copy all full dwords |
|
- | 603 | rep movsd ; |
|
- | 604 | pop ecx |
|
- | 605 | and ecx, 3 |
|
- | 606 | rep movsb ; copy the rest bytes |
|
- | 607 | ||
- | 608 | .exit: |
|
- | 609 | ret ; exit, or go back to shift remaining bytes if any |
|
- | 610 | ||
- | 611 | ||
549 | 612 | ||
550 | 613 | ||
551 | ;*************************************************************************** |
614 | ;*************************************************************************** |
552 | ; Function |
615 | ; Function |
553 | ; socket_write |
616 | ; socket_write |
554 | ; |
617 | ; |
555 | ; Description |
618 | ; Description |
556 | ; socket in ebx |
619 | ; socket in ebx |
557 | ; # of bytes to write in ecx |
620 | ; # of bytes to write in ecx |
558 | ; pointer to data in edx |
621 | ; pointer to data in edx |
559 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
622 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
560 | ; could not queue IP packet ) |
623 | ; could not queue IP packet ) |
561 | ; |
624 | ; |
562 | ;*************************************************************************** |
625 | ;*************************************************************************** |
563 | socket_write: |
626 | socket_write: |
564 | Index2RealAddr ebx |
627 | Index2RealAddr ebx |
565 | 628 | ||
566 | mov eax, 0xFFFFFFFF |
629 | mov eax, 0xFFFFFFFF |
567 | ; If the socket is invalid, return with an error code |
630 | ; If the socket is invalid, return with an error code |
568 | cmp [ebx], dword SOCK_EMPTY |
631 | cmp [ebx], dword SOCK_EMPTY |
569 | je sw_exit |
632 | je sw_exit |
570 | 633 | ||
571 | 634 | ||
572 | mov eax, EMPTY_QUEUE |
635 | mov eax, EMPTY_QUEUE |
573 | call dequeue |
636 | call dequeue |
574 | cmp ax, NO_BUFFER |
637 | cmp ax, NO_BUFFER |
575 | je sw_exit |
638 | je sw_exit |
576 | 639 | ||
577 | ; Save the queue entry number |
640 | ; Save the queue entry number |
578 | push eax |
641 | push eax |
579 | 642 | ||
580 | ; save the pointers to the data buffer & size |
643 | ; save the pointers to the data buffer & size |
581 | push edx |
644 | push edx |
582 | push ecx |
645 | push ecx |
583 | 646 | ||
584 | ; convert buffer pointer eax to the absolute address |
647 | ; convert buffer pointer eax to the absolute address |
585 | mov ecx, IPBUFFSIZE |
648 | mov ecx, IPBUFFSIZE |
586 | mul ecx |
649 | mul ecx |
587 | add eax, IPbuffs |
650 | add eax, IPbuffs |
588 | 651 | ||
589 | mov edx, eax |
652 | mov edx, eax |
590 | 653 | ||
591 | ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
654 | ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
592 | 655 | ||
593 | ; 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) |
594 | mov eax, [ebx + 8] |
657 | mov eax, [ebx + 8] |
595 | mov [edx + 12], eax ; source IP |
658 | mov [edx + 12], eax ; source IP |
596 | mov eax, [ebx + 16] |
659 | mov eax, [ebx + 16] |
597 | mov [edx + 16], eax ; Destination IP |
660 | mov [edx + 16], eax ; Destination IP |
598 | 661 | ||
599 | mov al, 0x45 |
662 | mov al, 0x45 |
600 | mov [edx], al ; Version, IHL |
663 | mov [edx], al ; Version, IHL |
601 | xor al, al |
664 | xor al, al |
602 | mov [edx + 1], al ; Type of service |
665 | mov [edx + 1], al ; Type of service |
603 | 666 | ||
604 | pop eax ; Get the UDP data length |
667 | pop eax ; Get the UDP data length |
605 | push eax |
668 | push eax |
606 | 669 | ||
607 | add eax, 20 + 8 ; add IP header and UDP header lengths |
670 | add eax, 20 + 8 ; add IP header and UDP header lengths |
608 | mov [edx + 2], ah |
671 | mov [edx + 2], ah |
609 | mov [edx + 3], al |
672 | mov [edx + 3], al |
610 | xor al, al |
673 | xor al, al |
611 | mov [edx + 4], al |
674 | mov [edx + 4], al |
612 | mov [edx + 5], al |
675 | mov [edx + 5], al |
613 | mov al, 0x40 |
676 | mov al, 0x40 |
614 | mov [edx + 6], al |
677 | mov [edx + 6], al |
615 | xor al, al |
678 | xor al, al |
616 | mov [edx + 7], al |
679 | mov [edx + 7], al |
617 | mov al, 0x20 |
680 | mov al, 0x20 |
618 | mov [edx + 8], al |
681 | mov [edx + 8], al |
619 | mov al, 17 |
682 | mov al, 17 |
620 | mov [edx + 9], al |
683 | mov [edx + 9], al |
621 | 684 | ||
622 | ; Checksum left unfilled |
685 | ; Checksum left unfilled |
623 | xor ax, ax |
686 | xor ax, ax |
624 | mov [edx + 10], ax |
687 | mov [edx + 10], ax |
625 | 688 | ||
626 | ; 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) |
627 | mov ax, [ebx + 12] |
690 | mov ax, [ebx + 12] |
628 | mov [edx + 20], ax |
691 | mov [edx + 20], ax |
629 | 692 | ||
630 | mov ax, [ebx + 20] |
693 | mov ax, [ebx + 20] |
631 | mov [edx + 20 + 2], ax |
694 | mov [edx + 20 + 2], ax |
632 | 695 | ||
633 | pop eax |
696 | pop eax |
634 | push eax |
697 | push eax |
635 | 698 | ||
636 | add eax, 8 |
699 | add eax, 8 |
637 | mov [edx + 20 + 4], ah |
700 | mov [edx + 20 + 4], ah |
638 | mov [edx + 20 + 5], al |
701 | mov [edx + 20 + 5], al |
639 | 702 | ||
640 | ; Checksum left unfilled |
703 | ; Checksum left unfilled |
641 | xor ax, ax |
704 | xor ax, ax |
642 | mov [edx + 20 + 6], ax |
705 | mov [edx + 20 + 6], ax |
643 | 706 | ||
644 | pop ecx ; count of bytes to send |
707 | pop ecx ; count of bytes to send |
645 | mov ebx, ecx ; need the length later |
708 | mov ebx, ecx ; need the length later |
646 | pop eax ; get callers ptr to data to send |
709 | pop eax ; get callers ptr to data to send |
647 | 710 | ||
648 | ; Get the address of the callers data |
711 | ; Get the address of the callers data |
649 | mov edi, [0x3010] |
712 | mov edi, [0x3010] |
650 | add edi, TASKDATA.mem_start |
713 | add edi, TASKDATA.mem_start |
651 | add eax, [edi] |
714 | add eax, [edi] |
652 | mov esi, eax |
715 | mov esi, eax |
653 | 716 | ||
654 | mov edi, edx |
717 | mov edi, edx |
655 | add edi, 28 |
718 | add edi, 28 |
656 | cld |
719 | cld |
657 | rep movsb ; copy the data across |
720 | rep movsb ; copy the data across |
658 | 721 | ||
659 | ; we have edx as IPbuffer ptr. |
722 | ; we have edx as IPbuffer ptr. |
660 | ; Fill in the UDP checksum |
723 | ; Fill in the UDP checksum |
661 | ; First, fill in pseudoheader |
724 | ; First, fill in pseudoheader |
662 | mov eax, [edx + 12] |
725 | mov eax, [edx + 12] |
663 | mov [pseudoHeader], eax |
726 | mov [pseudoHeader], eax |
664 | mov eax, [edx + 16] |
727 | mov eax, [edx + 16] |
665 | mov [pseudoHeader+4], eax |
728 | mov [pseudoHeader+4], eax |
666 | mov ax, 0x1100 ; 0 + protocol |
729 | mov ax, 0x1100 ; 0 + protocol |
667 | mov [pseudoHeader+8], ax |
730 | mov [pseudoHeader+8], ax |
668 | add ebx, 8 |
731 | add ebx, 8 |
669 | mov eax, ebx |
732 | mov eax, ebx |
670 | mov [pseudoHeader+10], ah |
733 | mov [pseudoHeader+10], ah |
671 | mov [pseudoHeader+11], al |
734 | mov [pseudoHeader+11], al |
672 | 735 | ||
673 | mov eax, pseudoHeader |
736 | mov eax, pseudoHeader |
674 | mov [checkAdd1], eax |
737 | mov [checkAdd1], eax |
675 | mov [checkSize1], word 12 |
738 | mov [checkSize1], word 12 |
676 | mov eax, edx |
739 | mov eax, edx |
677 | add eax, 20 |
740 | add eax, 20 |
678 | mov [checkAdd2], eax |
741 | mov [checkAdd2], eax |
679 | mov eax, ebx |
742 | mov eax, ebx |
680 | mov [checkSize2], ax ; was eax!! mjh 8/7/02 |
743 | mov [checkSize2], ax ; was eax!! mjh 8/7/02 |
681 | 744 | ||
682 | call checksum |
745 | call checksum |
683 | 746 | ||
684 | ; store it in the UDP checksum ( in the correct order! ) |
747 | ; store it in the UDP checksum ( in the correct order! ) |
685 | mov ax, [checkResult] |
748 | mov ax, [checkResult] |
686 | 749 | ||
687 | ; 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 |
688 | ; (0 is reserved for 'not used') |
751 | ; (0 is reserved for 'not used') |
689 | cmp ax, 0 |
752 | cmp ax, 0 |
690 | jne sw_001 |
753 | jne sw_001 |
691 | mov ax, 0xffff |
754 | mov ax, 0xffff |
692 | 755 | ||
693 | sw_001: |
756 | sw_001: |
694 | mov [edx + 20 + 6], ah |
757 | mov [edx + 20 + 6], ah |
695 | mov [edx + 20 + 7], al |
758 | mov [edx + 20 + 7], al |
696 | 759 | ||
697 | ; Fill in the IP header checksum |
760 | ; Fill in the IP header checksum |
698 | GET_IHL ecx,edx ; get IP-Header length |
761 | GET_IHL ecx,edx ; get IP-Header length |
699 | stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size |
762 | stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size |
700 | 763 | ||
701 | mov [edx + 10], ah |
764 | mov [edx + 10], ah |
702 | mov [edx + 11], al |
765 | mov [edx + 11], al |
703 | 766 | ||
704 | ; Check destination IP address. |
767 | ; Check destination IP address. |
705 | ; 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 |
706 | 769 | ||
707 | pop ebx |
770 | pop ebx |
708 | mov eax, NET1OUT_QUEUE |
771 | mov eax, NET1OUT_QUEUE |
709 | 772 | ||
710 | mov ecx, [ edx + 16] |
773 | mov ecx, [ edx + 16] |
711 | mov edx, [stack_ip] |
774 | mov edx, [stack_ip] |
712 | cmp edx, ecx |
775 | cmp edx, ecx |
713 | jne sw_notlocal |
776 | jne sw_notlocal |
714 | mov eax, IPIN_QUEUE |
777 | mov eax, IPIN_QUEUE |
715 | 778 | ||
716 | sw_notlocal: |
779 | sw_notlocal: |
717 | ; Send it. |
780 | ; Send it. |
718 | call queue |
781 | call queue |
719 | 782 | ||
720 | xor eax, eax |
783 | xor eax, eax |
721 | 784 | ||
722 | sw_exit: |
785 | sw_exit: |
723 | ret |
786 | ret |
724 | 787 | ||
725 | 788 | ||
726 | 789 | ||
727 | ;*************************************************************************** |
790 | ;*************************************************************************** |
728 | ; Function |
791 | ; Function |
729 | ; socket_write_tcp |
792 | ; socket_write_tcp |
730 | ; |
793 | ; |
731 | ; Description |
794 | ; Description |
732 | ; socket in ebx |
795 | ; socket in ebx |
733 | ; # of bytes to write in ecx |
796 | ; # of bytes to write in ecx |
734 | ; pointer to data in edx |
797 | ; pointer to data in edx |
735 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
798 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
736 | ; could not queue IP packet ) |
799 | ; could not queue IP packet ) |
737 | ; |
800 | ; |
738 | ;*************************************************************************** |
801 | ;*************************************************************************** |
739 | socket_write_tcp: |
802 | socket_write_tcp: |
740 | Index2RealAddr ebx |
803 | Index2RealAddr ebx |
741 | 804 | ||
742 | mov [sktAddr], ebx |
805 | mov [sktAddr], ebx |
743 | 806 | ||
744 | mov eax, 0xFFFFFFFF |
807 | mov eax, 0xFFFFFFFF |
745 | ; If the socket is invalid, return with an error code |
808 | ; If the socket is invalid, return with an error code |
746 | cmp [ebx], dword SOCK_EMPTY |
809 | cmp [ebx], dword SOCK_EMPTY |
747 | je swt_exit |
810 | je swt_exit |
748 | 811 | ||
749 | ; If the sockets window timer is nonzero, do not queue packet |
812 | ; If the sockets window timer is nonzero, do not queue packet |
750 | ; TODO - done |
813 | ; TODO - done |
751 | cmp [ebx + SOCKET.wndsizeTimer], dword 0 |
814 | cmp [ebx + SOCKET.wndsizeTimer], dword 0 |
752 | jne swt_exit |
815 | jne swt_exit |
753 | 816 | ||
754 | mov eax, EMPTY_QUEUE |
817 | mov eax, EMPTY_QUEUE |
755 | call dequeue |
818 | call dequeue |
756 | cmp ax, NO_BUFFER |
819 | cmp ax, NO_BUFFER |
757 | je swt_exit |
820 | je swt_exit |
758 | 821 | ||
759 | push eax |
822 | push eax |
760 | 823 | ||
761 | mov bl, 0x10 ; ACK |
824 | mov bl, 0x10 ; ACK |
762 | 825 | ||
763 | ; Get the address of the callers data |
826 | ; Get the address of the callers data |
764 | mov edi, [0x3010] |
827 | mov edi, [0x3010] |
765 | add edi, TASKDATA.mem_start |
828 | add edi, TASKDATA.mem_start |
766 | add edx, [edi] |
829 | add edx, [edi] |
767 | mov esi, edx |
830 | mov esi, edx |
768 | 831 | ||
769 | pop eax |
832 | pop eax |
770 | push eax |
833 | push eax |
771 | 834 | ||
772 | push ecx |
835 | push ecx |
773 | call buildTCPPacket |
836 | call buildTCPPacket |
774 | pop ecx |
837 | pop ecx |
775 | 838 | ||
776 | ; Check destination IP address. |
839 | ; Check destination IP address. |
777 | ; 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 |
778 | 841 | ||
779 | pop ebx |
842 | pop ebx |
780 | push ecx |
843 | push ecx |
781 | mov eax, NET1OUT_QUEUE |
844 | mov eax, NET1OUT_QUEUE |
782 | 845 | ||
783 | mov edx, [stack_ip] |
846 | mov edx, [stack_ip] |
784 | mov ecx, [sktAddr ] |
847 | mov ecx, [sktAddr ] |
785 | mov ecx, [ecx + 16] |
848 | mov ecx, [ecx + 16] |
786 | cmp edx, ecx |
849 | cmp edx, ecx |
787 | jne swt_notlocal |
850 | jne swt_notlocal |
788 | mov eax, IPIN_QUEUE |
851 | mov eax, IPIN_QUEUE |
789 | 852 | ||
790 | swt_notlocal: |
853 | swt_notlocal: |
791 | pop ecx |
854 | pop ecx |
792 | 855 | ||
793 | push ebx ; save ipbuffer number |
856 | push ebx ; save ipbuffer number |
794 | 857 | ||
795 | call queue |
858 | call queue |
796 | 859 | ||
797 | mov esi, [sktAddr] |
860 | mov esi, [sktAddr] |
798 | 861 | ||
799 | ; increament SND.NXT in socket |
862 | ; increament SND.NXT in socket |
800 | ; Amount to increment by is in ecx |
863 | ; Amount to increment by is in ecx |
801 | add esi, 48 |
864 | add esi, 48 |
802 | call add_inet_esi |
865 | call add_inet_esi |
803 | 866 | ||
804 | pop ebx |
867 | pop ebx |
805 | 868 | ||
806 | ; Copy the IP buffer to a resend queue |
869 | ; Copy the IP buffer to a resend queue |
807 | ; If there isn't one, dont worry about it for now |
870 | ; If there isn't one, dont worry about it for now |
808 | mov esi, resendQ |
871 | mov esi, resendQ |
809 | mov ecx, 0 |
872 | mov ecx, 0 |
810 | 873 | ||
811 | swt003: |
874 | swt003: |
812 | cmp ecx, NUMRESENDENTRIES |
875 | cmp ecx, NUMRESENDENTRIES |
813 | je swt001 ; None found |
876 | je swt001 ; None found |
814 | cmp [esi], byte 0xFF |
877 | cmp [esi], byte 0xFF |
815 | je swt002 ; found one |
878 | je swt002 ; found one |
816 | inc ecx |
879 | inc ecx |
817 | add esi, 4 |
880 | add esi, 4 |
818 | jmp swt003 |
881 | jmp swt003 |
819 | 882 | ||
820 | swt002: |
883 | swt002: |
821 | push ebx |
884 | push ebx |
822 | 885 | ||
823 | ; OK, we have a buffer descriptor ptr in esi. |
886 | ; OK, we have a buffer descriptor ptr in esi. |
824 | ; resend entry # in ecx |
887 | ; resend entry # in ecx |
825 | ; Populate it |
888 | ; Populate it |
826 | ; socket # |
889 | ; socket # |
827 | ; retries count |
890 | ; retries count |
828 | ; retry time |
891 | ; retry time |
829 | ; fill IP buffer associated with this descriptor |
892 | ; fill IP buffer associated with this descriptor |
830 | 893 | ||
831 | mov eax, [sktAddr] |
894 | mov eax, [sktAddr] |
832 | sub eax, sockets |
895 | sub eax, sockets |
833 | shr eax, 12 ; get skt # |
896 | shr eax, 12 ; get skt # |
834 | mov [esi], al |
897 | mov [esi], al |
835 | mov [esi + 1], byte TCP_RETRIES |
898 | mov [esi + 1], byte TCP_RETRIES |
836 | mov [esi + 2], word TCP_TIMEOUT |
899 | mov [esi + 2], word TCP_TIMEOUT |
837 | 900 | ||
838 | inc ecx |
901 | inc ecx |
839 | ; Now get buffer location, and copy buffer across. argh! more copying,, |
902 | ; Now get buffer location, and copy buffer across. argh! more copying,, |
840 | mov edi, resendBuffer - IPBUFFSIZE |
903 | mov edi, resendBuffer - IPBUFFSIZE |
841 | swt002a: |
904 | swt002a: |
842 | add edi, IPBUFFSIZE |
905 | add edi, IPBUFFSIZE |
843 | loop swt002a |
906 | loop swt002a |
844 | 907 | ||
845 | ; we have dest buffer location in edi |
908 | ; we have dest buffer location in edi |
846 | pop eax |
909 | pop eax |
847 | ; convert source buffer pointer eax to the absolute address |
910 | ; convert source buffer pointer eax to the absolute address |
848 | mov ecx, IPBUFFSIZE |
911 | mov ecx, IPBUFFSIZE |
849 | mul ecx |
912 | mul ecx |
850 | add eax, IPbuffs |
913 | add eax, IPbuffs |
851 | mov esi, eax |
914 | mov esi, eax |
852 | 915 | ||
853 | ; do copy |
916 | ; do copy |
854 | mov ecx, IPBUFFSIZE |
917 | mov ecx, IPBUFFSIZE |
855 | cld |
918 | cld |
856 | rep movsb |
919 | rep movsb |
857 | 920 | ||
858 | swt001: |
921 | swt001: |
859 | xor eax, eax |
922 | xor eax, eax |
860 | 923 | ||
861 | swt_exit: |
924 | swt_exit: |
862 | ret |
925 | ret |