Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | ha | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; STACK.INC ;; |
||
4 | ;; ;; |
||
5 | ;; TCP/IP stack for Menuet OS ;; |
||
6 | ;; ;; |
||
7 | ;; Version 0.7 4th July 2004 ;; |
||
8 | ;; ;; |
||
9 | ;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; |
||
10 | ;; ;; |
||
11 | ;; See file COPYING for details ;; |
||
12 | ;; ;; |
||
13 | ;; Version 0.7 ;; |
||
14 | ;; Added a timer per socket to allow delays when rx window ;; |
||
15 | ;; gets below 1KB ;; |
||
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
17 | |||
18 | |||
19 | ;******************************************************************* |
||
20 | ; Interface |
||
21 | ; The interfaces defined in ETHERNET.INC plus: |
||
22 | ; stack_init |
||
23 | ; stack_handler |
||
24 | ; app_stack_handler |
||
25 | ; app_socket_handler |
||
26 | ; checksum |
||
27 | ; |
||
28 | ;******************************************************************* |
||
29 | |||
30 | |||
31 | |||
32 | ; |
||
33 | ; IP Packet after reception - Normal IP packet format |
||
34 | ; |
||
35 | ; 0 1 2 3 |
||
36 | ; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
||
37 | ; |
||
38 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
39 | ;0 |Version| IHL |Type of Service| Total Length | |
||
40 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
41 | ;4 | Identification |Flags| Fragment Offset | |
||
42 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
43 | ;8 | Time to Live | Protocol | Header Checksum | |
||
44 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
45 | ;12 | Source Address | |
||
46 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
47 | ;16 | Destination Address | |
||
48 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
49 | ; | Data | |
||
50 | ; +-+-+-.......... -+ |
||
51 | |||
52 | |||
53 | ; TCP Payload ( Data field in IP datagram ) |
||
54 | ; |
||
55 | ; 0 1 2 3 |
||
56 | ; 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 |
||
57 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
58 | ;20 | Source Port | Destination Port | |
||
59 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
60 | ;24 | Sequence Number | |
||
61 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
62 | ;28 | Acknowledgment Number | |
||
63 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
64 | ;32 | Data | |U|A|P|R|S|F| | |
||
65 | ; | Offset| Reserved |R|C|S|S|Y|I| Window | |
||
66 | ; | | |G|K|H|T|N|N| | |
||
67 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
68 | ;36 | Checksum | Urgent Pointer | |
||
69 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
70 | ;40 | Options | Padding | |
||
71 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
72 | ; | data |
||
73 | |||
74 | |||
75 | ; |
||
76 | ; UDP Payload ( Data field in IP datagram ) |
||
77 | ; |
||
78 | ; 0 1 2 3 |
||
79 | ; 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 |
||
80 | ; |
||
81 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
82 | ; | Source Port | Destination Port | |
||
83 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
84 | ; | Length ( UDP Header + Data ) | Checksum | |
||
85 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
86 | ; | UDP Data | |
||
87 | ; +-+-+-.......... -+ |
||
88 | ; |
||
89 | |||
90 | |||
91 | ; |
||
92 | ; Socket Descriptor + Buffer |
||
93 | ; |
||
94 | ; 0 1 2 3 |
||
95 | ; 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 |
||
96 | ; |
||
97 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
98 | ; | Status ( of this buffer ) | |
||
99 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
100 | ; | Application Process ID | |
||
101 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
102 | ; | Local IP Address | |
||
103 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
104 | ; | Local IP Port | Unused ( set to 0 ) | |
||
105 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
106 | ; | Remote IP Address | |
||
107 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
108 | ; | Remote IP Port | Unused ( set to 0 ) | |
||
109 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
110 | ; 24| Rx Data Count INTEL format| |
||
111 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
112 | ; 28| TCB STATE INTEL format| |
||
113 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
114 | ; 32| TCB Timer (seconds) INTEL format| |
||
115 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
116 | ; 36| ISS (Inital Sequence # used by this connection ) INET format| |
||
117 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
118 | ; 40| IRS ( Inital Receive Sequence # ) INET format| |
||
119 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
120 | ; 44| SND.UNA Seq # of unack'ed sent packets INET format| |
||
121 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
122 | ; 48| SND.NXT Next send seq # to use INET format| |
||
123 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
124 | ; 52| SND.WND Send window INET format| |
||
125 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
126 | ; 56| RCV.NXT Next expected receive sequence # INET format| |
||
127 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
128 | ; 60| RCV.WND Receive window INET format| |
||
129 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
130 | ; 64| SEG.LEN Segment length INTEL format| |
||
131 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
132 | ; 68| SEG.WND Segment window INTEL format| |
||
133 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
134 | ; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format| |
||
135 | ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
136 | ; 76| RX Data | |
||
137 | ; +-+-+-.......... -+ |
||
138 | |||
139 | |||
140 | |||
141 | ; IP protocol numbers |
||
142 | PROTOCOL_ICMP equ 1 |
||
143 | PROTOCOL_TCP equ 6 |
||
144 | PROTOCOL_UDP equ 17 |
||
145 | |||
146 | |||
147 | ; TIPBUFF status values |
||
148 | BUFF_EMPTY equ 0 |
||
149 | BUFF_RX_FULL equ 1 |
||
150 | BUFF_ALLOCATED equ 2 |
||
151 | BUFF_TX_FULL equ 3 |
||
152 | |||
153 | NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX |
||
154 | |||
155 | SOCK_EMPTY equ 0 ; socket not in use |
||
156 | SOCK_OPEN equ 1 ; open issued, but no data sent |
||
157 | |||
158 | ; TCP opening modes |
||
159 | SOCKET_PASSIVE equ 0 |
||
160 | SOCKET_ACTIVE equ 1 |
||
161 | |||
162 | ; TCP TCB states |
||
163 | TCB_LISTEN equ 1 |
||
164 | TCB_SYN_SENT equ 2 |
||
165 | TCB_SYN_RECEIVED equ 3 |
||
166 | TCB_ESTABLISHED equ 4 |
||
167 | TCB_FIN_WAIT_1 equ 5 |
||
168 | TCB_FIN_WAIT_2 equ 6 |
||
169 | TCB_CLOSE_WAIT equ 7 |
||
170 | TCB_CLOSING equ 8 |
||
171 | TCB_LAST_ACK equ 9 |
||
172 | TCB_TIME_WAIT equ 10 |
||
173 | TCB_CLOSED equ 11 |
||
174 | |||
175 | TWOMSL equ 10 ; # of secs to wait before closing socket |
||
176 | |||
177 | ; socket buffers |
||
178 | SOCKETBUFFSIZE equ 4096 ; state + config + buffer. |
||
179 | SOCKETHEADERSIZE equ 76 ; thus 4096 - SOCKETHEADERSIZE bytes data |
||
180 | |||
181 | NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20 |
||
182 | |||
183 | |||
184 | NUMQUEUES equ 4 |
||
185 | EMPTY_QUEUE equ 0 |
||
186 | IPIN_QUEUE equ 1 |
||
187 | IPOUT_QUEUE equ 2 |
||
188 | NET1OUT_QUEUE equ 3 |
||
189 | |||
190 | NO_BUFFER equ 0xFFFF |
||
191 | IPBUFFSIZE equ 1500 ; MTU of an ethernet packet |
||
192 | NUMQUEUEENTRIES equ NUM_IPBUFFERS |
||
193 | NUMRESENDENTRIES equ 18 ; Buffers for TCP resend packets |
||
194 | TCP_RETRIES equ 5 ; Number of times to resend a packet |
||
195 | TCP_TIMEOUT equ 10 ; resend if not replied to in x hs |
||
196 | |||
197 | ; These are the 0x40 function codes for application access to the stack |
||
198 | STACK_DRIVER_STATUS equ 52 |
||
199 | SOCKET_INTERFACE equ 53 |
||
200 | |||
201 | |||
202 | ; 128KB allocated for the stack and network driver buffers and other |
||
203 | ; data requirements |
||
204 | stack_data_start equ 0x700000 |
||
205 | eth_data_start equ 0x700000 |
||
206 | stack_data equ 0x704000 |
||
207 | stack_data_end equ 0x71ffff |
||
208 | |||
209 | ; 32 bit word |
||
210 | stack_config equ stack_data |
||
211 | ; 32 bit word - IP Address in network format |
||
212 | stack_ip equ stack_data + 4 |
||
213 | ; 1 byte. 0 == inactive, 1 = active |
||
214 | slip_active equ stack_data + 8 ; no longer used |
||
215 | ; 1 byte. 0 == inactive, 1 = active |
||
216 | ethernet_active equ stack_data + 9 |
||
217 | unused equ stack_data + 10 |
||
218 | ; word. Buffer number, -1 if none |
||
219 | rx_buff_ptr equ stack_data + 12 |
||
220 | ; dword. Buffer number, -1 if none |
||
221 | tx_buff_ptr equ stack_data + 16 |
||
222 | ; byte. |
||
223 | slip_rx_state equ stack_data + 20 ; no longer used |
||
224 | ; byte |
||
225 | slip_tx_state equ stack_data + 21 ; no longer used |
||
226 | ; dword. Index into data |
||
227 | rx_data_ptr equ stack_data + 22 |
||
228 | ; dword. Index into data |
||
229 | tx_data_ptr equ stack_data + 26 |
||
230 | ; word. Count of bytes to send |
||
231 | tx_msg_len equ stack_data + 30 |
||
232 | ; Address of selected socket |
||
233 | sktAddr equ stack_data + 32 |
||
234 | ; Parameter to checksum routine - data ptr |
||
235 | checkAdd1 equ stack_data + 36 |
||
236 | ; Parameter to checksum routine - 2nd data ptr |
||
237 | checkAdd2 equ stack_data + 40 |
||
238 | ; Parameter to checksum routine - data size |
||
239 | checkSize1 equ stack_data + 44 |
||
240 | ; Parameter to checksum routine - 2nd data size |
||
241 | checkSize2 equ stack_data + 46 |
||
242 | ; result of checksum routine |
||
243 | checkResult equ stack_data + 48 |
||
244 | |||
245 | ; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len| |
||
246 | pseudoHeader equ stack_data + 50 |
||
247 | |||
248 | ; receive and transmit IP buffer allocation |
||
249 | sockets equ stack_data + 62 |
||
250 | Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS) |
||
251 | ; 1560 byte buffer for rx / tx ethernet packets |
||
252 | Ether_buffer equ Next_free2 |
||
253 | Next_free3 equ Ether_buffer + 1560 |
||
254 | last_1sTick equ Next_free3 |
||
255 | IPbuffs equ Next_free3 + 1 |
||
256 | queues equ IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE ) |
||
257 | queueList equ queues + (2 * NUMQUEUES) |
||
258 | last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES ) |
||
259 | |||
260 | ;resendQ equ queueList + ( 2 * NUMQUEUEENTRIES ) |
||
261 | ;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP |
||
262 | ; equ resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES ) |
||
263 | |||
264 | |||
265 | |||
266 | resendQ equ 0x770000 |
||
267 | resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP |
||
268 | |||
269 | |||
270 | ;*************************************************************************** |
||
271 | ; Function |
||
272 | ; stack_init |
||
273 | ; |
||
274 | ; Description |
||
275 | ; Clear all allocated memory to zero. This ensures that |
||
276 | ; on startup, the stack is inactive, and consumes no resources |
||
277 | ; This is a kernel function, called prior to the OS main loop |
||
278 | ; in set_variables |
||
279 | ; |
||
280 | ;*************************************************************************** |
||
281 | stack_init: |
||
282 | xor eax,eax |
||
283 | mov edi,stack_data_start |
||
284 | mov ecx,0x20000 / 4 ; Assume that we have 128KB of data |
||
285 | cld |
||
286 | rep stosd |
||
287 | |||
288 | ; Initialise TCP resend queue data structures |
||
289 | mov eax, 0xFFFFFFFF |
||
290 | mov edi, resendQ |
||
291 | mov ecx, NUMRESENDENTRIES ; 1 dword per entry |
||
292 | cld |
||
293 | rep stosd |
||
294 | |||
295 | |||
296 | mov eax, 0xFFFFFFFF |
||
297 | mov [rx_buff_ptr], eax |
||
298 | mov [tx_buff_ptr], eax |
||
299 | |||
300 | ; Put in some defaults : slip, 0x3f8, 4, ip=192.168.1.22 |
||
301 | ; Saves me entering them each boot up when debugging |
||
302 | mov eax, 0x03f80401 |
||
303 | mov [stack_config], eax |
||
304 | mov eax, 0xc801a8c0 |
||
305 | mov [stack_ip], eax |
||
306 | |||
307 | call queueInit |
||
308 | |||
309 | ; The following block sets up the 1s timer |
||
310 | mov al,0x0 |
||
311 | out 0x70,al |
||
312 | in al,0x71 |
||
313 | mov [last_1sTick], al |
||
314 | |||
315 | ret |
||
316 | |||
317 | |||
318 | |||
319 | ;*************************************************************************** |
||
320 | ; Function |
||
321 | ; stack_handler |
||
322 | ; |
||
323 | ; Description |
||
324 | ; The kernel loop routine for the stack |
||
325 | ; This is a kernel function, called in the main loop |
||
326 | ; |
||
327 | ;*************************************************************************** |
||
328 | stack_handler: |
||
329 | |||
330 | call ethernet_driver |
||
331 | call ip_rx |
||
332 | |||
333 | |||
334 | ; Test for 10ms tick, call tcp timer |
||
335 | mov eax, [timer_ticks] ;[0xfdf0] |
||
336 | cmp eax, [last_1hsTick] |
||
337 | je sh_001 |
||
338 | |||
339 | mov [last_1hsTick], eax |
||
340 | call tcp_tx_handler |
||
341 | |||
342 | sh_001: |
||
343 | |||
344 | ; Test for 1 second event, call 1s timer functions |
||
345 | mov al,0x0 ;second |
||
346 | out 0x70,al |
||
347 | in al,0x71 |
||
348 | cmp al, [last_1sTick] |
||
349 | je sh_exit |
||
350 | |||
351 | mov [last_1sTick], al |
||
352 | |||
353 | call arp_timer |
||
354 | call tcp_tcb_handler |
||
355 | |||
356 | sh_exit: |
||
357 | ret |
||
358 | |||
359 | |||
360 | |||
361 | |||
362 | ;*************************************************************************** |
||
363 | ; Function |
||
364 | ; is_localport_unused |
||
365 | ; |
||
366 | ; Description |
||
367 | ; scans through all the active sockets , looking to see if the |
||
368 | ; port number specified in bx is in use as a localport number. |
||
369 | ; This is useful when you want a to generate a unique local port |
||
370 | ; number. |
||
371 | ; On return, eax = 1 for free, 0 for in use |
||
372 | ; |
||
373 | ;*************************************************************************** |
||
374 | is_localport_unused: |
||
375 | mov al, bh |
||
376 | mov ah, bl |
||
377 | mov bx, ax |
||
378 | |||
379 | mov edx, SOCKETBUFFSIZE * NUM_SOCKETS |
||
380 | mov ecx, NUM_SOCKETS |
||
381 | mov eax, 0 ; Assume the return value is 'in use' |
||
382 | |||
383 | ilu1: |
||
384 | sub edx, SOCKETBUFFSIZE |
||
385 | cmp [edx + sockets + 12], bx |
||
386 | loopnz ilu1 ; Return back if the socket is occupied |
||
387 | |||
388 | jz ilu_exit |
||
389 | inc eax ; return port not in use |
||
390 | |||
391 | ilu_exit: |
||
392 | ret |
||
393 | |||
394 | |||
395 | |||
396 | ;*************************************************************************** |
||
397 | ; Function |
||
398 | ; get_free_socket |
||
399 | ; |
||
400 | ; Description |
||
401 | ; |
||
402 | ;*************************************************************************** |
||
403 | get_free_socket: |
||
404 | push ecx |
||
405 | mov eax, SOCKETBUFFSIZE * NUM_SOCKETS |
||
406 | mov ecx, NUM_SOCKETS |
||
407 | |||
408 | gfs1: |
||
409 | sub eax, SOCKETBUFFSIZE |
||
410 | cmp [eax + sockets], dword SOCK_EMPTY |
||
411 | loopnz gfs1 ; Return back if the socket is occupied |
||
412 | mov eax, ecx |
||
413 | pop ecx |
||
414 | jz gfs_exit |
||
415 | mov eax, 0xFFFFFFFF |
||
416 | |||
417 | gfs_exit: |
||
418 | ret |
||
419 | |||
420 | |||
421 | |||
422 | ;*************************************************************************** |
||
423 | ; Function |
||
424 | ; checksum |
||
425 | ; |
||
426 | ; Description |
||
427 | ; checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult |
||
428 | ; Dont break anything; Most registers are used by the caller |
||
429 | ; This code is derived from the 'C' source, cksum.c, in the book |
||
430 | ; Internetworking with TCP/IP Volume II by D.E. Comer |
||
431 | ; |
||
432 | ;*************************************************************************** |
||
433 | checksum: |
||
434 | pusha |
||
435 | |||
436 | xor edx, edx ; edx is the accumulative checksum |
||
437 | xor ebx, ebx |
||
438 | mov cx, [checkSize1] |
||
439 | shr cx, 1 |
||
440 | jz cs1_1 |
||
441 | |||
442 | mov eax, [checkAdd1] |
||
443 | |||
444 | cs1: |
||
445 | mov bh, [eax] |
||
446 | mov bl, [eax + 1] |
||
447 | |||
448 | add eax, 2 |
||
449 | add edx, ebx |
||
450 | |||
451 | loopw cs1 |
||
452 | |||
453 | cs1_1: |
||
454 | and word [checkSize1], 0x01 |
||
455 | jz cs_test2 |
||
456 | |||
457 | mov bh, [eax] |
||
458 | xor bl, bl |
||
459 | |||
460 | add edx, ebx |
||
461 | |||
462 | cs_test2: |
||
463 | mov cx, [checkSize2] |
||
464 | cmp cx, 0 |
||
465 | jz cs_exit ; Finished if no 2nd buffer |
||
466 | |||
467 | shr cx, 1 |
||
468 | jz cs2_1 |
||
469 | |||
470 | mov eax, [checkAdd2] |
||
471 | |||
472 | cs2: |
||
473 | mov bh, [eax] |
||
474 | mov bl, [eax + 1] |
||
475 | |||
476 | add eax, 2 |
||
477 | add edx, ebx |
||
478 | |||
479 | loopw cs2 |
||
480 | |||
481 | cs2_1: |
||
482 | and word [checkSize2], 0x01 |
||
483 | jz cs_exit |
||
484 | |||
485 | mov bh, [eax] |
||
486 | xor bl, bl |
||
487 | |||
488 | add edx, ebx |
||
489 | |||
490 | cs_exit: |
||
491 | mov ebx, edx |
||
492 | |||
493 | shr ebx, 16 |
||
494 | and edx, 0xffff |
||
495 | add edx, ebx |
||
496 | mov eax, edx |
||
497 | shr eax, 16 |
||
498 | add edx, eax |
||
499 | not dx |
||
500 | |||
501 | mov [checkResult], dx |
||
502 | popa |
||
503 | ret |
||
504 | |||
505 | |||
506 | |||
507 | |||
508 | ;*************************************************************************** |
||
509 | ; Function |
||
510 | ; app_stack_handler |
||
511 | ; |
||
512 | ; Description |
||
513 | ; This is an application service, called by int 0x40 fn 52 |
||
514 | ; It provides application access to the network interface layer |
||
515 | ; |
||
516 | ;*************************************************************************** |
||
517 | app_stack_handler: |
||
518 | cmp eax, 0 |
||
519 | jnz not0 |
||
520 | ; Read the configuartion word |
||
521 | mov eax, [stack_config] |
||
522 | ret |
||
523 | |||
524 | not0: |
||
525 | cmp eax, 1 |
||
526 | jnz not1 |
||
527 | ; read the IP address |
||
528 | |||
529 | mov eax, [stack_ip] |
||
530 | ret |
||
531 | |||
532 | not1: |
||
533 | cmp eax, 2 |
||
534 | jnz not2 |
||
535 | |||
536 | ; write the configuration word |
||
537 | mov [stack_config], ebx |
||
538 | |||
539 | ; |
||
540 | ; If ethernet now enabled, probe for the card, reset it and empty |
||
541 | ; the packet buffer |
||
542 | ; If all successfull, enable the card. |
||
543 | ; If ethernet now disabled, set it as disabled. Should really |
||
544 | ; empty the tcpip data area too. |
||
545 | |||
546 | ; ethernet interface is '3' in ls 7 bits |
||
547 | and bl, 0x7f |
||
548 | cmp bl, 3 |
||
549 | |||
550 | je ash_eth_enable |
||
551 | ; Ethernet isn't enabled, so make sure that the card is disabled |
||
552 | mov [ethernet_active], byte 0 |
||
553 | |||
554 | ret |
||
555 | |||
556 | ash_eth_enable: |
||
557 | ; Probe for the card. This will reset it and enable the interface |
||
558 | ; if found |
||
559 | call eth_probe |
||
560 | cmp eax, 0 |
||
561 | je ash_eth_done ; Abort if no hardware found |
||
562 | |||
563 | mov [ethernet_active], byte 1 |
||
564 | |||
565 | ash_eth_done: |
||
566 | ret |
||
567 | |||
568 | not2: |
||
569 | cmp eax, 3 |
||
570 | jnz not3 |
||
571 | ; write the IP Address |
||
572 | mov [stack_ip], ebx |
||
573 | ret |
||
574 | |||
575 | not3: |
||
576 | cmp eax, 4 |
||
577 | jnz not4 |
||
578 | ; Enabled the slip driver on the comm port |
||
579 | ; slip removed |
||
580 | ret |
||
581 | |||
582 | not4: |
||
583 | cmp eax, 5 |
||
584 | jnz not5 |
||
585 | ; Disable the slip driver on the comm port |
||
586 | ; slip removed |
||
587 | |||
588 | not5: |
||
589 | cmp eax, 6 |
||
590 | jnz not6 |
||
591 | |||
592 | ; Insert an IP packet into the stacks received packet queue |
||
593 | call stack_insert_packet |
||
594 | ret |
||
595 | |||
596 | not6: |
||
597 | cmp eax, 7 |
||
598 | jnz not7 |
||
599 | |||
600 | ; Test for any packets queued for transmission over the network |
||
601 | |||
602 | not7: |
||
603 | cmp eax, 8 |
||
604 | jnz not8 |
||
605 | |||
606 | call stack_get_packet |
||
607 | ; Extract a packet queued for transmission by the network |
||
608 | ret |
||
609 | |||
610 | not8: |
||
611 | cmp eax, 9 |
||
612 | jnz not9 |
||
613 | |||
614 | ; read the gateway IP address |
||
615 | |||
616 | mov eax, [gateway_ip] |
||
617 | ret |
||
618 | |||
619 | not9: |
||
620 | cmp eax, 10 |
||
621 | jnz not10 |
||
622 | |||
623 | ; read the subnet mask |
||
624 | |||
625 | mov eax, [subnet_mask] |
||
626 | ret |
||
627 | |||
628 | not10: |
||
629 | cmp eax, 11 |
||
630 | jnz not11 |
||
631 | |||
632 | ; write the gateway IP Address |
||
633 | mov [gateway_ip], ebx |
||
634 | |||
635 | ret |
||
636 | |||
637 | not11: |
||
638 | cmp eax, 12 |
||
639 | jnz not12 |
||
640 | |||
641 | ; write the subnet mask |
||
642 | mov [subnet_mask], ebx |
||
643 | |||
644 | |||
645 | not12: |
||
646 | cmp eax, 13 |
||
647 | jnz not13 |
||
648 | |||
649 | ; read the dns |
||
650 | |||
651 | mov eax, [dns_ip] |
||
652 | ret |
||
653 | |||
654 | not13: |
||
655 | cmp eax, 14 |
||
656 | jnz stack_driver_end |
||
657 | |||
658 | ; write the dns IP Address |
||
659 | mov [dns_ip], ebx |
||
660 | |||
661 | ret |
||
662 | |||
663 | stack_driver_end: |
||
664 | ret |
||
665 | |||
666 | |||
667 | |||
668 | ;*************************************************************************** |
||
669 | ; Function |
||
670 | ; app_socket_handler |
||
671 | ; |
||
672 | ; Description |
||
673 | ; This is an application service, called by int 0x40 |
||
674 | ; It provides application access to stack socket services |
||
675 | ; such as opening sockets |
||
676 | ; |
||
677 | ;*************************************************************************** |
||
678 | app_socket_handler: |
||
679 | cmp eax, 0 |
||
680 | jnz nots0 |
||
681 | |||
682 | call socket_open |
||
683 | ret |
||
684 | |||
685 | nots0: |
||
686 | cmp eax, 1 |
||
687 | jnz nots1 |
||
688 | |||
689 | call socket_close |
||
690 | ret |
||
691 | |||
692 | nots1: |
||
693 | cmp eax, 2 |
||
694 | jnz nots2 |
||
695 | |||
696 | call socket_poll |
||
697 | ret |
||
698 | |||
699 | nots2: |
||
700 | cmp eax, 3 |
||
701 | jnz nots3 |
||
702 | |||
703 | call socket_read |
||
704 | ret |
||
705 | |||
706 | nots3: |
||
707 | cmp eax, 4 |
||
708 | jnz nots4 |
||
709 | |||
710 | call socket_write |
||
711 | ret |
||
712 | |||
713 | nots4: |
||
714 | cmp eax, 5 |
||
715 | jnz nots5 |
||
716 | |||
717 | call socket_open_tcp |
||
718 | ret |
||
719 | |||
720 | nots5: |
||
721 | cmp eax, 6 |
||
722 | jnz nots6 |
||
723 | |||
724 | call socket_status |
||
725 | ret |
||
726 | |||
727 | nots6: |
||
728 | cmp eax, 7 |
||
729 | jnz nots7 |
||
730 | |||
731 | call socket_write_tcp |
||
732 | ret |
||
733 | |||
734 | nots7: |
||
735 | cmp eax, 8 |
||
736 | jnz nots8 |
||
737 | |||
738 | call socket_close_tcp |
||
739 | ret |
||
740 | |||
741 | nots8: |
||
742 | cmp eax, 9 |
||
743 | jnz nots9 |
||
744 | |||
745 | call is_localport_unused |
||
746 | ret |
||
747 | |||
748 | nots9: |
||
749 | cmp eax, 254 |
||
750 | jnz notdump |
||
751 | |||
752 | ret |
||
753 | |||
754 | notdump: |
||
755 | cmp eax, 255 |
||
756 | jnz notsdebug |
||
757 | |||
758 | ; This sub function allows access to debugging information on the stack |
||
759 | ; ebx holds the request: |
||
760 | ; 100 : return length of empty queue |
||
761 | ; 101 : return length of IPOUT QUEUE |
||
762 | ; 102 : return length of IPIN QUEUE |
||
763 | ; 103 : return length of NET1OUT QUEUE |
||
764 | ; 200 : return # of ARP entries |
||
765 | ; 201 : return size of ARP table ( max # entries ) |
||
766 | ; 202 : select ARP table entry # |
||
767 | ; 203 : return IP of selected table entry |
||
768 | ; 204 : return High 4 bytes of MAC address of selected table entry |
||
769 | ; 205 : return low 2 bytes of MAC address of selected table entry |
||
770 | ; 206 : return status word of selected table entry |
||
771 | ; 207 : return Time to live of selected table entry |
||
772 | |||
773 | |||
774 | ; 2 : return number of IP packets received |
||
775 | ; 3 : return number of packets transmitted |
||
776 | ; 4 : return number of received packets dumped |
||
777 | ; 5 : return number of arp packets received |
||
778 | ; 6 : return status of packet driver |
||
779 | ; ( 0 == not active, FFFFFFFF = successful ) |
||
780 | |||
781 | call stack_internal_status |
||
782 | ret |
||
783 | |||
784 | notsdebug: |
||
785 | ; Invalid Option |
||
786 | ret |
||
787 | |||
788 | |||
789 | uglobal |
||
790 | ARPTmp: |
||
791 | times 14 db 0 |
||
792 | endg |
||
793 | |||
794 | ;*************************************************************************** |
||
795 | ; Function |
||
796 | ; stack_internal_status |
||
797 | ; |
||
798 | ; Description |
||
799 | ; Returns information about the internal status of the stack |
||
800 | ; This is only useful for debugging |
||
801 | ; It works with the ethernet driver |
||
802 | ; sub function in ebx |
||
803 | ; return requested data in eax |
||
804 | ; |
||
805 | ;*************************************************************************** |
||
806 | stack_internal_status: |
||
807 | cmp ebx, 100 |
||
808 | jnz notsis100 |
||
809 | |||
810 | ; 100 : return length of EMPTY QUEUE |
||
811 | mov ebx, EMPTY_QUEUE |
||
812 | call queueSize |
||
813 | ret |
||
814 | |||
815 | notsis100: |
||
816 | cmp ebx, 101 |
||
817 | jnz notsis101 |
||
818 | |||
819 | ; 101 : return length of IPOUT QUEUE |
||
820 | mov ebx, IPOUT_QUEUE |
||
821 | call queueSize |
||
822 | ret |
||
823 | |||
824 | notsis101: |
||
825 | cmp ebx, 102 |
||
826 | jnz notsis102 |
||
827 | |||
828 | ; 102 : return length of IPIN QUEUE |
||
829 | mov ebx, IPIN_QUEUE |
||
830 | call queueSize |
||
831 | ret |
||
832 | |||
833 | notsis102: |
||
834 | cmp ebx, 103 |
||
835 | jnz notsis103 |
||
836 | |||
837 | ; 103 : return length of NET1OUT QUEUE |
||
838 | mov ebx, NET1OUT_QUEUE |
||
839 | call queueSize |
||
840 | ret |
||
841 | |||
842 | notsis103: |
||
843 | cmp ebx, 200 |
||
844 | jnz notsis200 |
||
845 | |||
846 | ; 200 : return num entries in arp table |
||
847 | movzx eax, byte [NumARP] |
||
848 | ret |
||
849 | |||
850 | notsis200: |
||
851 | cmp ebx, 201 |
||
852 | jnz notsis201 |
||
853 | |||
854 | ; 201 : return arp table size |
||
855 | mov eax, 20 ; ARP_TABLE_SIZE |
||
856 | ret |
||
857 | |||
858 | notsis201: |
||
859 | cmp ebx, 202 |
||
860 | jnz notsis202 |
||
861 | |||
862 | ; 202 - read the requested table entry |
||
863 | ; into a temporary buffer |
||
864 | ; ecx holds the entry number |
||
865 | |||
866 | mov eax, ecx |
||
867 | mov ecx, 14 ; ARP_ENTRY_SIZE |
||
868 | mul ecx |
||
869 | |||
870 | mov ecx, [eax + ARPTable] |
||
871 | mov [ARPTmp], ecx |
||
872 | mov ecx, [eax + ARPTable+4] |
||
873 | mov [ARPTmp+4], ecx |
||
874 | mov ecx, [eax + ARPTable+8] |
||
875 | mov [ARPTmp+8], ecx |
||
876 | mov cx, [eax + ARPTable+12] |
||
877 | mov [ARPTmp+12], cx |
||
878 | ret |
||
879 | |||
880 | notsis202: |
||
881 | cmp ebx, 203 |
||
882 | jnz notsis203 |
||
883 | |||
884 | ; 203 - return IP address |
||
885 | mov eax, [ARPTmp] |
||
886 | ret |
||
887 | |||
888 | notsis203: |
||
889 | cmp ebx, 204 |
||
890 | jnz notsis204 |
||
891 | |||
892 | ; 204 - return MAC high dword |
||
893 | mov eax, [ARPTmp+4] |
||
894 | ret |
||
895 | |||
896 | notsis204: |
||
897 | cmp ebx, 205 |
||
898 | jnz notsis205 |
||
899 | |||
900 | ; 205 - return MAC ls word |
||
901 | movzx eax, word [ARPTmp+8] |
||
902 | ret |
||
903 | |||
904 | notsis205: |
||
905 | cmp ebx, 206 |
||
906 | jnz notsis206 |
||
907 | |||
908 | ; 206 - return status word |
||
909 | movzx eax, word [ARPTmp+10] |
||
910 | ret |
||
911 | |||
912 | notsis206: |
||
913 | cmp ebx, 207 |
||
914 | jnz notsis207 |
||
915 | |||
916 | ; 207 - return ttl word |
||
917 | movzx eax, word [ARPTmp+12] |
||
918 | ret |
||
919 | |||
920 | notsis207: |
||
921 | cmp ebx, 2 |
||
922 | jnz notsis2 |
||
923 | |||
924 | ; 2 : return number of IP packets received |
||
925 | mov eax, [ip_rx_count] |
||
926 | ret |
||
927 | |||
928 | notsis2: |
||
929 | cmp ebx, 3 |
||
930 | jnz notsis3 |
||
931 | |||
932 | ; 3 : return number of packets transmitted |
||
933 | mov eax, [ip_tx_count] |
||
934 | ret |
||
935 | |||
936 | notsis3: |
||
937 | cmp ebx, 4 |
||
938 | jnz notsis4 |
||
939 | |||
940 | ; 4 : return number of received packets dumped |
||
941 | mov eax, [dumped_rx_count] |
||
942 | ret |
||
943 | |||
944 | notsis4: |
||
945 | cmp ebx, 5 |
||
946 | jnz notsis5 |
||
947 | |||
948 | ; 5 : return number of arp packets received |
||
949 | mov eax, [arp_rx_count] |
||
950 | ret |
||
951 | |||
952 | notsis5: |
||
953 | cmp ebx, 6 |
||
954 | jnz notsis6 |
||
955 | |||
956 | ; 6 : return status of packet driver |
||
957 | ; ( 0 == not active, FFFFFFFF = successful ) |
||
958 | mov eax, [eth_status] |
||
959 | ret |
||
960 | |||
961 | notsis6: |
||
962 | xor eax, eax |
||
963 | ret |
||
964 | |||
965 | |||
966 | |||
967 | ;*************************************************************************** |
||
968 | ; Function |
||
969 | ; stack_get_packet |
||
970 | ; |
||
971 | ; Description |
||
972 | ; extracts an IP packet from the NET1 output queue |
||
973 | ; and sends the data to the calling process |
||
974 | ; pointer to data in edx |
||
975 | ; returns number of bytes read in eax |
||
976 | ; |
||
977 | ;*************************************************************************** |
||
978 | stack_get_packet: |
||
979 | ; Look for a buffer to tx |
||
980 | mov eax, NET1OUT_QUEUE |
||
981 | call dequeue |
||
982 | cmp ax, NO_BUFFER |
||
983 | je sgp_non_exit ; Exit if no buffer available |
||
984 | |||
985 | push eax ; Save buffer number for freeing at end |
||
986 | |||
987 | push edx |
||
988 | ; convert buffer pointer eax to the absolute address |
||
989 | mov ecx, IPBUFFSIZE |
||
990 | mul ecx |
||
991 | add eax, IPbuffs |
||
992 | pop edx |
||
993 | |||
994 | push eax ; save address of IP data |
||
995 | |||
996 | ; Get the address of the callers data |
||
997 | mov edi,[0x3010] |
||
115 | poddubny | 998 | add edi,TASKDATA.mem_start |
1 | ha | 999 | add edx,[edi] |
1000 | mov edi, edx |
||
1001 | |||
1002 | pop eax |
||
1003 | |||
1004 | mov ecx, 1500 ; should get the actual number of bytes to write |
||
1005 | mov esi, eax |
||
1006 | cld |
||
1007 | rep movsb ; copy the data across |
||
1008 | |||
1009 | ; And finally, return the buffer to the free queue |
||
1010 | pop eax |
||
1011 | call freeBuff |
||
1012 | |||
1013 | mov eax, 1500 |
||
1014 | ret |
||
1015 | |||
1016 | sgp_non_exit: |
||
1017 | xor eax, eax |
||
1018 | ret |
||
1019 | |||
1020 | |||
1021 | |||
1022 | ;*************************************************************************** |
||
1023 | ; Function |
||
1024 | ; stack_insert_packet |
||
1025 | ; |
||
1026 | ; Description |
||
1027 | ; writes an IP packet into the stacks receive queue |
||
1028 | ; # of bytes to write in ecx |
||
1029 | ; pointer to data in edx |
||
1030 | ; returns 0 in eax ok, -1 == failed |
||
1031 | ; |
||
1032 | ;*************************************************************************** |
||
1033 | stack_insert_packet: |
||
1034 | |||
1035 | mov eax, EMPTY_QUEUE |
||
1036 | call dequeue |
||
1037 | cmp ax, NO_BUFFER |
||
1038 | je sip_err_exit |
||
1039 | |||
1040 | push eax |
||
1041 | |||
1042 | ; save the pointers to the data buffer & size |
||
1043 | push edx |
||
1044 | push ecx |
||
1045 | |||
1046 | ; convert buffer pointer eax to the absolute address |
||
1047 | mov ecx, IPBUFFSIZE |
||
1048 | mul ecx |
||
1049 | add eax, IPbuffs |
||
1050 | |||
1051 | mov edx, eax |
||
1052 | |||
1053 | ; So, edx holds the IPbuffer ptr |
||
1054 | |||
1055 | pop ecx ; count of bytes to send |
||
1056 | mov ebx, ecx ; need the length later |
||
1057 | pop eax ; get callers ptr to data to send |
||
1058 | |||
1059 | ; Get the address of the callers data |
||
1060 | mov edi,[0x3010] |
||
115 | poddubny | 1061 | add edi,TASKDATA.mem_start |
1 | ha | 1062 | add eax,[edi] |
1063 | mov esi, eax |
||
1064 | |||
1065 | mov edi, edx |
||
1066 | cld |
||
1067 | rep movsb ; copy the data across |
||
1068 | |||
1069 | pop ebx |
||
1070 | |||
1071 | mov eax, IPIN_QUEUE |
||
1072 | call queue |
||
1073 | |||
1074 | inc dword [ip_rx_count] |
||
1075 | |||
1076 | mov eax, 0 |
||
1077 | ret |
||
1078 | |||
1079 | sip_err_exit: |
||
1080 | mov eax, 0xFFFFFFFF |
||
1081 | ret |
||
1082 | |||
1083 | |||
1084 | |||
1085 | ;*************************************************************************** |
||
1086 | ; Function |
||
1087 | ; socket_open |
||
1088 | ; |
||
1089 | ; Description |
||
1090 | ; find a free socket |
||
1091 | ; local port in ebx |
||
1092 | ; remote port in ecx |
||
1093 | ; remote ip in edx |
||
1094 | ; return socket # in eax, -1 if none available |
||
1095 | ; |
||
1096 | ;*************************************************************************** |
||
1097 | socket_open: |
||
1098 | call get_free_socket |
||
1099 | |||
1100 | cmp eax, 0xFFFFFFFF |
||
1101 | jz so_exit |
||
1102 | |||
1103 | ; ax holds the socket number that is free. Get real address |
||
1104 | push eax |
||
1105 | shl eax, 12 |
||
1106 | add eax, sockets |
||
1107 | |||
1108 | mov [eax], dword SOCK_OPEN |
||
1109 | |||
1110 | mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
||
1111 | mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
||
1112 | mov ebx, [stack_ip] |
||
1113 | mov [eax + 8], ebx ; Local IP |
||
1114 | mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
||
1115 | mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
||
1116 | mov [eax + 16], edx ; Remote IP ( in Internet order ) |
||
1117 | mov [eax + 24], dword 0 ; recieved data count |
||
1118 | |||
1119 | mov esi, [0x3010] |
||
115 | poddubny | 1120 | mov ebx, [esi+TASKDATA.pid] |
1 | ha | 1121 | mov [eax + 4], ebx ; save the process ID |
1122 | pop eax ; Get the socket number back, so we can return it |
||
1123 | |||
1124 | so_exit: |
||
1125 | ret |
||
1126 | |||
1127 | |||
1128 | |||
1129 | ;*************************************************************************** |
||
1130 | ; Function |
||
1131 | ; socket_open_tcp |
||
1132 | ; |
||
1133 | ; Description |
||
1134 | ; Opens a TCP socket in PASSIVE or ACTIVE mode |
||
1135 | ; find a free socket |
||
1136 | ; local port in ebx ( intel format ) |
||
1137 | ; remote port in ecx ( intel format ) |
||
1138 | ; remote ip in edx ( in Internet byte order ) |
||
1139 | ; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE ) |
||
1140 | ; return socket # in eax, -1 if none available |
||
1141 | ; |
||
1142 | ;*************************************************************************** |
||
1143 | socket_open_tcp: |
||
1144 | call get_free_socket |
||
1145 | |||
1146 | cmp eax, 0xFFFFFFFF |
||
1147 | jz so_exit |
||
1148 | |||
1149 | ; ax holds the socket number that is free. Get real address |
||
1150 | push eax |
||
1151 | shl eax, 12 |
||
1152 | add eax, sockets |
||
1153 | |||
1154 | mov [sktAddr], eax |
||
1155 | mov [eax], dword SOCK_OPEN |
||
1156 | |||
1157 | ; TODO - check this works! |
||
1158 | mov [eax + 72], dword 0 ; Reset the window timer. |
||
1159 | |||
1160 | mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
||
1161 | mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
||
1162 | mov ebx, [stack_ip] |
||
1163 | mov [eax + 8], ebx ; Local IP |
||
1164 | mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
||
1165 | mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
||
1166 | mov [eax + 16], edx ; Remote IP ( in Internet order ) |
||
1167 | mov [eax + 24], dword 0 ; recieved data count |
||
1168 | |||
1169 | ; Now fill in TCB state |
||
1170 | mov ebx, TCB_LISTEN |
||
1171 | cmp esi, SOCKET_PASSIVE |
||
1172 | jz sot_001 |
||
1173 | mov ebx, TCB_SYN_SENT |
||
1174 | |||
1175 | sot_001: |
||
1176 | mov [eax + 28], ebx ; Indicate the state of the TCB |
||
1177 | |||
1178 | mov esi, [0x3010] |
||
115 | poddubny | 1179 | mov ecx, [esi+TASKDATA.pid] |
1 | ha | 1180 | mov [eax + 4], ecx ; save the process ID |
1181 | |||
1182 | cmp ebx, TCB_LISTEN |
||
1183 | je sot_done |
||
1184 | |||
1185 | ; Now, if we are in active mode, then we have to send a SYN to the specified remote port |
||
1186 | |||
1187 | |||
1188 | mov eax, EMPTY_QUEUE |
||
1189 | call dequeue |
||
1190 | cmp ax, NO_BUFFER |
||
1191 | je sot_done |
||
1192 | |||
1193 | push eax |
||
1194 | |||
1195 | mov bl, 0x02 ; SYN |
||
1196 | mov ecx, 0 |
||
1197 | |||
1198 | call buildTCPPacket |
||
1199 | |||
1200 | mov eax, NET1OUT_QUEUE |
||
1201 | |||
1202 | mov edx, [stack_ip] |
||
1203 | mov ecx, [ sktAddr ] |
||
1204 | mov ecx, [ ecx + 16 ] |
||
1205 | cmp edx, ecx |
||
1206 | jne sot_notlocal |
||
1207 | mov eax, IPIN_QUEUE |
||
1208 | |||
1209 | sot_notlocal: |
||
1210 | ; Send it. |
||
1211 | pop ebx |
||
1212 | call queue |
||
1213 | |||
1214 | mov esi, [sktAddr] |
||
1215 | |||
1216 | ; increment SND.NXT in socket |
||
1217 | add esi, 48 |
||
1218 | call inc_inet_esi |
||
1219 | |||
1220 | sot_done: |
||
1221 | pop eax ; Get the socket number back, so we can return it |
||
1222 | |||
1223 | sot_exit: |
||
1224 | ret |
||
1225 | |||
1226 | |||
1227 | |||
1228 | ;*************************************************************************** |
||
1229 | ; Function |
||
1230 | ; socket_close |
||
1231 | ; |
||
1232 | ; Description |
||
1233 | ; socket # in ebx |
||
1234 | ; returns 0 for ok, -1 for socket not open (fail) |
||
1235 | ; |
||
1236 | ;*************************************************************************** |
||
1237 | socket_close: |
||
1238 | shl ebx, 12 |
||
1239 | add ebx, sockets |
||
1240 | mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
||
1241 | cmp [ebx], dword SOCK_EMPTY |
||
1242 | jz sc_exit |
||
1243 | |||
1244 | ; Clear the socket varaibles |
||
1245 | xor eax, eax |
||
1246 | mov edi,ebx |
||
1247 | mov ecx,SOCKETHEADERSIZE |
||
1248 | cld |
||
1249 | rep stosb |
||
1250 | |||
1251 | sc_exit: |
||
1252 | ret |
||
1253 | |||
1254 | |||
1255 | |||
1256 | ;*************************************************************************** |
||
1257 | ; Function |
||
1258 | ; socket_close_tcp |
||
1259 | ; |
||
1260 | ; Description |
||
1261 | ; socket # in ebx |
||
1262 | ; returns 0 for ok, -1 for socket not open (fail) |
||
1263 | ; |
||
1264 | ;*************************************************************************** |
||
1265 | socket_close_tcp: |
||
1266 | ; first, remove any resend entries |
||
1267 | pusha |
||
1268 | |||
1269 | mov esi, resendQ |
||
1270 | mov ecx, 0 |
||
1271 | |||
1272 | sct001: |
||
1273 | cmp ecx, NUMRESENDENTRIES |
||
1274 | je sct003 ; None left |
||
1275 | cmp [esi], bl |
||
1276 | je sct002 ; found one |
||
1277 | inc ecx |
||
1278 | add esi, 4 |
||
1279 | jmp sct001 |
||
1280 | |||
1281 | sct002: |
||
1282 | dec dword [arp_rx_count] ; ************ TEST ONLY! |
||
1283 | |||
1284 | mov [esi], byte 0xFF |
||
1285 | jmp sct001 |
||
1286 | |||
1287 | sct003: |
||
1288 | popa |
||
1289 | |||
1290 | shl ebx, 12 |
||
1291 | add ebx, sockets |
||
1292 | mov [sktAddr], ebx |
||
1293 | mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
||
1294 | cmp [ebx], dword SOCK_EMPTY |
||
1295 | jz sct_exit |
||
1296 | |||
1297 | ; Now construct the response, and queue for sending by IP |
||
1298 | mov eax, EMPTY_QUEUE |
||
1299 | call dequeue |
||
1300 | cmp ax, NO_BUFFER |
||
1301 | je stl_exit |
||
1302 | |||
1303 | push eax |
||
1304 | |||
1305 | mov bl, 0x11 ; FIN + ACK |
||
1306 | mov ecx, 0 |
||
1307 | mov esi, 0 |
||
1308 | |||
1309 | call buildTCPPacket |
||
1310 | |||
1311 | mov ebx, [sktAddr] |
||
1312 | |||
1313 | ; increament SND.NXT in socket |
||
1314 | mov esi, 48 |
||
1315 | add esi, ebx |
||
1316 | call inc_inet_esi |
||
1317 | |||
1318 | |||
1319 | ; Get the socket state |
||
1320 | mov eax, [ebx + 28] |
||
1321 | cmp eax, TCB_LISTEN |
||
1322 | je destroyTCB |
||
1323 | cmp eax, TCB_SYN_SENT |
||
1324 | je destroyTCB |
||
1325 | cmp eax, TCB_SYN_RECEIVED |
||
1326 | je sct_finwait1 |
||
1327 | cmp eax, TCB_ESTABLISHED |
||
1328 | je sct_finwait1 |
||
1329 | |||
1330 | ; assume CLOSE WAIT |
||
1331 | ; Send a fin, then enter last-ack state |
||
1332 | mov eax, TCB_LAST_ACK |
||
1333 | mov [ebx + 28], eax |
||
1334 | xor eax, eax |
||
1335 | jmp sct_send |
||
1336 | |||
1337 | sct_finwait1: |
||
1338 | ; Send a fin, then enter finwait2 state |
||
1339 | mov eax, TCB_FIN_WAIT_1 |
||
1340 | mov [ebx + 28], eax |
||
1341 | xor eax, eax |
||
1342 | |||
1343 | sct_send: |
||
1344 | mov eax, NET1OUT_QUEUE |
||
1345 | |||
1346 | mov edx, [stack_ip] |
||
1347 | mov ecx, [ sktAddr ] |
||
1348 | mov ecx, [ ecx + 16 ] |
||
1349 | cmp edx, ecx |
||
1350 | jne sct_notlocal |
||
1351 | mov eax, IPIN_QUEUE |
||
1352 | |||
1353 | sct_notlocal: |
||
1354 | ; Send it. |
||
1355 | pop ebx |
||
1356 | call queue |
||
1357 | jmp sct_exit |
||
1358 | |||
1359 | destroyTCB: |
||
1360 | pop eax |
||
1361 | ; Clear the socket varaibles |
||
1362 | xor eax, eax |
||
1363 | mov edi,ebx |
||
1364 | mov ecx,SOCKETHEADERSIZE |
||
1365 | cld |
||
1366 | rep stosb |
||
1367 | |||
1368 | sct_exit: |
||
1369 | ret |
||
1370 | |||
1371 | |||
1372 | |||
1373 | ;*************************************************************************** |
||
1374 | ; Function |
||
1375 | ; socket_poll |
||
1376 | ; |
||
1377 | ; Description |
||
1378 | ; socket # in ebx |
||
1379 | ; returns count in eax. |
||
1380 | ; |
||
1381 | ;*************************************************************************** |
||
1382 | socket_poll: |
||
1383 | shl ebx, 12 |
||
1384 | add ebx, sockets |
||
1385 | mov eax, [ebx + 24] |
||
1386 | |||
1387 | ret |
||
1388 | |||
1389 | |||
1390 | |||
1391 | ;*************************************************************************** |
||
1392 | ; Function |
||
1393 | ; socket_status |
||
1394 | ; |
||
1395 | ; Description |
||
1396 | ; socket # in ebx |
||
1397 | ; returns TCB state in eax. |
||
1398 | ; |
||
1399 | ;*************************************************************************** |
||
1400 | socket_status: |
||
1401 | shl ebx, 12 |
||
1402 | add ebx, sockets |
||
1403 | mov eax, [ebx + 28] |
||
1404 | |||
1405 | ret |
||
1406 | |||
1407 | |||
1408 | |||
1409 | ;*************************************************************************** |
||
1410 | ; Function |
||
1411 | ; socket_read |
||
1412 | ; |
||
1413 | ; Description |
||
1414 | ; socket # in ebx |
||
1415 | ; returns # of bytes remaining in eax, data in bl |
||
1416 | ; |
||
1417 | ;*************************************************************************** |
||
1418 | socket_read: |
||
1419 | shl ebx, 12 |
||
1420 | add ebx, sockets |
||
1421 | mov eax, [ebx + 24] ; get count of bytes |
||
1422 | mov ecx,1 |
||
1423 | test eax, eax |
||
1424 | jz sr2 |
||
1425 | |||
1426 | dec eax |
||
1427 | mov esi, ebx ; esi is address of socket |
||
1428 | mov [ebx + 24], eax ; store new count |
||
1429 | movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte |
||
1430 | add esi, SOCKETHEADERSIZE |
||
1431 | mov edi, esi |
||
1432 | inc esi |
||
1433 | |||
1434 | mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4 |
||
1435 | cld |
||
1436 | rep movsd |
||
1437 | xor ecx, ecx |
||
1438 | |||
1439 | sr1: |
||
1440 | jmp sor_exit |
||
1441 | |||
1442 | sr2: |
||
1443 | xor bl, bl |
||
1444 | |||
1445 | sor_exit: |
||
1446 | ret |
||
1447 | |||
1448 | |||
1449 | |||
1450 | ;*************************************************************************** |
||
1451 | ; Function |
||
1452 | ; socket_write |
||
1453 | ; |
||
1454 | ; Description |
||
1455 | ; socket in ebx |
||
1456 | ; # of bytes to write in ecx |
||
1457 | ; pointer to data in edx |
||
1458 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
||
1459 | ; could not queue IP packet ) |
||
1460 | ; |
||
1461 | ;*************************************************************************** |
||
1462 | socket_write: |
||
1463 | ; First, find the address of the socket descriptor |
||
1464 | shl ebx, 12 |
||
1465 | add ebx, sockets ; ebx = address of actual socket |
||
1466 | |||
1467 | mov eax, 0xFFFFFFFF |
||
1468 | ; If the socket is invalid, return with an error code |
||
1469 | cmp [ebx], dword SOCK_EMPTY |
||
1470 | je sw_exit |
||
1471 | |||
1472 | |||
1473 | mov eax, EMPTY_QUEUE |
||
1474 | call dequeue |
||
1475 | cmp ax, NO_BUFFER |
||
1476 | je sw_exit |
||
1477 | |||
1478 | ; Save the queue entry number |
||
1479 | push eax |
||
1480 | |||
1481 | ; save the pointers to the data buffer & size |
||
1482 | push edx |
||
1483 | push ecx |
||
1484 | |||
1485 | ; convert buffer pointer eax to the absolute address |
||
1486 | mov ecx, IPBUFFSIZE |
||
1487 | mul ecx |
||
1488 | add eax, IPbuffs |
||
1489 | |||
1490 | mov edx, eax |
||
1491 | |||
1492 | ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr |
||
1493 | |||
1494 | ; Fill in the IP header ( some data is in the socket descriptor) |
||
1495 | mov eax, [ebx + 8] |
||
1496 | mov [edx + 12], eax ; source IP |
||
1497 | mov eax, [ebx + 16] |
||
1498 | mov [edx + 16], eax ; Destination IP |
||
1499 | |||
1500 | mov al, 0x45 |
||
1501 | mov [edx], al ; Version, IHL |
||
1502 | xor al, al |
||
1503 | mov [edx + 1], al ; Type of service |
||
1504 | |||
1505 | pop eax ; Get the UDP data length |
||
1506 | push eax |
||
1507 | |||
1508 | add eax, 20 + 8 ; add IP header and UDP header lengths |
||
1509 | mov [edx + 2], ah |
||
1510 | mov [edx + 3], al |
||
1511 | xor al, al |
||
1512 | mov [edx + 4], al |
||
1513 | mov [edx + 5], al |
||
1514 | mov al, 0x40 |
||
1515 | mov [edx + 6], al |
||
1516 | xor al, al |
||
1517 | mov [edx + 7], al |
||
1518 | mov al, 0x20 |
||
1519 | mov [edx + 8], al |
||
1520 | mov al, 17 |
||
1521 | mov [edx + 9], al |
||
1522 | |||
1523 | ; Checksum left unfilled |
||
1524 | xor ax, ax |
||
1525 | mov [edx + 10], ax |
||
1526 | |||
1527 | ; Fill in the UDP header ( some data is in the socket descriptor) |
||
1528 | mov ax, [ebx + 12] |
||
1529 | mov [edx + 20], ax |
||
1530 | |||
1531 | mov ax, [ebx + 20] |
||
1532 | mov [edx + 20 + 2], ax |
||
1533 | |||
1534 | pop eax |
||
1535 | push eax |
||
1536 | |||
1537 | add eax, 8 |
||
1538 | mov [edx + 20 + 4], ah |
||
1539 | mov [edx + 20 + 5], al |
||
1540 | |||
1541 | ; Checksum left unfilled |
||
1542 | xor ax, ax |
||
1543 | mov [edx + 20 + 6], ax |
||
1544 | |||
1545 | pop ecx ; count of bytes to send |
||
1546 | mov ebx, ecx ; need the length later |
||
1547 | pop eax ; get callers ptr to data to send |
||
1548 | |||
1549 | ; Get the address of the callers data |
||
1550 | mov edi,[0x3010] |
||
115 | poddubny | 1551 | add edi,TASKDATA.mem_start |
1 | ha | 1552 | add eax,[edi] |
1553 | mov esi, eax |
||
1554 | |||
1555 | mov edi, edx |
||
1556 | add edi, 28 |
||
1557 | cld |
||
1558 | rep movsb ; copy the data across |
||
1559 | |||
1560 | ; we have edx as IPbuffer ptr. |
||
1561 | ; Fill in the UDP checksum |
||
1562 | ; First, fill in pseudoheader |
||
1563 | mov eax, [edx + 12] |
||
1564 | mov [pseudoHeader], eax |
||
1565 | mov eax, [edx + 16] |
||
1566 | mov [pseudoHeader+4], eax |
||
1567 | mov ax, 0x1100 ; 0 + protocol |
||
1568 | mov [pseudoHeader+8], ax |
||
1569 | add ebx, 8 |
||
1570 | mov eax, ebx |
||
1571 | mov [pseudoHeader+10], ah |
||
1572 | mov [pseudoHeader+11], al |
||
1573 | |||
1574 | mov eax, pseudoHeader |
||
1575 | mov [checkAdd1], eax |
||
1576 | mov [checkSize1], word 12 |
||
1577 | mov eax, edx |
||
1578 | add eax, 20 |
||
1579 | mov [checkAdd2], eax |
||
1580 | mov eax, ebx |
||
1581 | mov [checkSize2], ax ; was eax!! mjh 8/7/02 |
||
1582 | |||
1583 | call checksum |
||
1584 | |||
1585 | ; store it in the UDP checksum ( in the correct order! ) |
||
1586 | mov ax, [checkResult] |
||
1587 | |||
1588 | ; If the UDP checksum computes to 0, we must make it 0xffff |
||
1589 | ; (0 is reserved for 'not used') |
||
1590 | cmp ax, 0 |
||
1591 | jne sw_001 |
||
1592 | mov ax, 0xffff |
||
1593 | |||
1594 | sw_001: |
||
1595 | mov [edx + 20 + 6], ah |
||
1596 | mov [edx + 20 + 7], al |
||
1597 | |||
1598 | ; Fill in the IP header checksum |
||
1599 | mov eax, edx |
||
1600 | mov [checkAdd1], eax |
||
1601 | mov [checkSize1], word 20 |
||
1602 | mov [checkAdd2], dword 0 |
||
1603 | mov [checkSize2], word 0 |
||
1604 | |||
1605 | call checksum |
||
1606 | |||
1607 | mov ax, [checkResult] |
||
1608 | mov [edx + 10], ah |
||
1609 | mov [edx + 11], al |
||
1610 | |||
1611 | ; Check destination IP address. |
||
1612 | ; If it is the local host IP, route it back to IP_RX |
||
1613 | |||
1614 | pop ebx |
||
1615 | mov eax, NET1OUT_QUEUE |
||
1616 | |||
1617 | mov ecx, [ edx + 16] |
||
1618 | mov edx, [stack_ip] |
||
1619 | cmp edx, ecx |
||
1620 | jne sw_notlocal |
||
1621 | mov eax, IPIN_QUEUE |
||
1622 | |||
1623 | sw_notlocal: |
||
1624 | ; Send it. |
||
1625 | call queue |
||
1626 | |||
1627 | xor eax, eax |
||
1628 | |||
1629 | sw_exit: |
||
1630 | ret |
||
1631 | |||
1632 | |||
1633 | |||
1634 | ;*************************************************************************** |
||
1635 | ; Function |
||
1636 | ; socket_write_tcp |
||
1637 | ; |
||
1638 | ; Description |
||
1639 | ; socket in ebx |
||
1640 | ; # of bytes to write in ecx |
||
1641 | ; pointer to data in edx |
||
1642 | ; returns 0 in eax ok, -1 == failed ( invalid socket, or |
||
1643 | ; could not queue IP packet ) |
||
1644 | ; |
||
1645 | ;*************************************************************************** |
||
1646 | socket_write_tcp: |
||
1647 | ; First, find the address of the socket descriptor |
||
1648 | shl ebx, 12 |
||
1649 | add ebx, sockets ; ebx = address of actual socket |
||
1650 | |||
1651 | mov [sktAddr], ebx |
||
1652 | |||
1653 | mov eax, 0xFFFFFFFF |
||
1654 | ; If the socket is invalid, return with an error code |
||
1655 | cmp [ebx], dword SOCK_EMPTY |
||
1656 | je swt_exit |
||
1657 | |||
1658 | ; If the sockets window timer is nonzero, do not queue packet |
||
1659 | ; TODO - done |
||
1660 | cmp [ebx + 72], dword 0 |
||
1661 | jne swt_exit |
||
1662 | |||
1663 | mov eax, EMPTY_QUEUE |
||
1664 | call dequeue |
||
1665 | cmp ax, NO_BUFFER |
||
1666 | je swt_exit |
||
1667 | |||
1668 | push eax |
||
1669 | |||
1670 | mov bl, 0x10 ; ACK |
||
1671 | |||
1672 | ; Get the address of the callers data |
||
1673 | mov edi,[0x3010] |
||
115 | poddubny | 1674 | add edi,TASKDATA.mem_start |
1 | ha | 1675 | add edx,[edi] |
1676 | mov esi, edx |
||
1677 | |||
1678 | pop eax |
||
1679 | push eax |
||
1680 | |||
1681 | push ecx |
||
1682 | call buildTCPPacket |
||
1683 | pop ecx |
||
1684 | |||
1685 | ; Check destination IP address. |
||
1686 | ; If it is the local host IP, route it back to IP_RX |
||
1687 | |||
1688 | pop ebx |
||
1689 | push ecx |
||
1690 | mov eax, NET1OUT_QUEUE |
||
1691 | |||
1692 | mov edx, [stack_ip] |
||
1693 | mov ecx, [ sktAddr ] |
||
1694 | mov ecx, [ ecx + 16 ] |
||
1695 | cmp edx, ecx |
||
1696 | jne swt_notlocal |
||
1697 | mov eax, IPIN_QUEUE |
||
1698 | |||
1699 | swt_notlocal: |
||
1700 | pop ecx |
||
1701 | |||
1702 | push ebx ; save ipbuffer number |
||
1703 | |||
1704 | call queue |
||
1705 | |||
1706 | mov esi, [sktAddr] |
||
1707 | |||
1708 | ; increament SND.NXT in socket |
||
1709 | ; Amount to increment by is in ecx |
||
1710 | add esi, 48 |
||
1711 | call add_inet_esi |
||
1712 | |||
1713 | pop ebx |
||
1714 | |||
1715 | ; Copy the IP buffer to a resend queue |
||
1716 | ; If there isn't one, dont worry about it for now |
||
1717 | mov esi, resendQ |
||
1718 | mov ecx, 0 |
||
1719 | |||
1720 | swt003: |
||
1721 | cmp ecx, NUMRESENDENTRIES |
||
1722 | je swt001 ; None found |
||
1723 | cmp [esi], byte 0xFF |
||
1724 | je swt002 ; found one |
||
1725 | inc ecx |
||
1726 | add esi, 4 |
||
1727 | jmp swt003 |
||
1728 | |||
1729 | swt002: |
||
1730 | push ebx |
||
1731 | |||
1732 | ; OK, we have a buffer descriptor ptr in esi. |
||
1733 | ; resend entry # in ecx |
||
1734 | ; Populate it |
||
1735 | ; socket # |
||
1736 | ; retries count |
||
1737 | ; retry time |
||
1738 | ; fill IP buffer associated with this descriptor |
||
1739 | |||
1740 | mov eax, [sktAddr] |
||
1741 | sub eax, sockets |
||
1742 | shr eax, 12 ; get skt # |
||
1743 | mov [esi], al |
||
1744 | mov [esi + 1], byte TCP_RETRIES |
||
1745 | mov [esi + 2], word TCP_TIMEOUT |
||
1746 | |||
1747 | inc ecx |
||
1748 | ; Now get buffer location, and copy buffer across. argh! more copying,, |
||
1749 | mov edi, resendBuffer - IPBUFFSIZE |
||
1750 | swt002a: |
||
1751 | add edi, IPBUFFSIZE |
||
1752 | loop swt002a |
||
1753 | |||
1754 | ; we have dest buffer location in edi |
||
1755 | pop eax |
||
1756 | ; convert source buffer pointer eax to the absolute address |
||
1757 | mov ecx, IPBUFFSIZE |
||
1758 | mul ecx |
||
1759 | add eax, IPbuffs |
||
1760 | mov esi, eax |
||
1761 | |||
1762 | ; do copy |
||
1763 | mov ecx, IPBUFFSIZE |
||
1764 | cld |
||
1765 | rep movsb |
||
1766 | |||
1767 | inc dword [arp_rx_count] ; ************ TEST ONLY! |
||
1768 | |||
1769 | swt001: |
||
1770 | xor eax, eax |
||
1771 | |||
1772 | swt_exit: |
||
1773 | ret |
||
1774 | |||
1775 | |||
1776 | |||
1777 | ; Below, the main network layer source code is included |
||
1778 | ; |
||
1779 | |||
1780 | include "queue.inc" |
||
1781 | include "ip.inc" |
||
1782 | include "tcp.inc" |
||
1783 | include "udp.inc" |
||
1784 | include "eth_drv/ethernet.inc" |