Rev 1257 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1257 | Rev 1274 | ||
---|---|---|---|
Line 13... | Line 13... | ||
13 | ;; Version 2, June 1991 ;; |
13 | ;; Version 2, June 1991 ;; |
14 | ;; ;; |
14 | ;; ;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
15 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 16... | Line 16... | ||
16 | 16 | ||
Line 17... | Line 17... | ||
17 | 17 | ||
18 | $Revision: 1257 $ |
18 | $Revision: 1274 $ |
19 | 19 | ||
20 | TCP_RETRIES equ 5 ; Number of times to resend a Packet |
20 | TCP_RETRIES equ 5 ; Number of times to resend a Packet |
Line 31... | Line 31... | ||
31 | .DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7] |
31 | .DataOffset db ? ; DataOffset[0-3 bits] and Reserved[4-7] |
32 | .Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN |
32 | .Flags db ? ; Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN |
33 | .Window dw ? |
33 | .Window dw ? |
34 | .Checksum dw ? |
34 | .Checksum dw ? |
35 | .UrgentPointer dw ? |
35 | .UrgentPointer dw ? |
36 | .Options rb 3 |
36 | ; .Options rb 3 |
37 | .Padding db ? |
37 | ; .Padding db ? |
38 | .Data: |
38 | .Data: |
39 | ends |
39 | ends |
Line -... | Line 40... | ||
- | 40 | ||
- | 41 | struct tcp_in_queue_entry |
|
- | 42 | .data_ptr dd ? |
|
- | 43 | .data_size dd ? |
|
- | 44 | .offset dd ? |
|
- | 45 | .size: |
|
- | 46 | ends |
|
- | 47 | ||
- | 48 | struct tcp_out_queue_entry |
|
- | 49 | .data_ptr dd ? |
|
- | 50 | .data_size dd ? |
|
- | 51 | .ttl dd ? |
|
- | 52 | .retries dd ? |
|
- | 53 | .owner dd ? |
|
- | 54 | .sendproc dd ? |
|
- | 55 | .seq_num dd ? |
|
- | 56 | .socket dd ? |
|
- | 57 | .size: |
|
- | 58 | ends |
|
40 | 59 | ||
41 | align 4 |
60 | align 4 |
42 | uglobal |
61 | uglobal |
43 | TCP_PACKETS_TX rd MAX_IP |
62 | TCP_PACKETS_TX rd MAX_IP |
Line 146... | Line 165... | ||
146 | stdcall net_socket_free, ebx |
165 | stdcall net_socket_free, ebx |
147 | pop ebx |
166 | pop ebx |
148 | jmp .next_socket |
167 | jmp .next_socket |
Line 149... | Line 168... | ||
149 | 168 | ||
150 | .decrement_wnd: |
- | |
151 | ; TODO - prove it works! |
169 | .decrement_wnd: |
152 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer] |
170 | dec [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer] |
Line 153... | Line 171... | ||
153 | jmp .next_socket |
171 | jmp .next_socket |
154 | 172 | ||
Line 224... | Line 242... | ||
224 | 242 | ||
225 | 243 | ||
226 | - | ||
227 | ;----------------------------------------------------------------- |
- | |
228 | ; |
- | |
229 | ; TCP_add_to_queue: |
- | |
230 | ; |
- | |
231 | ; Queue a TCP packet for sending |
- | |
232 | ; |
- | |
233 | ; IN: [esp] pointer to buffer |
- | |
234 | ; [esp + 4] size of buffer |
- | |
235 | ; ebx = driver struct |
- | |
236 | ; esi = sender proc |
- | |
237 | ; edx = acknum |
- | |
238 | ; OUT: / |
- | |
239 | ; |
- | |
240 | ;----------------------------------------------------------------- |
- | |
241 | align 4 |
- | |
242 | TCP_add_to_queue: |
- | |
243 | - | ||
244 | DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %x\n", [esp], [esp+4], ebx, edx |
- | |
245 | - | ||
246 | cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
- | |
247 | jge .full |
- | |
248 | - | ||
249 | mov ecx, TCP_QUEUE_SIZE |
- | |
250 | mov eax, TCP_OUT_QUEUE+4 |
- | |
251 | - | ||
252 | .loop: |
- | |
253 | cmp [eax + tcp_out_queue_entry.data_ptr], 0 |
- | |
254 | je .found_it |
- | |
255 | add eax, tcp_out_queue_entry.size |
- | |
256 | loop .loop |
- | |
257 | - | ||
258 | .full: ; silently discard the packet |
- | |
259 | - | ||
260 | DEBUGF 1,"TCP queue is full!\n" |
- | |
261 | - | ||
262 | call kernel_free |
- | |
263 | add esp, 4 |
- | |
264 | - | ||
265 | ret |
- | |
266 | - | ||
267 | .found_it: ; eax point to empty queue entry |
- | |
268 | - | ||
269 | pop [eax + tcp_out_queue_entry.data_ptr] |
- | |
270 | pop [eax + tcp_out_queue_entry.data_size] |
- | |
271 | mov [eax + tcp_out_queue_entry.ttl], 1 ; send immediately |
- | |
272 | mov [eax + tcp_out_queue_entry.retries], TCP_RETRIES |
- | |
273 | mov [eax + tcp_out_queue_entry.owner], ebx |
- | |
274 | mov [eax + tcp_out_queue_entry.sendproc], esi |
- | |
275 | mov [eax + tcp_out_queue_entry.seq_num], edx |
- | |
276 | - | ||
277 | inc [TCP_OUT_QUEUE] |
- | |
278 | - | ||
279 | sub eax, TCP_OUT_QUEUE+4 |
- | |
280 | DEBUGF 1,"Added to queue in pos %u\n", eax |
- | |
281 | - | ||
282 | ret |
- | |
283 | - | ||
284 | 244 | ||
285 | ;----------------------------------------------------------------- |
245 | ;----------------------------------------------------------------- |
286 | ; |
246 | ; |
287 | ; TCP_handler: |
247 | ; TCP_handler: |
288 | ; |
248 | ; |
289 | ; Called by IPv4_handler, |
249 | ; Called by IPv4_handler, |
290 | ; this procedure will inject the tcp data diagrams in the application sockets. |
250 | ; this procedure will inject the tcp data diagrams in the application sockets. |
291 | ; |
251 | ; |
292 | ; IN: Pointer to buffer in [esp] |
252 | ; IN: Pointer to buffer in [esp] |
293 | ; size of buffer in [esp+4] |
253 | ; size of buffer in [esp+4] |
294 | ; pointer to device struct in ebx |
254 | ; pointer to device struct in ebx |
295 | ; TCP Packet size in ecx |
255 | ; TCP Packet size in ecx |
296 | ; pointer to TCP Packet data in edx |
256 | ; pointer to TCP Packet in edx |
297 | ; SourceAddres in esi |
257 | ; SourceAddres (IPv4) in esi |
298 | ; OUT: / |
258 | ; OUT: / |
299 | ; |
259 | ; |
Line 327... | Line 287... | ||
327 | jne .socket_loop |
287 | jne .socket_loop |
328 | @@: |
288 | @@: |
Line 329... | Line 289... | ||
329 | 289 | ||
330 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
290 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort] |
331 | cmp [edx + TCP_Packet.SourcePort] , ax |
291 | cmp [edx + TCP_Packet.SourcePort] , ax |
332 | je .change_state |
292 | je .found_socket |
333 | test ax, ax |
293 | test ax, ax |
334 | jnz .socket_loop |
- | |
335 | 294 | jnz .socket_loop |
|
336 | .change_state: |
- | |
337 | 295 | .found_socket: |
|
Line 338... | Line 296... | ||
338 | DEBUGF 1,"Found valid socket for packet\n" |
296 | DEBUGF 1,"Found valid socket for packet\n" |
Line 339... | Line -... | ||
339 | - | ||
340 | inc [TCP_PACKETS_RX] |
297 | |
341 | 298 | inc [TCP_PACKETS_RX] |
|
342 | push ebx |
299 | |
Line 343... | Line 300... | ||
343 | lea ebx, [ebx + SOCKET_head.lock] |
300 | add ebx, SOCKET_head.lock |
344 | call wait_mutex |
301 | call wait_mutex |
345 | pop ebx |
302 | sub ebx, SOCKET_head.lock |
346 | 303 | ||
Line -... | Line 304... | ||
- | 304 | ;------------------------------- |
|
- | 305 | ; ebx is pointer to socket |
|
- | 306 | ; ecx is size of tcp packet |
|
- | 307 | ; edx is pointer to tcp packet |
|
- | 308 | ||
- | 309 | ; calculate header length |
|
- | 310 | movzx eax, [edx + TCP_Packet.DataOffset] |
|
- | 311 | and eax, 11110000b |
|
- | 312 | shr eax, 2 |
|
- | 313 | DEBUGF 1,"TCP header size: %u\n", eax |
|
347 | ;---------------------------------- |
314 | sub ecx, eax |
348 | ; ebx is pointer to socket |
315 | |
Line 349... | Line 316... | ||
349 | ; ecx is size of tcp packet |
316 | ;------------------------------- |
350 | ; edx is pointer to tcp packet |
317 | ; ecx is size of tcp data |
351 | 318 | ||
Line -... | Line 319... | ||
- | 319 | ; as a Packet has been received, update the TCB timer |
|
352 | ; as a Packet has been received, update the TCB timer |
320 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL |
- | 321 | ||
353 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.timer], TCP_SOCKET_TTL |
322 | ; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges |
354 | 323 | test [edx + TCP_Packet.Flags], TH_ACK |
|
- | 324 | jz .no_ack ; No ACK, so no data yet |
|
355 | ; If the received Packet has an ACK bit set, remove any Packets in the resend queue that this received Packet acknowledges |
325 | |
356 | test [edx + TCP_Packet.Flags], TH_ACK |
326 | ; Calculate ACK number |
357 | jz .call_handler ; No ACK, so no data yet |
327 | mov edi, [edx + TCP_Packet.AckNumber] |
358 | 328 | bswap edi |
|
Line 359... | Line -... | ||
359 | ; mov eax, [edx + TCP_Packet.SequenceNumber] ; Calculate sequencenumber in eax |
- | |
360 | ; bswap eax ; |
- | |
361 | ; add eax, ecx ; |
329 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], edi |
362 | - | ||
363 | mov eax, [edx + TCP_Packet.AckNumber] |
330 | DEBUGF 1,"Setting last_ack_number to %u\n", edi |
364 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.last_ack_number], eax |
- | |
365 | ;--------- |
331 | bswap edi |
366 | 332 | ||
367 | cmp [TCP_OUT_QUEUE], 0 |
- | |
368 | je .call_handler |
333 | ; Dequeue all acknowledged packets |
369 | push ecx |
334 | cmp [TCP_OUT_QUEUE], 0 ; first, check if any packets are queued at all |
370 | 335 | je .no_ack |
|
- | 336 | ||
- | 337 | push ecx |
|
- | 338 | DEBUGF 1,"Removing all queued packets with smaller ACK\n" |
|
- | 339 | mov ecx, TCP_QUEUE_SIZE |
|
371 | DEBUGF 1,"Removing all queued packets with smaller ACK\n" |
340 | mov esi, TCP_OUT_QUEUE+4 |
372 | 341 | .loop: |
|
373 | mov ecx, TCP_QUEUE_SIZE |
- | |
Line 374... | Line 342... | ||
374 | mov esi, TCP_OUT_QUEUE+4 |
342 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
Line 375... | Line 343... | ||
375 | 343 | je .maybe_next |
|
376 | .loop: |
344 | |
Line 388... | Line 356... | ||
388 | call kernel_free |
356 | call kernel_free |
Line 389... | Line 357... | ||
389 | 357 | ||
390 | .maybe_next: |
358 | .maybe_next: |
391 | add esi, tcp_out_queue_entry.size |
359 | add esi, tcp_out_queue_entry.size |
392 | loop .loop |
- | |
393 | 360 | loop .loop |
|
- | 361 | pop ecx |
|
- | 362 | ||
- | 363 | ||
394 | pop ecx |
364 | ; Now call the correct handler, depending on the socket state |
395 | .call_handler: |
- | |
396 | ; Call handler for given TCB state |
365 | .no_ack: |
397 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state] |
- | |
Line 398... | Line 366... | ||
398 | DEBUGF 1,"Socket state: %u\n", eax |
366 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state] |
399 | 367 | ||
400 | cmp eax, TCB_LISTEN |
368 | cmp eax, TCB_LISTEN |
401 | jb .dump |
369 | jb .dump |
Line 417... | Line 385... | ||
417 | 385 | ||
418 | 386 | ||
419 | 387 | ||
420 | ;----------------------------------------------------------------- |
388 | ;----------------------------------------------------------------- |
421 | ; |
389 | ; |
- | 390 | ; TCP_send (Assumes socket mutex set) |
|
422 | ; TCP_socket_send |
391 | ; |
423 | ; |
392 | ; IN: eax = socket pointer |
424 | ; IN: eax = socket pointer |
393 | ; bl = flags |
425 | ; ecx = number of bytes to send |
394 | ; ecx = number of bytes to send, may be set to 0 |
426 | ; esi = pointer to data |
395 | ; esi = pointer to data |
427 | ; |
396 | ; |
Line 428... | Line 397... | ||
428 | ;----------------------------------------------------------------- |
397 | ;----------------------------------------------------------------- |
Line 429... | Line 398... | ||
429 | align 4 |
398 | align 4 |
- | 399 | TCP_send: |
|
Line -... | Line 400... | ||
- | 400 | ||
430 | TCP_socket_send: |
401 | DEBUGF 1,"Creating TCP packet, socket: %x, flags: %x\n",eax, bl |
431 | - | ||
432 | DEBUGF 1,"Creating TCP Packet\n" |
402 | |
433 | 403 | mov di , IP_PROTO_TCP |
|
Line 434... | Line -... | ||
434 | mov di , IP_PROTO_TCP |
- | |
435 | - | ||
436 | ; Create an IPv4 Packet of the correct size |
- | |
437 | push eax |
- | |
438 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
- | |
439 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
- | |
440 | - | ||
441 | ; meanwhile, create the pseudoheader in stack, |
- | |
442 | ; (now that we still have all the variables that are needed.) |
- | |
443 | push cx |
- | |
444 | push di |
404 | add ecx, TCP_Packet.Data |
445 | push eax |
405 | |
446 | push ebx |
406 | push bx eax esi |
Line -... | Line 407... | ||
- | 407 | ; Create an IPv4 Packet of the correct size |
|
447 | 408 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
|
448 | - | ||
449 | push ecx esi eax ; save some variables for later |
- | |
450 | add ecx, TCP_Packet.Options |
- | |
451 | call IPv4_create_packet |
- | |
452 | cmp edi, -1 |
- | |
453 | je .fail |
- | |
454 | - | ||
455 | pop esi |
- | |
456 | - | ||
457 | ; Now add the TCP header to the IPv4 packet |
- | |
458 | - | ||
459 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
409 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
460 | pop [edi + TCP_Packet.SequenceNumber] |
- | |
461 | - | ||
462 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] |
410 | |
463 | pop dword [edi + TCP_Packet.SourcePort] |
- | |
464 | - | ||
465 | - | ||
466 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | |
467 | pop [edi + TCP_Packet.AckNumber] |
- | |
468 | - | ||
469 | mov al, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.flags] |
- | |
470 | mov [edi + TCP_Packet.Flags], al |
- | |
471 | - | ||
472 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
411 | call IPv4_create_packet |
Line 473... | Line 412... | ||
473 | mov [edi + TCP_Packet.UrgentPointer], 0 |
412 | cmp edi, -1 |
474 | mov [edi + TCP_Packet.DataOffset], 0x50 |
413 | je .fail |
475 | mov [edi + TCP_Packet.Checksum], 0 |
414 | |
476 | 415 | ; If there is any data, copy it first |
|
477 | ; Copy the data |
416 | pop esi |
478 | mov esi, [esp] |
417 | push edi |
479 | mov ecx, [esp+4] |
- | |
480 | add edi, TCP_Packet.Options |
- | |
481 | - | ||
482 | shr ecx, 1 |
418 | add edi, TCP_Packet.Data |
483 | jnc .nb |
- | |
484 | movsb |
- | |
485 | .nb: shr ecx, 1 |
- | |
486 | jnc .nw |
- | |
487 | movsw |
- | |
488 | .nw: rep movsd |
419 | sub ecx, TCP_Packet.Data |
489 | 420 | ||
490 | ; Now, calculate the checksum for pseudoheader |
- | |
491 | xor edx, edx |
- | |
492 | mov ecx, 12 |
- | |
493 | mov esi, esp |
- | |
494 | call checksum_1 |
- | |
495 | add esp, 12 ; remove the pseudoheader from stack |
- | |
496 | ; And that of the data |
- | |
497 | pop esi |
- | |
498 | pop ecx |
- | |
499 | call checksum_1 |
- | |
500 | ; Now create the final checksum and store it in TCP header |
- | |
501 | call checksum_2 |
- | |
502 | mov [edi + TCP_Packet.Checksum], dx |
- | |
503 | 421 | shr ecx, 1 |
|
504 | ; And now, send it! |
- | |
505 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
- | |
506 | lea esi, [ebx+ETH_DEVICE.transmit] |
- | |
507 | mov edx, [edi + TCP_Packet.AckNumber] |
- | |
508 | jmp TCP_add_to_queue |
- | |
509 | - | ||
510 | .fail: |
- | |
511 | add esp, 12+12+4 |
- | |
512 | ret |
- | |
513 | - | ||
514 | - | ||
515 | - | ||
516 | - | ||
517 | - | ||
518 | ;----------------------------------------------------------------- |
- | |
519 | ; |
- | |
520 | ; TCP_send_ack |
- | |
521 | ; |
- | |
522 | ; IN: eax = socket pointer |
- | |
523 | ; bl = flags |
- | |
524 | ; |
- | |
525 | ;----------------------------------------------------------------- |
- | |
526 | align 4 |
- | |
527 | TCP_send_ack: |
- | |
528 | - | ||
529 | DEBUGF 1,"Creating TCP ACK, socket: %x, flags: %x\n",eax, bl |
- | |
530 | - | ||
531 | mov di , IP_PROTO_TCP |
- | |
532 | mov ecx, TCP_Packet.Options |
- | |
533 | 422 | jnc .nb |
|
534 | push bx eax |
- | |
Line 535... | Line 423... | ||
535 | 423 | movsb |
|
536 | ; Create an IPv4 Packet of the correct size |
424 | .nb: shr ecx, 1 |
Line -... | Line 425... | ||
- | 425 | jnc .nw |
|
537 | 426 | movsw |
|
538 | mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP] |
427 | .nw: test ecx, ecx |
- | 428 | jz .nd |
|
Line -... | Line 429... | ||
- | 429 | rep movsd |
|
539 | mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP] |
430 | .nd: |
540 | 431 | pop edi |
|
Line -... | Line 432... | ||
- | 432 | ||
541 | call IPv4_create_packet |
433 | ; Fill in the TCP header |
542 | cmp edi, -1 |
434 | pop esi |
Line -... | Line 435... | ||
- | 435 | ||
543 | je .fail |
436 | ; fill in tcp sequence number |
544 | 437 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
|
545 | ; Fill in the TCP header |
438 | pop [edi + TCP_Packet.SequenceNumber] |
546 | pop esi |
439 | inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT) ;;;;;;;; |
547 | 440 | ||
548 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
441 | ; Fill in local and remote ports |
Line -... | Line 442... | ||
- | 442 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] |
|
549 | pop [edi + TCP_Packet.SequenceNumber] |
443 | pop dword [edi + TCP_Packet.SourcePort] |
Line 550... | Line 444... | ||
550 | 444 | ||
551 | push dword [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.LocalPort] ; both ports at once |
445 | ; Acknumber |
Line 552... | Line 446... | ||
552 | pop dword [edi + TCP_Packet.SourcePort] |
446 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
553 | 447 | pop [edi + TCP_Packet.AckNumber] |
|
554 | push [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
448 | |
555 | pop [edi + TCP_Packet.AckNumber] |
449 | ; Fill in other tcp options |
556 | 450 | pop cx |
|
Line 557... | Line 451... | ||
557 | pop cx |
451 | mov [edi + TCP_Packet.Flags], cl |
558 | mov [edi + TCP_Packet.Flags], cl |
452 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
559 | mov [edi + TCP_Packet.Window], 0x0005 ; 1280 bytes |
453 | mov [edi + TCP_Packet.UrgentPointer], 0 |
560 | mov [edi + TCP_Packet.UrgentPointer], 0 |
454 | mov [edi + TCP_Packet.DataOffset], 0x50 |
561 | mov [edi + TCP_Packet.DataOffset], 0x50 |
455 | mov [edi + TCP_Packet.Checksum], 0 |
562 | mov [edi + TCP_Packet.Checksum], 0 |
456 | |
563 | 457 | ; Push pointer to and size of total packet (needed for send procedure) |
|
564 | push edx eax |
458 | push edx eax |
565 | 459 | ||
566 | ; lea esi, [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
460 | ; push socket number (for TCP_add_to_queue) |
567 | ; inc_INET esi |
461 | push esi |
Line 568... | Line 462... | ||
568 | 462 | ||
569 | ; Now, calculate the checksum |
463 | ; Now, calculate the checksum ; TODO: calculate correct checksum for packets with data |
570 | pushw TCP_Packet.Options shl 8 |
- | |
571 | pushw IP_PROTO_TCP shl 8 |
464 | pushw TCP_Packet.Data shl 8 |
- | 465 | pushw IP_PROTO_TCP shl 8 |
|
- | 466 | pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
|
- | 467 | pushd [edi-8] ; source address |
|
572 | pushd [edi-4] ; destination address ; TODO: fix this, IPv4 packet could have options.. |
468 | |
Line 573... | Line 469... | ||
573 | pushd [edi-8] ; source address |
469 | xor edx, edx |
574 | 470 | mov ecx, TCP_Packet.Data |
|
- | 471 | mov esi, edi |
|
- | 472 | call checksum_1 |
|
- | 473 | mov ecx, 12 |
|
- | 474 | mov esi, esp |
|
- | 475 | call checksum_1 |
|
- | 476 | add esp, 12 ; remove the pseudoheader from stack |
|
- | 477 | ; and store it in TCP header |
|
- | 478 | call checksum_2 |
|
- | 479 | mov [edi + TCP_Packet.Checksum], dx |
|
- | 480 | ||
- | 481 | ; At last send the packet! |
|
- | 482 | DEBUGF 1,"Sending TCP Packet to device %x\n", ebx |
|
- | 483 | mov edx, [edi + TCP_Packet.SequenceNumber] |
|
- | 484 | bswap edx |
|
- | 485 | mov esi, [ebx + ETH_DEVICE.transmit] |
|
- | 486 | pop edi |
|
- | 487 | jmp TCP_queue |
|
- | 488 | ||
- | 489 | .fail: |
|
- | 490 | add esp, 2+4 |
|
- | 491 | or eax, -1 |
|
- | 492 | ret |
|
- | 493 | ||
- | 494 | ||
- | 495 | ;----------------------------------------------------------------- |
|
- | 496 | ; |
|
- | 497 | ; Queue a TCP packet for sending |
|
- | 498 | ; |
|
- | 499 | ; IN: [esp] pointer to buffer |
|
- | 500 | ; [esp + 4] size of buffer |
|
- | 501 | ; ebx = driver struct |
|
- | 502 | ; esi = sender proc |
|
- | 503 | ; edx = sequence number of this packet in normal byte order |
|
- | 504 | ; edi = socket number |
|
- | 505 | ; OUT: / |
|
- | 506 | ; |
|
- | 507 | ;----------------------------------------------------------------- |
|
- | 508 | align 4 |
|
- | 509 | TCP_queue: |
|
- | 510 | ||
- | 511 | bswap edx |
|
- | 512 | DEBUGF 1,"Adding packet to TCP queue, buffer: %x, size: %u, driver: %x, acknum: %u\n", [esp], [esp+4], ebx, edx |
|
- | 513 | bswap edx |
|
- | 514 | ||
- | 515 | cmp [TCP_OUT_QUEUE], TCP_QUEUE_SIZE |
|
- | 516 | jge .full |
|
- | 517 | ||
- | 518 | mov ecx, TCP_QUEUE_SIZE |
|
- | 519 | mov eax, TCP_OUT_QUEUE+4 |
|
- | 520 | ||
- | 521 | .loop: |
|
- | 522 | cmp [eax + tcp_out_queue_entry.data_ptr], 0 |
|
- | 523 | je .found_it |
|
- | 524 | add eax, tcp_out_queue_entry.size |
|
- | 525 | loop .loop |
|
- | 526 | ||
- | 527 | .full: ; silently discard the packet |
|
- | 528 | DEBUGF 1,"TCP queue is full!\n" |
|
- | 529 | ||
- | 530 | call kernel_free |
|
575 | xor edx, edx |
531 | add esp, 4 |
Line 606... | Line 562... | ||
606 | align 4 |
562 | align 4 |
607 | stateTCB_LISTEN: |
563 | stateTCB_LISTEN: |
Line 608... | Line 564... | ||
608 | 564 | ||
Line 609... | Line -... | ||
609 | DEBUGF 1,"TCBStateHandler: Listen\n" |
- | |
610 | 565 | DEBUGF 1,"TCBStateHandler: Listen\n" |
|
611 | ; In this case, we are expecting a SYN Packet |
- | |
612 | ; For now, if the Packet is a SYN, process it, and send a response |
- | |
613 | ; If not, ignore it |
- | |
614 | - | ||
615 | ; Look at control flags |
566 | |
616 | test [edx + TCP_Packet.Flags], TH_SYN |
567 | test [edx + TCP_Packet.Flags], TH_SYN ; SYN packet? => send syn+ack, open new socket and set connection to established |
617 | jz .exit |
568 | jz .exit |
618 | ; Exit if backlog queue is full |
569 | ; Exit if backlog queue is full |
619 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
570 | mov ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
620 | cmp ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog] |
571 | cmp ax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog] |
621 | jae .exit |
572 | jae .exit |
622 | ; Allocate new socket |
573 | ; Allocate new socket |
623 | push esi |
- | |
624 | call net_socket_alloc |
574 | push esi edi |
625 | pop esi |
575 | call net_socket_alloc |
626 | test eax, eax |
576 | test eax, eax |
627 | jz .exit |
- | |
628 | ; Copy structure from current socket to new, including lock |
577 | jz .fail |
629 | push esi edi |
578 | ; Copy structure from current socket to new, including lock |
630 | lea esi, [ebx + SOCKET_head.PID] ; yes, PID must also be copied |
579 | lea esi, [ebx + SOCKET_head.PID] ; yes, PID must also be copied |
631 | lea edi, [eax + SOCKET_head.PID] |
580 | lea edi, [eax + SOCKET_head.PID] |
632 | mov ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4 |
581 | mov ecx, ((SOCKET_head.end - SOCKET_head.PID) + IPv4_SOCKET.end + TCP_SOCKET.end + 3)/4 |
633 | rep movsd |
582 | rep movsd |
634 | pop edi esi |
583 | pop edi esi |
635 | ; Push pointer to new socket to queue |
584 | ; Push pointer to new socket to queue |
636 | movzx ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
585 | movzx ecx, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
Line 637... | Line -... | ||
637 | inc [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
- | |
638 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax |
- | |
639 | - | ||
640 | ; We have a SYN. update the socket with this IP Packets details, |
586 | inc [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog_cur] |
641 | ; And send a response |
587 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end + ecx*4], eax |
642 | 588 | ||
643 | mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address |
589 | mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], esi ; IP source address |
644 | mov cx, [edx + TCP_Packet.SourcePort] |
590 | mov cx, [edx + TCP_Packet.SourcePort] |
Line 649... | Line 595... | ||
649 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
595 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
650 | inc_INET esi ; RCV.NXT |
596 | inc_INET esi ; RCV.NXT |
651 | mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS] |
597 | mov ecx, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.ISS] |
652 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx |
598 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT], ecx |
Line 653... | Line -... | ||
653 | - | ||
654 | mov [eax + SOCKET_head.lock], 0 |
599 | |
Line 655... | Line 600... | ||
655 | mov [ebx + SOCKET_head.lock], 0 |
600 | mov [ebx + SOCKET_head.lock], 0 |
656 | 601 | ||
657 | push eax |
602 | push eax |
- | 603 | ; Now construct the response |
|
658 | ; Now construct the response |
604 | mov bl, TH_SYN + TH_ACK |
659 | mov bl, TH_SYN + TH_ACK |
605 | xor ecx, ecx |
Line -... | Line 606... | ||
- | 606 | call TCP_send |
|
660 | call TCP_send_ack |
607 | pop eax |
661 | pop eax |
608 | |
662 | - | ||
663 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
- | |
664 | call notify_network_event |
- | |
665 | - | ||
666 | ; increment SND.NXT in socket |
609 | mov [eax + SOCKET_head.lock], 0 |
Line 667... | Line 610... | ||
667 | lea esi, [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
610 | mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
668 | inc_INET esi |
611 | call notify_network_event |
669 | ret |
612 | ret |
Line -... | Line 613... | ||
- | 613 | ||
- | 614 | .exit: |
|
- | 615 | mov [ebx + SOCKET_head.lock], 0 |
|
- | 616 | ret |
|
- | 617 | ||
Line 670... | Line 618... | ||
670 | 618 | .fail: |
|
671 | .exit: |
619 | add esp, 8 |
Line 672... | Line 620... | ||
672 | mov [ebx + SOCKET_head.lock], 0 |
620 | mov [ebx + SOCKET_head.lock], 0 |
Line 673... | Line 621... | ||
673 | ret |
621 | ret |
674 | 622 | ||
Line 675... | Line 623... | ||
675 | 623 | ||
676 | align 4 |
- | |
677 | stateTCB_SYN_SENT: |
- | |
678 | - | ||
Line 679... | Line 624... | ||
679 | DEBUGF 1,"TCBStateHandler: Syn_Sent\n" |
624 | align 4 |
680 | 625 | stateTCB_SYN_SENT: |
|
Line -... | Line 626... | ||
- | 626 | ||
681 | ; We are awaiting an ACK to our SYN, with a SYM |
627 | DEBUGF 1,"TCBStateHandler: Syn_Sent\n" |
682 | ; Look at control flags - expecting an ACK |
628 | |
683 | - | ||
Line 684... | Line -... | ||
684 | mov al, [edx + TCP_Packet.Flags] |
- | |
685 | and al, TH_SYN + TH_ACK |
- | |
686 | cmp al, TH_SYN + TH_ACK |
- | |
Line 687... | Line -... | ||
687 | je .syn_ack |
- | |
688 | - | ||
689 | test al, TH_SYN |
629 | ; We are awaiting an ACK to our SYN, with a SYM |
690 | jz .exit |
630 | ; Look at control flags - expecting an ACK |
691 | - | ||
692 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
- | |
693 | pushd TH_SYN + TH_ACK |
- | |
694 | jmp .send |
- | |
695 | - | ||
Line -... | Line 631... | ||
- | 631 | ||
696 | .syn_ack: |
632 | mov al, [edx + TCP_Packet.Flags] |
697 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
- | |
Line -... | Line 633... | ||
- | 633 | ||
- | 634 | test al, TH_RST |
|
- | 635 | jnz .reset ; jump if RST bit set |
|
- | 636 | ||
- | 637 | push [edx + TCP_Packet.SequenceNumber] ;; |
|
- | 638 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] ;; |
|
- | 639 | inc_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) ;; |
|
- | 640 | ||
698 | pushd TH_ACK |
641 | |
699 | 642 | push [edx + TCP_Packet.AckNumber] ;;;;;; |
|
- | 643 | pop [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] ;;;;;; |
|
- | 644 | ||
- | 645 | and al, TH_SYN + TH_ACK |
|
- | 646 | jz .exit ; jump if none of the following is set: RST, SYN, ACK |
|
700 | .send: |
647 | |
701 | ; Store the recv.nxt field |
- | |
Line 702... | Line 648... | ||
702 | mov eax, [edx + TCP_Packet.SequenceNumber] |
648 | test al, TH_ACK |
703 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.IRS], eax |
649 | jz .onlysyn ; jump if only SYN bit is set |
704 | bswap eax |
650 | |
Line -... | Line 651... | ||
- | 651 | ; If we arrived here, SYN and ACK are set |
|
- | 652 | ||
- | 653 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_ESTABLISHED |
|
- | 654 | pushw TH_ACK |
|
- | 655 | ||
- | 656 | .send: ; Send an ACK |
|
- | 657 | mov eax, ebx |
|
- | 658 | pop bx |
|
- | 659 | push eax |
|
- | 660 | xor ecx, ecx |
|
- | 661 | call TCP_send |
|
- | 662 | pop ebx |
|
- | 663 | ||
- | 664 | .exit: |
|
Line 705... | Line 665... | ||
705 | inc eax |
665 | mov [ebx + SOCKET_head.lock], 0 |
706 | bswap eax |
666 | ret |
Line 707... | Line 667... | ||
707 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT], eax ; Update our recv.nxt field |
667 | |
Line 708... | Line -... | ||
708 | mov [ebx + SOCKET_head.lock], 0 |
- | |
709 | - | ||
710 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | |
711 | inc_INET esi |
- | |
712 | 668 | .reset: |
|
713 | ; Send an ACK |
669 | ; TODO: .... |
Line 714... | Line 670... | ||
714 | mov eax, ebx |
670 | |
715 | pop ebx |
671 | ; remove all queued TCP packets for this connection ! |
716 | call TCP_send_ack |
672 | |
717 | 673 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSED |
|
Line 718... | Line 674... | ||
718 | .exit: |
674 | mov [ebx + SOCKET_head.lock], 0 |
719 | mov [ebx + SOCKET_head.lock], 0 |
675 | ret |
Line 720... | Line 676... | ||
720 | ret |
676 | |
721 | - | ||
722 | 677 | .onlysyn: |
|
723 | 678 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_SYN_RECEIVED |
|
Line 724... | Line 679... | ||
724 | align 4 |
679 | pushw TH_SYN + TH_ACK |
725 | stateTCB_SYN_RECEIVED: |
680 | jmp .send |
726 | 681 | ||
Line 757... | Line 712... | ||
757 | 712 | ||
758 | 713 | ||
Line 759... | Line -... | ||
759 | align 4 |
- | |
760 | stateTCB_ESTABLISHED: |
714 | align 4 |
Line 761... | Line 715... | ||
761 | 715 | stateTCB_ESTABLISHED: |
|
- | 716 | ||
- | 717 | DEBUGF 1,"TCBStateHandler: Established\n" |
|
- | 718 | ||
762 | 719 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
|
763 | DEBUGF 1,"TCBStateHandler: Established\n" |
720 | bswap eax |
Line 764... | Line 721... | ||
764 | 721 | DEBUGF 1,"RCV_NXT is set to:%u\n", eax |
|
- | 722 | bswap eax |
|
- | 723 | cmp eax, [edx + TCP_Packet.SequenceNumber] |
|
- | 724 | jne .exit |
|
765 | mov eax, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
725 | |
- | 726 | ; Calculate next sequencenumber |
|
Line 766... | Line -... | ||
766 | cmp eax, [edx + TCP_Packet.SequenceNumber] |
- | |
767 | jne .exit |
727 | test ecx, ecx |
768 | 728 | jnz @f |
|
769 | ; Here we are expecting data, or a request to close |
- | |
770 | ; OR both... |
- | |
771 | - | ||
772 | ; Did we receive a FIN or RST? |
- | |
773 | test [edx + TCP_Packet.Flags], TH_FIN |
- | |
774 | jz .check_ack |
- | |
Line 775... | Line 729... | ||
775 | 729 | inc ecx |
|
776 | ; It was a fin or reset. |
- | |
777 | 730 | @@: |
|
778 | ;;; TODO: write following code: |
731 | add_INET (ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT) |
Line 779... | Line 732... | ||
779 | ; Remove resend entries from the queue - I dont want to send any more data |
732 | |
780 | ; Send an ACK to that fin, and enter closewait state |
- | |
781 | 733 | test [edx + TCP_Packet.Flags], TH_FIN |
|
782 | .check_ack: |
734 | jnz .fin |
783 | ; Check that we received an ACK |
735 | |
784 | test [edx + TCP_Packet.Flags], TH_ACK |
736 | .check_ack: |
785 | jz .exit |
737 | test [edx + TCP_Packet.Flags], TH_ACK |
Line 796... | Line 748... | ||
796 | ja @f |
748 | ja @f |
797 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1 |
749 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.wndsizeTimer], 1 |
798 | @@: |
750 | @@: |
799 | pop ecx |
751 | pop ecx |
Line -... | Line 752... | ||
- | 752 | ||
800 | 753 | ; Now, see if we received any data |
|
801 | test ecx, ecx |
- | |
802 | jnz .data ; Read data, if any |
- | |
803 | - | ||
804 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
754 | test ecx, ecx |
Line -... | Line 755... | ||
- | 755 | jz .ack |
|
805 | inc_INET esi |
756 | |
806 | 757 | DEBUGF 1,"Got %u bytes data!\n", ecx |
|
807 | ; If we had received a fin, we need to ACK it. |
758 | ; calculate header length |
808 | cmp [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT |
759 | movzx eax, [edx + TCP_Packet.DataOffset] |
809 | je .ack |
- | |
- | 760 | and eax, 11110000b |
|
810 | jmp .exit |
761 | shr eax, 2 |
811 | 762 | DEBUGF 1,"TCP header size: %u\n", eax |
|
812 | .data: |
- | |
813 | ;;; |
763 | add edx, eax |
814 | lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.SND_NXT] |
- | |
815 | add_INET esi |
- | |
816 | 764 | add esp, 4 |
|
817 | DEBUGF 1,"Got data!\n" |
765 | pop esi |
818 | mov esi, [esp + 4] |
766 | add esp, 4 |
819 | sub edx, esi |
767 | sub edx, esi |
820 | mov edi, edx |
768 | mov edi, edx |
Line 821... | Line 769... | ||
821 | mov eax, ebx |
769 | mov eax, ebx |
822 | call socket_internal_receiver |
- | |
823 | - | ||
824 | .ack: |
770 | jmp socket_internal_receiver ; Place the data from packet into socket |
825 | mov [ebx + SOCKET_head.lock], 0 |
771 | |
- | 772 | .ack: |
|
- | 773 | mov eax, ebx |
|
826 | ; Send an ACK |
774 | mov bl, TH_ACK |
- | 775 | push eax |
|
827 | mov eax, ebx |
776 | xor ecx, ecx |
828 | mov bl, TH_ACK |
- | |
829 | call TCP_send_ack |
777 | call TCP_send ; send the ack |
830 | .exit: |
778 | pop ebx |
Line -... | Line 779... | ||
- | 779 | .exit: |
|
- | 780 | mov [ebx + SOCKET_head.lock], 0 |
|
- | 781 | ret |
|
- | 782 | ||
- | 783 | .fin: |
|
- | 784 | ; Remove all resend entries from the queue |
|
- | 785 | mov ecx, TCP_QUEUE_SIZE |
|
- | 786 | mov esi, TCP_OUT_QUEUE+4 |
|
- | 787 | ||
- | 788 | .removeloop: |
|
- | 789 | cmp [esi + tcp_out_queue_entry.data_ptr], 0 |
|
- | 790 | je .maybe_next |
|
- | 791 | ||
- | 792 | ; TODO: check if the packets belong to the same tcp connection ! |
|
- | 793 | ||
- | 794 | DEBUGF 1,"Removing a queued packet\n" |
|
- | 795 | ||
- | 796 | push [esi + tcp_out_queue_entry.data_ptr] |
|
- | 797 | mov [esi + tcp_out_queue_entry.data_ptr], 0 |
|
- | 798 | dec [TCP_OUT_QUEUE] |
|
- | 799 | call kernel_free |
|
- | 800 | ||
- | 801 | .maybe_next: |
|
- | 802 | add esi, tcp_out_queue_entry.size |
|
- | 803 | loop .removeloop |
|
- | 804 | ||
Line 831... | Line 805... | ||
831 | 805 | ; Send an ACK to that fin, and enter closewait state |
|
832 | mov [ebx + SOCKET_head.lock], 0 |
806 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSE_WAIT |
Line 853... | Line 827... | ||
853 | @@: mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING |
827 | @@: mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_CLOSING |
854 | cmp al, TH_FIN |
828 | cmp al, TH_FIN |
855 | je @f |
829 | je @f |
856 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
830 | mov [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.state], TCB_TIMED_WAIT |
Line -... | Line 831... | ||
- | 831 | ||
- | 832 | @@: |
|
857 | 833 | ||
858 | @@: lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
834 | ; lea esi, [ebx + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RCV_NXT] |
Line 859... | Line -... | ||
859 | inc_INET esi |
- | |
860 | 835 | ; inc_INET esi |
|
861 | mov [ebx + SOCKET_head.lock], 0 |
836 | |
862 | ; Send an ACK |
837 | ; Send an ACK |
- | 838 | mov eax, ebx |
|
- | 839 | mov bl, TH_ACK |
|
863 | mov eax, ebx |
840 | push eax |
- | 841 | xor ecx, ecx |
|
Line 864... | Line 842... | ||
864 | mov bl, TH_ACK |
842 | call TCP_send |
865 | call TCP_send_ack |
843 | pop ebx |
866 | 844 | ||
Line 887... | Line 865... | ||
887 | mov [ebx + SOCKET_head.lock], 0 |
865 | mov [ebx + SOCKET_head.lock], 0 |
Line 888... | Line 866... | ||
888 | 866 | ||
889 | ; Send an ACK |
867 | ; Send an ACK |
890 | mov eax, ebx |
868 | mov eax, ebx |
- | 869 | mov bl, TH_ACK |
|
- | 870 | push eax |
|
891 | mov bl, TH_ACK |
871 | xor ecx, ecx |
- | 872 | call TCP_send |
|
Line 892... | Line 873... | ||
892 | call TCP_send_ack |
873 | pop ebx |
893 | 874 | ||
894 | .exit: |
875 | .exit: |