Subversion Repositories Kolibri OS

Rev

Rev 1519 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1519 Rev 1529
Line 14... Line 14...
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 18... Line 18...
18
 
18
 
Line 19... Line 19...
19
$Revision: 1519 $
19
$Revision: 1529 $
20
 
20
 
21
; Socket states
21
; Socket states
22
TCB_CLOSED		equ 0
22
TCB_CLOSED		equ 0
Line 71... Line 71...
71
 
71
 
72
; timer constants
72
; timer constants
73
TCP_max_rxtshift	equ 12		; max retransmissions waiting for ACK
73
TCP_max_rxtshift	equ 12		; max retransmissions waiting for ACK
Line -... Line 74...
-
 
74
TCP_max_keepcnt 	equ 8		; max keepalive probes
-
 
75
 
-
 
76
;
Line 74... Line 77...
74
TCP_max_keepcnt 	equ 8		; max keepalive probes
77
TCP_max_winshift	equ 14
75
 
78
TCP_max_win		equ 65535
76
 
79
 
77
struct	TCP_segment
80
struct	TCP_segment
Line 115... Line 118...
115
;
118
;
116
; TCP_init
119
; TCP_init
117
;
120
;
118
;  This function resets all TCP variables
121
;  This function resets all TCP variables
119
;
122
;
120
;  IN:  /
-
 
121
;  OUT: /
-
 
122
;
-
 
123
;-----------------------------------------------------------------
123
;-----------------------------------------------------------------
124
align 4
-
 
125
TCP_init:
124
macro	TCP_init {
Line 126... Line 125...
126
 
125
 
127
	xor	eax, eax
126
	xor	eax, eax
128
	mov	edi, TCP_segments_tx
127
	mov	edi, TCP_segments_tx
129
	mov	ecx, (6*IP_MAX_INTERFACES)
128
	mov	ecx, (6*IP_MAX_INTERFACES)
Line -... Line 129...
-
 
129
	rep	stosd
130
	rep	stosd
130
 
Line 131... Line 131...
131
 
131
	pseudo_random	eax
Line 132... Line 132...
132
	mov	[TCP_sequence_num], 1
132
	mov	[TCP_sequence_num], eax
133
 
133
 
134
	ret
134
}
135
 
135
 
-
 
136
 
-
 
137
;----------------------
136
 
138
;
137
;----------------------
139
;
Line 138... Line 140...
138
;
140
;----------------------
139
;
141
macro	TCP_timer_160ms {
140
;----------------------
142
 
141
align 4
143
local	.loop
Line 154... Line 156...
154
	jnz	.loop
156
	jnz	.loop
Line 155... Line 157...
155
 
157
 
Line 156... Line 158...
156
	DEBUGF	1,"TCP ack for socket %x expired, time to piggyback!\n", eax
158
	DEBUGF	1,"TCP ack for socket %x expired, time to piggyback!\n", eax
157
 
159
 
158
	push	eax
160
	push	eax
Line 159... Line 161...
159
	call	TCP_respond
161
	call	TCP_respond_socket
Line 160... Line 162...
160
	pop	eax
162
	pop	eax
Line 161... Line 163...
161
 
163
 
Line 162... Line 164...
162
	jmp	.loop
164
	jmp	.loop
163
 
165
 
164
  .exit:
166
  .exit:
165
 
167
 
-
 
168
}
-
 
169
 
166
	ret
170
 
167
 
171
;-----------------------------------------------------------------
Line 168... Line 172...
168
 
172
;
Line 169... Line 173...
169
;-----------------------------------------------------------------
173
;
Line 188... Line 192...
188
	jz	.exit
192
	jz	.exit
Line 189... Line 193...
189
 
193
 
190
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
194
	cmp	[eax + SOCKET.Type], IP_PROTO_TCP
Line -... Line 195...
-
 
195
	jne	.loop
191
	jne	.loop
196
 
192
 
197
	inc	[eax + TCP_SOCKET.t_idle]
Line 193... Line 198...
193
	dec    [eax + TCP_SOCKET.timer_retransmission]
198
	dec	[eax + TCP_SOCKET.timer_retransmission]
Line 219... Line 224...
219
 
224
 
Line 220... Line 225...
220
	DEBUGF	1,"socket %x: persist timer expired\n", eax
225
	DEBUGF	1,"socket %x: persist timer expired\n", eax
221
 
226
 
-
 
227
	jmp	.loop
-
 
228
  .exit:
-
 
229
}
-
 
230
 
-
 
231
 
-
 
232
 
-
 
233
 
-
 
234
macro	TCP_checksum IP1, IP2 {
-
 
235
 
-
 
236
;-------------
-
 
237
; Pseudoheader
-
 
238
 
-
 
239
	; protocol type
-
 
240
	mov	edx, IP_PROTO_TCP
-
 
241
 
-
 
242
	; source address
-
 
243
	add	dl, byte [IP1+1+4]
-
 
244
	adc	dh, byte [IP1+0+4]
-
 
245
	adc	dl, byte [IP1+3+4]
-
 
246
	adc	dh, byte [IP1+2+4]
-
 
247
 
-
 
248
	; destination address
-
 
249
	adc	dl, byte [IP2+1+8]
-
 
250
	adc	dh, byte [IP2+0+8]
-
 
251
	adc	dl, byte [IP2+3+8]
-
 
252
	adc	dh, byte [IP2+2+8]
-
 
253
 
-
 
254
	; size
-
 
255
	adc	dl, cl
-
 
256
	adc	dh, ch
-
 
257
 
-
 
258
;---------------------
-
 
259
; Real header and data
-
 
260
 
-
 
261
	push	esi
222
	jmp	.loop
262
	call	checksum_1
-
 
263
	call	checksum_2
-
 
264
	pop	esi
-
 
265
 
Line 223... Line 266...
223
  .exit:
266
}	; returns in dx only
224
	ret
267
 
225
 
268
 
Line 241... Line 284...
241
;
284
;
242
;-----------------------------------------------------------------
285
;-----------------------------------------------------------------
243
align 4
286
align 4
244
TCP_input:
287
TCP_input:
Line 245... Line 288...
245
 
288
 
246
       DEBUGF  1,"TCP_input\n"
-
 
247
 
289
       DEBUGF  1,"TCP_input size=%u\n", ecx
Line 248... Line 290...
248
; Offset must be greater than or equal to the size of the standard TCP header (20) and less than or equal to the TCP length.
290
; Offset must be greater than or equal to the size of the standard TCP header (20) and less than or equal to the TCP length.
249
 
291
 
250
	movzx	eax, [edx + TCP_segment.DataOffset]
292
	movzx	eax, [edx + TCP_segment.DataOffset]
Line 251... Line 293...
251
	and	eax, 0xf0
293
	and	eax, 0xf0
Line 252... Line 294...
252
	shr	al , 2
294
	shr	al, 2
253
 
295
 
Line 254... Line -...
254
	DEBUGF	1,"data offset: %u\n", eax
-
 
255
 
-
 
256
	cmp	eax, 20
-
 
257
	jl	.drop
296
	DEBUGF	1,"headersize=%u\n", eax
258
 
297
 
Line 259... Line 298...
259
	cmp	eax, ecx
298
	cmp	eax, 20
260
	jg	.drop
-
 
261
 
299
	jl	.drop
-
 
300
 
262
;-------------------------------
301
;-------------------------------
263
; Now, re-calculate the checksum
302
; Now, re-calculate the checksum
-
 
303
 
264
 
304
	push	eax ecx edx
265
	push	eax edx ebx
-
 
266
 
305
	pushw	[edx + TCP_segment.Checksum]
267
	push	edi
306
	mov	[edx + TCP_segment.Checksum], 0
268
	push	esi
307
	push	esi edi
269
	mov	esi, edx
308
	mov	esi, edx
Line 270... Line 309...
270
	call	TCP_checksum	; this destroys edx, ecx and esi (but not edi! :)
309
	TCP_checksum
Line -... Line 310...
-
 
310
	pop	esi edi ; yes, swap them (we dont need dest addr)
-
 
311
	pop	cx	; previous checksum
-
 
312
	cmp	cx, dx
271
 
313
	pop	edx ecx esi
272
	pop	ebx edx eax
314
	jnz	.drop
Line 273... Line 315...
273
 
315
 
274
	cmp	[edx + TCP_segment.Checksum], 0
316
	DEBUGF	1,"Checksum is correct\n"
275
	jnz	.drop
317
 
Line 276... Line 318...
276
 
318
	sub	ecx, esi	; update packet size
277
	DEBUGF	1,"Checksum is correct\n"
319
	jl	.drop
Line 278... Line 320...
278
 
320
 
279
;-----------------------------------------------------------------------------------------
321
;-----------------------------------------------------------------------------------------
280
; Check if this packet has a timestamp option (We do it here so we can process it quickly)
322
; Check if this packet has a timestamp option (We do it here so we can process it quickly)
Line 293... Line 335...
293
	cmp	dword [edx + TCP_segment.Data], 0x0101080a	; Timestamp header
335
	cmp	dword [edx + TCP_segment.Data], 0x0101080a	; Timestamp header
294
	jne	.no_timestamp
336
	jne	.no_timestamp
Line 295... Line 337...
295
 
337
 
Line 296... Line 338...
296
	DEBUGF	1,"timestamp ok\n"
338
	DEBUGF	1,"timestamp ok\n"
297
 
339
 
Line 298... Line -...
298
	; TODO: Parse the options
-
 
299
	; TODO: Set a Bit in the TCP to tell all options are parsed
-
 
300
 
340
	; TODO: Parse the option
Line 301... Line 341...
301
	ret
341
	; TODO: Set a Bit in the TCP to tell all options are parsed
302
 
342
 
Line 303... Line 343...
303
  .no_timestamp:
343
  .no_timestamp:
304
 
344
 
Line 305... Line 345...
305
;-------------------------------------------
345
;-------------------------------------------
306
; Convert Big-endian values to little endian
346
; Convert Big-endian values to little endian
-
 
347
 
-
 
348
	ntohld	[edx + TCP_segment.SequenceNumber]
Line 307... Line 349...
307
 
349
	ntohld	[edx + TCP_segment.AckNumber]
308
	ntohld	[edx + TCP_segment.SequenceNumber]
350
 
Line 309... Line 351...
309
	ntohld	[edx + TCP_segment.AckNumber]
351
	ntohlw	[edx + TCP_segment.Window]
Line 331... Line 373...
331
	mov	ax, [edx + TCP_segment.DestinationPort]
373
	mov	ax, [edx + TCP_segment.DestinationPort]
332
	cmp	[ebx + TCP_SOCKET.LocalPort], ax
374
	cmp	[ebx + TCP_SOCKET.LocalPort], ax
333
	jne	.socket_loop
375
	jne	.socket_loop
Line 334... Line 376...
334
 
376
 
335
	mov	eax, [ebx + IP_SOCKET.RemoteIP]
377
	mov	eax, [ebx + IP_SOCKET.RemoteIP]
336
	cmp	eax, esi
378
	cmp	eax, edi			; sender IP
337
	je	@f
379
	je	@f
338
	test	eax, eax
380
	test	eax, eax
339
	jnz	.socket_loop
381
	jnz	.socket_loop
Line 350... Line 392...
350
; ebx now contains the pointer to the socket
392
; ebx now contains the pointer to the socket
Line 351... Line 393...
351
 
393
 
352
;----------------------------
394
;----------------------------
Line 353... Line 395...
353
; Check if socket isnt closed
395
; Check if socket isnt closed
354
 
396
 
Line 355... Line 397...
355
	cmp	[TCP_SOCKET.t_state], TCB_CLOSED
397
	cmp	[ebx + TCP_SOCKET.t_state], TCB_CLOSED
356
	je	.drop
398
	je	.drop
Line 357... Line 399...
357
 
399
 
358
;----------------
400
;----------------
359
; Lock the socket
401
; Lock the socket
360
 
-
 
361
	add	ebx, SOCKET.lock ; TODO: figure out if we should lock now already
-
 
362
	call	wait_mutex
-
 
Line 363... Line 402...
363
	sub	ebx, SOCKET.lock
402
 
364
 
-
 
Line -... Line 403...
-
 
403
;;        add     ebx, SOCKET.lock ; TODO: figure out if we should lock now already
365
;---------------------------------------
404
;;        call    wait_mutex
366
; unscale the window into a 32 bit value  ;;;;;;
-
 
Line -... Line 405...
-
 
405
;;        sub     ebx, SOCKET.lock
-
 
406
 
367
 
407
	DEBUGF	1,"Socket locked\n"
368
	movzx	eax, [edx + TCP_segment.Window]
408
 
-
 
409
;----------------------------------------------------------------------------------------
Line 369... Line 410...
369
	xchg	al, ah
410
; unscale the window into a 32 bit value (notice that SND_SCALE must be initialised to 0)
Line 370... Line 411...
370
 
411
 
371
	test	[edx + TCP_segment.Flags], TH_SYN
412
	movzx	eax, [edx + TCP_segment.Window]
Line 372... Line 413...
372
	jnz	.no_syn
413
	push	cx
-
 
414
	mov	cl, [ebx + TCP_SOCKET.SND_SCALE]
Line 373... Line 415...
373
 
415
	shl	eax, cl
374
	mov	cl , [ebx + TCP_SOCKET.SND_SCALE]
416
	pop	cx
Line -... Line 417...
-
 
417
 
-
 
418
	;;;; do something with eax
Line -... Line 419...
-
 
419
 
375
	shl	eax, cl
420
;-----------------------------------
Line -... Line 421...
-
 
421
; Is this socket a listening socket?
-
 
422
 
Line 376... Line 423...
376
 
423
;        test    [ebx + SOCKET.options], SO_ACCEPTCON
Line 377... Line 424...
377
  .no_syn:
424
;        jnz     .listening_socket                       ;;;;; TODO
378
 
425
 
Line -... Line 426...
-
 
426
;-------------------------------------
-
 
427
; Reset idle timer and keepalive timer
Line 379... Line 428...
379
;-----------------------------------
428
 
-
 
429
	mov	[ebx + TCP_SOCKET.t_idle], 0
-
 
430
	mov	[ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
Line -... Line 431...
-
 
431
 
-
 
432
;--------------------
Line 380... Line 433...
380
; Is this socket a listening socket?
433
; Process TCP options
381
 
434
 
Line 382... Line 435...
382
; If so, create a new socket
435
	cmp	esi, 20 			; esi is headersize
-
 
436
	je	.no_options
Line -... Line 437...
-
 
437
 
-
 
438
	DEBUGF	1,"Segment has options\n"
-
 
439
 
-
 
440
	test	[ebx + TCP_SOCKET.t_state], TCB_LISTEN		; no options when in listen state
-
 
441
	jz	.no_options
-
 
442
 
-
 
443
	lea	edi, [edx + TCP_segment.Data]
-
 
444
	lea	eax, [edx + esi]
-
 
445
 
-
 
446
  .opt_loop:
-
 
447
	cmp	edi, eax
-
 
448
	jge	.no_options
-
 
449
 
-
 
450
	cmp	byte [edi], TCP_OPT_EOL 	; end of option list?
-
 
451
	jz	.no_options
-
 
452
 
383
 
453
	cmp	byte [edi], TCP_OPT_NOP 	; nop ?
-
 
454
	jz	.opt_nop
-
 
455
 
-
 
456
	cmp	byte [edi], TCP_OPT_MAXSEG
-
 
457
	je	.opt_maxseg
-
 
458
 
-
 
459
	cmp	byte [edi], TCP_OPT_WINDOW
-
 
460
	je	.opt_window
-
 
461
 
Line 384... Line -...
384
	test	[ebx + SOCKET.options], SO_ACCEPTCON
-
 
385
	jz	.no_accept_conn
-
 
Line -... Line 462...
-
 
462
	cmp	byte [edi], TCP_OPT_TIMESTAMP
386
 
463
	je	.opt_timestamp
387
 
464
 
Line 388... Line 465...
388
		; TODO: create a new socket
465
	jmp	.no_options	; If we reach here, some unknown options were received, skip them all!
-
 
466
 
Line -... Line 467...
-
 
467
  .opt_nop:
-
 
468
	inc	edi
-
 
469
	jmp	.opt_loop
-
 
470
 
-
 
471
  .opt_maxseg:
-
 
472
	cmp	byte [edi+1], 4
-
 
473
	jne	.no_options		; error occured, ignore all options!
-
 
474
 
-
 
475
	test	[edx + TCP_segment.Flags], TH_SYN
-
 
476
	jz	@f
-
 
477
 
-
 
478
	DEBUGF	1,"Got maxseg option"
-
 
479
 
-
 
480
	;;;;;
-
 
481
       @@:
-
 
482
	add	edi, 4
-
 
483
	jmp	.opt_loop
-
 
484
 
-
 
485
 
389
 
486
  .opt_window:
Line 390... Line 487...
390
 
487
	cmp	byte [edi+1], 3
391
  .no_accept_conn:
488
	jne	.no_options
Line 392... Line -...
392
 
-
 
393
;----------------------------
489
 
394
; Compute window scale factor
490
	test	[edx + TCP_segment.Flags], TH_SYN
395
 
491
	jz	@f
396
 
492
 
397
; TODO
493
	DEBUGF	1,"Got window option"
Line 428... Line 524...
428
;      In this case we'll free the ACK'ed data and notify higher levels that we have free space in buffer
524
;      In this case we'll free the ACK'ed data and notify higher levels that we have free space in buffer
429
;
525
;
430
;  -  If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer.
526
;  -  If the length is not 0 and the ACK didn't move, we're the receiver side of the transfer.
431
;      If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK
527
;      If the packets are in order (data queue is empty), add the data to the socket buffer and request a delayed ACK
Line 432... Line 528...
432
 
528
 
433
	cmp	[TCP_SOCKET.t_state], TCB_ESTABLISHED
529
	cmp	[ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
Line 434... Line 530...
434
	jnz	.not_uni_xfer
530
	jnz	.not_uni_xfer
435
 
531
 
Line 436... Line 532...
436
	test	[TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
532
	test	[edx + TCP_segment.Flags], TH_SYN + TH_FIN + TH_RST + TH_URG
437
	jnz	.not_uni_xfer
533
	jnz	.not_uni_xfer
Line 438... Line 534...
438
 
534
 
439
	test	[TCP_segment.Flags], TH_ACK
535
	test	[edx + TCP_segment.Flags], TH_ACK
440
	jz	.not_uni_xfer
536
	jz	.not_uni_xfer
Line 441... Line 537...
441
 
537
 
442
	mov	eax, [edx + TCP_segment.SequenceNumber]
538
	mov	eax, [edx + TCP_segment.SequenceNumber]
443
	cmp	eax, [ebx + TCP_SOCKET.RCV_NXT]
539
	cmp	eax, [ebx + TCP_SOCKET.RCV_NXT]
Line 444... Line 540...
444
	jne	.not_uni_xfer
540
	jne	.not_uni_xfer
445
 
541
 
446
	movzx	eax, [edx + TCP_segment.Window] ;;;;;
542
	movzx	eax, [edx + TCP_segment.Window] ;;;;; (should use pre-calculated value isntead: todo: figure out where to store it)
Line 447... Line -...
447
	cmp	eax, [ebx + TCP_SOCKET.SND_WND]
-
 
448
	jne	.not_uni_xfer
-
 
449
 
-
 
450
	mov	eax, [ebx + TCP_SOCKET.SND_NXT]
-
 
451
	cmp	eax, [ebx + TCP_SOCKET.SND_MAX]
-
 
452
	jne	.not_uni_xfer
-
 
453
 
-
 
454
;-------------------------------------------------------------------------------
-
 
455
; If last ACK falls within this segment's sequence number, record the timestamp.
543
	cmp	eax, [ebx + TCP_SOCKET.SND_WND]
456
 
544
	jne	.not_uni_xfer
Line 457... Line 545...
457
	; TODO: check if it has a timestamp
545
 
458
 
546
	mov	eax, [ebx + TCP_SOCKET.SND_NXT]
459
 
547
	cmp	eax, [ebx + TCP_SOCKET.SND_MAX]
460
 
-
 
461
 
-
 
462
;---------------------------------------
-
 
463
; check if we are sender in the uni-xfer
-
 
464
 
548
	jne	.not_uni_xfer
465
; If the following 4 conditions are all true, this segment is a pure ACK.
549
 
Line 466... Line -...
466
;
-
 
467
; - The segment contains no data (ti_len is 0).
-
 
468
 
-
 
469
	movzx	eax, [edx + TCP_segment.DataOffset]
-
 
470
	and	eax, 11110000b
-
 
471
	shr	eax, 2
-
 
472
	sub	ecx, eax
-
 
473
	jnz	.not_sender
-
 
474
 
-
 
475
; - The acknowledgment field in the segment (ti_ack) is greater than the largest unacknowledged sequence number (snd_una).
-
 
476
;     Since this test is "greater than" and not "greater than or equal to," it is true only if some positive amount of data is acknowledged by the ACK.
-
 
477
 
-
 
478
	mov	eax, [edx + TCP_segment.AckNumber]
-
 
479
	cmp	eax, [ebx + TCP_SOCKET.SND_UNA]
550
;---------------------------------------
480
	jle	.not_uni_xfer
551
; check if we are sender in the uni-xfer
481
 
-
 
482
; - The acknowledgment field in the segment (ti_ack) is less than or equal to the maximum sequence number sent (snd_max).
552
 
483
 
553
; If the following 4 conditions are all true, this segment is a pure ACK.
484
;        mov     eax, [edx + TCP_segment.Ack]
554
;
Line -... Line 555...
-
 
555
; - The segment contains no data.
-
 
556
	test	ecx, ecx
-
 
557
	jnz	.not_sender
-
 
558
 
-
 
559
; - The congestion window is greater than or equal to the current send window.
-
 
560
;     This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance.
-
 
561
	mov	eax, [ebx + TCP_SOCKET.SND_CWND]
-
 
562
	cmp	eax, [ebx + TCP_SOCKET.SND_WND]
-
 
563
	jl	.not_uni_xfer
485
	cmp	eax, [ebx + TCP_SOCKET.SND_MAX]
564
 
Line 486... Line 565...
486
	jg	.not_uni_xfer
565
; - The acknowledgment field in the segment is less than or equal to the maximum sequence number sent.
487
 
566
	mov	ecx, [edx + TCP_segment.AckNumber]
Line 488... Line 567...
488
; - The congestion window (snd_cwnd) is greater than or equal to the current send window (snd_wnd).
567
	cmp	ecx, [ebx + TCP_SOCKET.SND_MAX]
Line 489... Line 568...
489
;     This test is true only if the window is fully open, that is, the connection is not in the middle of slow start or congestion avoidance.
568
	jg	.not_uni_xfer
-
 
569
 
-
 
570
; - The acknowledgment field in the segment is greater than the largest unacknowledged sequence number.
-
 
571
	sub	ecx, [ebx + TCP_SOCKET.SND_UNA]
-
 
572
	jle	.not_uni_xfer
Line 490... Line 573...
490
 
573
 
491
	mov	eax, [ebx + TCP_SOCKET.SND_CWND]
574
	DEBUGF	1,"Header prediction: we are sender\n"
Line 492... Line 575...
492
	cmp	eax, [ebx + TCP_SOCKET.SND_WND]
575
 
Line 511... Line 594...
511
; Generate more output
594
; Generate more output
512
	call	TCP_output
595
	call	TCP_output
Line 513... Line 596...
513
 
596
 
Line 514... Line -...
514
	jmp	.drop
-
 
515
 
-
 
516
 
-
 
517
 
597
	jmp	.drop
518
 
598
 
Line 519... Line 599...
519
;-------------------------------------------------
599
;-------------------------------------------------
520
; maybe we are the receiver in the uni-xfer then..
600
; maybe we are the receiver in the uni-xfer then..
Line 521... Line -...
521
 
-
 
522
  .not_sender:
601
 
523
; The amount of data in the segment (ti_len) is greater than 0 (data count is in ecx)
602
  .not_sender:
524
 
603
; - The amount of data in the segment is greater than 0 (data count is in ecx)
525
 
604
 
Line 526... Line 605...
526
; The acknowledgment field (ti_ack) equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment.
605
; - The acknowledgment field equals the largest unacknowledged sequence number. This means no data is acknowledged by this segment.
527
	mov	eax, [edx + TCP_segment.AckNumber]
-
 
528
	cmp	eax, [ebx + TCP_SOCKET.SND_UNA]
-
 
Line 529... Line -...
529
	jne	.not_uni_xfer
-
 
530
 
-
 
531
; The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp).
606
	mov	eax, [edx + TCP_segment.AckNumber]
Line 532... Line 607...
532
;;;;
607
	cmp	eax, [ebx + TCP_SOCKET.SND_UNA]
533
	jnz	.not_uni_xfer
608
	jne	.not_uni_xfer
Line 534... Line 609...
534
 
609
 
Line 535... Line -...
535
; There is room in the receive buffer for the data in the segment.
-
 
536
;;;;
-
 
537
	jnz	.not_uni_xfer
-
 
538
 
-
 
539
;-------------------------------------
-
 
540
; Complete processing of received data
610
; - The reassembly list of out-of-order segments for the connection is empty (seg_next equals tp). ;;;;;;;
541
 
611
 
542
	DEBUGF	1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx
612
	jnz	.not_uni_xfer
Line -... Line 613...
-
 
613
 
543
 
614
;-------------------------------------
Line 544... Line 615...
544
; The next expected receive sequence number (rcv_nxt) is incremented by the number of bytes of data.
615
; Complete processing of received data
Line 545... Line -...
545
 
-
 
546
	add	[ebx + TCP_SOCKET.RCV_NXT], ecx
-
 
547
 
-
 
548
; Add the data to the socket buffer
-
 
549
	mov	eax, ebx
616
 
550
	;;; mov...
617
	DEBUGF	1,"header prediction: we are receiver\nreceiving %u bytes of data\n", ecx
Line 551... Line 618...
551
	call	SOCKET_input
618
 
Line 552... Line 619...
552
 
619
	add	esi, edx
Line 553... Line -...
553
; The delayed-ACK flag is set and the input processing is complete.
-
 
554
 
-
 
555
	jmp	.drop
-
 
556
 
-
 
557
 
-
 
558
 
-
 
559
 
-
 
560
 
-
 
561
;----------------------------------------------------
-
 
562
; Header prediction failed, doing it the slow way..
-
 
563
 
-
 
564
  .not_uni_xfer:
620
	lea	eax, [ebx + rcv]
565
 
621
	call	SOCKET_ring_add 			; Add the data to the socket buffer
Line 566... Line 622...
566
	DEBUGF	1,"Header prediction failed\n"
622
 
Line 567... Line -...
567
 
-
 
568
;------------------------
623
	add	[ebx + TCP_SOCKET.RCV_NXT], ecx 	; Update sequence number with number of bytes we have copied
569
; calculate header length                               ;;;;; we already calculated this before!
624
	or	[ebx + TCP_SOCKET.t_flags], TF_DELACK	; Set delayed ack flag
Line 570... Line 625...
570
	movzx	eax, [edx + TCP_segment.DataOffset]
625
 
Line 571... Line 626...
571
	and	eax, 0xf0
626
	jmp	.drop
572
	shr	eax, 2
627
 
Line 573... Line 628...
573
 
628
;----------------------------------------------------
574
; Update edx to point to data..
629
; Header prediction failed, doing it the slow way..     ;;;;; current implementation of header prediction destroys some regs (ecx) !!
Line 575... Line -...
575
	add	edx, eax
-
 
576
; ..and ecx to give data size
630
 
577
	sub	ecx, eax
631
  .not_uni_xfer:
Line 578... Line -...
578
 
-
 
579
;------------------------------
632
 
Line 580... Line 633...
580
; Calculate receive window size
633
	DEBUGF	1,"Header prediction failed\n"
Line 581... Line 634...
581
 
634
 
Line 582... Line 635...
582
	;;;;
635
;------------------------------
Line 583... Line 636...
583
 
636
; Calculate receive window size
Line -... Line 637...
-
 
637
 
-
 
638
	;;;;
-
 
639
 
584
 
640
;-------------------------
585
;-------------------------
641
; TCP slow input procedure
Line 586... Line 642...
586
; TCP slow input procedure
642
 
Line 620... Line 676...
620
	jnz	.drop_with_reset
676
	jnz	.drop_with_reset
Line 621... Line 677...
621
 
677
 
622
	test	[edx + TCP_segment.Flags], TH_SYN
678
	test	[edx + TCP_segment.Flags], TH_SYN
Line -... Line 679...
-
 
679
	jz	.drop
623
	jz	.drop
680
 
Line 624... Line 681...
624
 
681
	; TODO: find sender ip address somewhere!
-
 
682
	; TODO: check if it's a broadcast or multicast, and drop if so
Line -... Line 683...
-
 
683
 
625
	; TODO: check if it's a broadcast or multicast, and drop if so
684
	call	SOCKET_fork
Line 626... Line -...
626
 
-
 
627
;;; 28.6
-
 
628
 
-
 
629
	; create a new socket and fill in the nescessary variables
-
 
630
 
-
 
631
;; Exit if backlog queue is full
-
 
632
;        mov     ax, [ebx + TCP_SOCKET.backlog_cur]
-
 
633
;        cmp     ax, [ebx + TCP_SOCKET.backlog]
-
 
634
;        jae     .exit
-
 
635
 
-
 
636
; Allocate new socket
-
 
637
	call	SOCKET_alloc
-
 
638
     ;;;   jz      .fail
685
	jz	.drop		; if we could not open a new connection, drop segment (;;;; should we send RST too?)
639
 
-
 
640
; Copy structure from current socket to new, (including lock!)
-
 
Line 641... Line 686...
641
; We start at PID to reserve the socket num, and the 2 pointers at beginning of socket
686
 
642
	lea	esi, [edx + SOCKET.PID]
-
 
643
	lea	edi, [eax + SOCKET.PID]
687
;-----------------------
644
	mov	ecx, (TCP_SOCKET.end - SOCKET.PID + 3)/4
-
 
Line 645... Line 688...
645
	rep	movsd
688
; Fill in some variables
-
 
689
 
Line 646... Line 690...
646
 
690
	add	[TCP_sequence_num], 64000
647
;; Push pointer to new socket to queue
691
 
Line 648... Line 692...
648
;        movzx   ecx, [ebx + TCP_SOCKET.backlog_cur]
692
	push	[edx + TCP_segment.SourcePort]
649
;        inc     [ebx + TCP_SOCKET.backlog_cur]
693
	pop	[eax + TCP_SOCKET.RemotePort]
-
 
694
 
Line 650... Line 695...
650
;        mov     [ebx + TCP_SOCKET.end + ecx*4], eax
695
	push	[edx + TCP_segment.SequenceNumber]
651
 
-
 
Line 652... Line 696...
652
	mov	[eax + IP_SOCKET.RemoteIP], esi ; IP source address
696
	pop	[eax + TCP_SOCKET.IRS]
Line -... Line 697...
-
 
697
 
-
 
698
	push	[eax + TCP_SOCKET.ISS]
Line 653... Line 699...
653
 
699
	pop	[eax + TCP_SOCKET.SND_NXT]
654
	mov	cx, [edx + TCP_segment.SourcePort]
700
 
Line 655... Line 701...
655
	mov	[eax + TCP_SOCKET.RemotePort], cx
701
	mov	[eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED
Line 674... Line 720...
674
 
720
 
675
	mov	eax, [edx + TCP_segment.AckNumber]
721
	mov	eax, [edx + TCP_segment.AckNumber]
676
	cmp	eax, [ebx + TCP_SOCKET.ISS]
722
	cmp	eax, [ebx + TCP_SOCKET.ISS]
Line 677... Line -...
677
	jle	.drop_with_reset
-
 
678
 
723
	jle	.drop_with_reset
679
	mov	eax, [edx + TCP_segment.AckNumber]
-
 
680
	cmp	eax, [ebx + TCP_SOCKET.SND_MAX]
-
 
Line -... Line 724...
-
 
724
 
-
 
725
	DEBUGF	1,"snd_max = %x\n", [ebx + TCP_SOCKET.SND_MAX]	 ;;; TODO: set this, but where?
-
 
726
 
-
 
727
;        mov     eax, [edx + TCP_segment.AckNumber]
Line 681... Line 728...
681
	jg	.drop_with_reset
728
;;        cmp     eax, [ebx + TCP_SOCKET.SND_MAX]
682
       @@:
729
;;        jg      .drop_with_reset
Line 683... Line 730...
683
 
730
       @@:
Line 694... Line 741...
694
       @@:
741
       @@:
Line 695... Line 742...
695
 
742
 
696
	test	[edx + TCP_segment.Flags], TH_SYN
743
	test	[edx + TCP_segment.Flags], TH_SYN
Line 697... Line 744...
697
	jz	.drop
744
	jz	.drop
-
 
745
 
698
 
746
; at this point, segment seems to be valid
699
; now, process received SYN in response to an active open
747
 
-
 
748
	test	[edx + TCP_segment.Flags], TH_ACK
-
 
749
	jz	.no_syn_ack
Line 700... Line 750...
700
	test	[edx + TCP_segment.Flags], TH_ACK
750
 
701
	jz	@f
751
; now, process received SYN in response to an active open
702
 
-
 
703
	mov	eax, [edx + TCP_segment.AckNumber]
-
 
704
	mov	[ebx + TCP_SOCKET.SND_UNA], eax
752
 
705
 
753
	mov	eax, [edx + TCP_segment.AckNumber]
706
	mov	eax, [ebx + TCP_SOCKET.SND_UNA]
754
	mov	[ebx + TCP_SOCKET.SND_UNA], eax
-
 
755
	cmp	eax, [ebx + TCP_SOCKET.SND_NXT]
Line 707... Line -...
707
	cmp	eax, [ebx + TCP_SOCKET.SND_NXT]
-
 
708
	jle	@f
756
	jle	@f
Line -... Line 757...
-
 
757
	mov	[ebx + TCP_SOCKET.SND_NXT], eax
-
 
758
       @@:
709
	mov	[ebx + TCP_SOCKET.SND_NXT], eax
759
 
710
 
760
  .no_syn_ack:
-
 
761
 
-
 
762
	mov	[ebx + TCP_SOCKET.timer_retransmission], 0	; disable retransmission
-
 
763
 
-
 
764
	push	[edx + TCP_segment.SequenceNumber]
-
 
765
	pop	[ebx + TCP_SOCKET.IRS]
-
 
766
 
-
 
767
;;; TODO: tcp_rcvseqinit
-
 
768
 
-
 
769
	mov	[ebx + TCP_SOCKET.t_flags], TF_ACKNOW
-
 
770
 
-
 
771
	mov	eax, [ebx + TCP_SOCKET.SND_UNA]
-
 
772
	cmp	eax, [ebx + TCP_SOCKET.ISS]
-
 
773
	jle	.simultaneous_open
Line -... Line 774...
-
 
774
 
711
	mov	[ebx + TCP_SOCKET.timer_keepalive], TCP_time_keep_interval
775
	test	[edx + TCP_segment.Flags], TH_ACK
Line 712... Line 776...
712
	mov	[ebx + TCP_SOCKET.timer_retransmission], 0
776
	jz	.simultaneous_open
Line 713... Line 777...
713
 
777
 
714
	mov	eax, [edx + TCP_segment.SequenceNumber]
778
	DEBUGF	1,"TCP: active open\n"
Line -... Line 779...
-
 
779
 
Line 715... Line 780...
715
	mov	[ebx + TCP_SOCKET.IRS], eax
780
; TODO: update stats
Line -... Line 781...
-
 
781
; TODO: set socket state to connected
716
 
782
 
717
; TODO: set socket state to connected
783
	mov	[ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
Line 718... Line 784...
718
 
784
 
719
	mov	[ebx + TCP_SOCKET.t_state], TCB_ESTABLISHED
785
; TODO: check if we should scale the connection (567-572)
Line 742... Line 808...
742
	; TODO: 592
808
	; TODO: 592
743
	mov	cx, [ebx + TCP_SOCKET.RCV_WND]
809
	mov	cx, [ebx + TCP_SOCKET.RCV_WND]
744
	; TODO...
810
	; TODO...
745
       @@:
811
       @@:
746
	;;;;;
812
	;;;;;
747
	;;; jmp     .step6
813
	jmp	.step6
Line 748... Line -...
748
 
-
 
749
 
814
 
Line 750... Line 815...
750
 
815
 
Line 751... Line 816...
751
 
816
 
752
 
817
 
Line 753... Line 818...
753
align 4
818
 
Line 781... Line 846...
781
	and	[edx + TCP_segment.Flags], not (TH_URG)
846
	and	[edx + TCP_segment.Flags], not (TH_URG)
782
	dec	eax
847
	dec	eax
Line 783... Line 848...
783
 
848
 
Line 784... Line 849...
784
  .no_drop:
849
  .no_drop:
Line -... Line 850...
-
 
850
 
Line 785... Line 851...
785
 
851
	DEBUGF	1,"Going to drop %u bytes of data", eax
786
; eax holds number of bytes to drop
852
 
Line 787... Line 853...
787
 
853
; eax holds number of bytes to drop
788
 
854
 
Line 789... Line 855...
789
;----------------------------------
855
;----------------------------------
Line 790... Line -...
790
; Check for entire duplicate packet
-
 
791
 
-
 
792
	cmp	eax, ecx
-
 
793
	jge	.duplicate
-
 
794
 
-
 
795
	;;; TODO: figure 28.30
856
; Check for entire duplicate packet
796
 
857
 
Line 797... Line 858...
797
;;        inc     [TCP_segments_rx]
858
	cmp	eax, ecx
798
 
859
	jge	.duplicate
Line 809... Line 870...
809
	dec	ecx
870
	dec	ecx
810
	jne	@f
871
	jne	@f
Line 811... Line 872...
811
 
872
 
812
	mov	eax, ecx
873
	mov	eax, ecx
813
	and	[edx + TCP_segment.Flags], not TH_FIN
874
	and	[edx + TCP_segment.Flags], not TH_FIN
814
	;;; TODO: set ACKNOW flag
-
 
815
 
875
	or	[ebx + TCP_SOCKET.t_flags], TF_ACKNOW
816
	jmp	.no_duplicate
876
	jmp	.no_duplicate
Line 817... Line 877...
817
       @@:
877
       @@:
818
 
878
 
Line 819... Line -...
819
	; Handle the case when a bound socket connects to itself
-
 
820
	; Allow packets with a SYN and an ACKto continue with the processing
879
	; Handle the case when a bound socket connects to itself
821
 
880
	; Allow packets with a SYN and an ACKto continue with the processing
Line 822... Line 881...
822
 
881
 
Line 831... Line 890...
831
	cmp	[edx + TCP_segment.Flags], TH_ACK
890
	cmp	[edx + TCP_segment.Flags], TH_ACK
832
	jz	.drop_after_ack
891
	jz	.drop_after_ack
Line 833... Line 892...
833
 
892
 
Line -... Line 893...
-
 
893
  .duplicate:
-
 
894
 
834
  .duplicate:
895
	DEBUGF	1,"Duplicate received"
835
 
896
 
Line 836... Line 897...
836
;----------------------------------------
897
;----------------------------------------
Line 837... Line 898...
837
; Update statistics for duplicate packets
898
; Update statistics for duplicate packets
Line 838... Line 899...
838
 
899
 
Line 839... Line 900...
839
	;;; TODO
900
	;;; TODO
840
 
901
 
Line 896... Line 957...
896
 
957
 
Line 897... Line 958...
897
  .dont_drop_all:
958
  .dont_drop_all:
Line 898... Line -...
898
 
-
 
899
  .no_excess_data:
959
 
900
 
960
  .no_excess_data:
Line 901... Line 961...
901
 
961
 
Line 908... Line 968...
908
; Process RST flags
968
; Process RST flags
Line 909... Line 969...
909
 
969
 
910
	test	[edx + TCP_segment.Flags], TH_RST
970
	test	[edx + TCP_segment.Flags], TH_RST
Line -... Line 971...
-
 
971
	jz	.rst_skip
-
 
972
 
911
	jz	.rst_skip
973
	DEBUGF	1,"Got an RST flag"
912
 
974
 
913
	mov	eax, [ebx + TCP_SOCKET.t_state]
975
	mov	eax, [ebx + TCP_SOCKET.t_state]
Line 914... Line 976...
914
	shl	eax, 2
976
	shl	eax, 2
Line 927... Line 989...
927
	dd	.econnreset	;TCB_FIN_WAIT_2
989
	dd	.econnreset	;TCB_FIN_WAIT_2
928
	dd	.rst_close	;TCB_TIMED_WAIT
990
	dd	.rst_close	;TCB_TIMED_WAIT
Line 929... Line 991...
929
 
991
 
Line -... Line 992...
-
 
992
  .econnrefused:
-
 
993
 
930
  .econnrefused:
994
	DEBUGF	1,"Connection refused"
Line 931... Line 995...
931
 
995
 
Line 932... Line 996...
932
	;;; TODO: debug info
996
	;;; TODO: debug info
Line -... Line 997...
-
 
997
 
-
 
998
	jmp	.close
933
 
999
 
934
	jmp	.close
1000
  .econnreset:
Line -... Line 1001...
-
 
1001
 
-
 
1002
	DEBUGF	1,"Connection reset"
935
 
1003
 
Line 936... Line 1004...
936
  .econnreset:
1004
	;;; TODO: debug info
Line -... Line 1005...
-
 
1005
  .close:
-
 
1006
 
937
 
1007
	DEBUGF	1,"Closing connection"
938
	;;; TODO: debug info
1008
 
Line 939... Line 1009...
939
    .close:
1009
	;;; update stats
Line 1004... Line 1074...
1004
 
1074
 
1005
 
1075
 
Line -... Line 1076...
-
 
1076
;------------------------------------------
1006
;------------------------------------------
1077
; Remove acknowledged data from send buffer
-
 
1078
 
Line 1007... Line 1079...
1007
; Remove acknowledged data from send buffer
1079
	lea	eax, [ebx + snd]
1008
 
1080
	mov	ecx, ecx		;;;; 943 - 956
Line 1009... Line 1081...
1009
	;;;; 943 - 956
1081
	call	SOCKET_ring_free
-
 
1082
 
Line 1010... Line 1083...
1010
 
1083
;---------------------------------------
1011
;---------------------------------------
1084
; Wake up process waiting on send buffer
1012
; Wake up process waiting on send buffer
1085
 
Line 1101... Line 1174...
1101
 
1174
 
Line 1102... Line 1175...
1102
	;;; needoutput = 1
1175
	;;; needoutput = 1
Line 1103... Line -...
1103
 
-
 
1104
  .no_window_update:
1176
 
1105
 
1177
  .no_window_update:
Line 1106... Line 1178...
1106
 
1178
 
1107
;-----------------
1179
;-----------------
Line 1119... Line 1191...
1119
; Ignore bogus urgent offsets
1191
; Ignore bogus urgent offsets
Line 1120... Line 1192...
1120
 
1192
 
Line 1121... Line 1193...
1121
	;;; 1040-1050
1193
	;;; 1040-1050
1122
 
1194
 
1123
	movzx	eax, [edx + TCP_segment.UrgentPointer]
1195
	movzx	eax, [edx + TCP_segment.UrgentPointer]
1124
	add	eax, [ebx + SOCKET.SO_RCV.SB_CC]
1196
	add	eax, [ebx + rcv.size]
Line 1125... Line 1197...
1125
	cmp	eax, SOCKET_MAXDATA
1197
	cmp	eax, SOCKET_MAXDATA
1126
	jle	.not_urgent
1198
	jle	.not_urgent
Line 1132... Line 1204...
1132
  .not_urgent:
1204
  .not_urgent:
Line 1133... Line 1205...
1133
 
1205
 
1134
;--------------------------------------
1206
;--------------------------------------
Line 1135... Line 1207...
1135
; processing of received urgent pointer
1207
; processing of received urgent pointer
Line 1136... Line 1208...
1136
 
1208
 
1137
	;;; 1051-1093
1209
	;;; TODO (1051-1093)
Line 1138... Line 1210...
1138
 
1210
 
Line 1139... Line 1211...
1139
align 4
1211
;--------------------------------
Line 1140... Line 1212...
1140
.do_data:
1212
; process the data in the segment
1141
 
1213
 
Line 1142... Line 1214...
1142
	DEBUGF	1,"Do data:\n"
1214
  .do_data:
1143
 
1215
 
Line 1144... Line 1216...
1144
	; process the data in the segment
1216
	DEBUGF	1,"TCP: do data:\n"
Line 1145... Line 1217...
1145
 
1217
 
Line 1156... Line 1228...
1156
	jmp	.final_processing
1228
	jmp	.final_processing
Line 1157... Line 1229...
1157
 
1229
 
Line 1158... Line -...
1158
 
-
 
1159
  .dont_do_data:
1230
 
1160
 
1231
  .dont_do_data:
Line 1161... Line 1232...
1161
 
1232
 
Line 1207... Line 1278...
1207
 
1278
 
1208
	;test    ;;;needoutput = 1
1279
	;test    ;;;needoutput = 1
Line 1209... Line 1280...
1209
	;jnz     .outputnow
1280
	;jnz     .outputnow
-
 
1281
 
-
 
1282
	test	[ebx + TCP_SOCKET.t_flags], TF_ACKNOW
-
 
1283
	jnz	.ack_now
-
 
1284
 
-
 
1285
	mov	[ebx + SOCKET.lock], 0
1210
 
1286
	call	kernel_free
-
 
1287
	add	esp, 4
-
 
1288
	ret
-
 
1289
 
-
 
1290
  .ack_now:
Line -... Line 1291...
-
 
1291
 
1211
	test	[ebx + TCP_SOCKET.t_flags], TF_ACKNOW
1292
	DEBUGF	1,"ACK now!\n"
1212
	jz	.ret
1293
 
-
 
1294
	push	ebx
Line 1213... Line -...
1213
 
-
 
1214
  .outputnow:
1295
	mov	eax, ebx
1215
	call	TCP_output
-
 
1216
 
1296
	call	TCP_output
-
 
1297
	pop	ebx
1217
  .ret:
1298
 
Line 1218... Line 1299...
1218
	mov	[ebx + SOCKET.lock], 0
1299
	mov	[ebx + SOCKET.lock], 0
1219
 
1300
	call	kernel_free
Line 1220... Line 1301...
1220
	call	kernel_free
1301
	add	esp, 4
Line 1231... Line 1312...
1231
	test	[edx + TCP_segment.Flags], TH_RST
1312
	test	[edx + TCP_segment.Flags], TH_RST
1232
	jnz	.drop
1313
	jnz	.drop
Line 1233... Line 1314...
1233
 
1314
 
Line -... Line 1315...
-
 
1315
	and	[ebx + TCP_SOCKET.t_flags], TF_ACKNOW
-
 
1316
 
1234
	and	[ebx + TCP_SOCKET.t_flags], TF_ACKNOW
1317
	push	ebx
-
 
1318
	mov	eax, ebx
Line 1235... Line 1319...
1235
 
1319
	call	TCP_output
1236
	call	TCP_output
-
 
1237
 
1320
	pop	ebx
-
 
1321
 
1238
	mov	[ebx + SOCKET.lock], 0
1322
	mov	[ebx + SOCKET.lock], 0
Line 1239... Line 1323...
1239
 
1323
	call	kernel_free
1240
	call	kernel_free
1324
	add	esp, 4
Line 1259... Line 1343...
1259
 
1343
 
1260
	test	[edx + TCP_segment.Flags], TH_SYN
1344
	test	[edx + TCP_segment.Flags], TH_SYN
Line 1261... Line 1345...
1261
	jnz	.respond_syn
1345
	jnz	.respond_syn
1262
 
-
 
1263
	mov	[ebx + SOCKET.lock], 0
1346
 
-
 
1347
	mov	[ebx + SOCKET.lock], 0
1264
 
1348
	call	kernel_free
Line 1265... Line 1349...
1265
	call	kernel_free
1349
	add	esp, 4
Line 1266... Line 1350...
1266
	ret	4
1350
	ret
Line 1267... Line 1351...
1267
 
1351
 
Line 1268... Line 1352...
1268
  .respond_ack:
1352
  .respond_ack:
Line 1269... Line 1353...
1269
 
1353
 
Line 1270... Line 1354...
1270
	;;;;
1354
	;;;;
Line 1271... Line 1355...
1271
 
1355
 
Line 1272... Line 1356...
1272
	call	TCP_respond
1356
	call	TCP_respond_segment
Line 1273... Line 1357...
1273
 
1357
 
1274
	jmp	.destroy_new_socket
1358
	jmp	.destroy_new_socket
Line 1295... Line 1379...
1295
  .destroy_new_socket:
1379
  .destroy_new_socket:
Line 1296... Line 1380...
1296
 
1380
 
Line 1297... Line 1381...
1297
	;;;; kill the newly created socket
1381
	;;;; kill the newly created socket
1298
 
-
 
1299
	mov	[ebx + SOCKET.lock], 0
1382
 
1300
 
-
 
1301
	call	kernel_free
-
 
1302
	ret	4
-
 
1303
 
-
 
1304
 
-
 
1305
 
-
 
1306
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 
1307
 
-
 
1308
 
-
 
1309
 
-
 
1310
;---------------------
-
 
1311
;
-
 
1312
; TCP_do_options
-
 
1313
;
-
 
1314
;-------------------
-
 
1315
 
-
 
1316
align 4
-
 
1317
TCP_do_options:
-
 
1318
 
-
 
1319
	DEBUGF	1,"TCP_do_options\n"
-
 
1320
 
1383
	mov	[ebx + SOCKET.lock], 0
1321
	push	eax
-
 
1322
	sub	eax, 20
-
 
1323
	jz	.no_options
-
 
1324
 
-
 
1325
	lea	esi, [edx + TCP_segment.Data]
-
 
1326
 
-
 
1327
 
-
 
1328
;-------------------------------------------
-
 
1329
; Begin the loop by checking for EOL and NOP
-
 
1330
 
-
 
1331
  .loop:
-
 
1332
 
-
 
1333
	cmp	byte [esi], TCP_OPT_EOL 	; end of option list?
-
 
1334
	jz	.no_options
-
 
1335
 
-
 
1336
	cmp	byte [esi], TCP_OPT_NOP 	; nop ?
-
 
1337
      ;;;  cmove   edi, 1                          ; if so, set option size to 1
-
 
1338
	jz	.continue			; and continue scanning
-
 
1339
 
-
 
1340
;------------------
-
 
1341
; We have an option
-
 
1342
 
-
 
1343
	movzx	edi, byte [esi + 1]		; get the length of this option in edi
-
 
1344
 
-
 
1345
 
-
 
1346
;--------------------------------------
-
 
1347
; Check for Maximum segment size option
-
 
1348
 
-
 
1349
	cmp	byte [esi], TCP_OPT_MAXSEG
-
 
1350
	jne	.no_maxseg
-
 
1351
 
-
 
1352
	cmp	edi, 4	; option length
-
 
1353
	jne	.continue
-
 
1354
 
-
 
1355
	test	[edx + TCP_segment.Flags], TH_SYN
-
 
1356
	jz	.continue
-
 
1357
 
-
 
1358
	; Now parse the option...
-
 
1359
 
-
 
1360
	jmp	.continue
-
 
1361
 
-
 
1362
  .no_maxseg:
-
 
1363
 
-
 
1364
;------------------------
1384
	call	kernel_free
1365
; Check for Window option
-
 
1366
 
-
 
Line 1367... Line -...
1367
	cmp	byte [esi], TCP_OPT_WINDOW
-
 
1368
	jne	.no_window
-
 
Line 1369... Line -...
1369
 
-
 
1370
	cmp	edi, 3 ; option length
-
 
1371
	jne	.continue
-
 
1372
 
-
 
1373
	test	[edx + TCP_segment.Flags], TH_SYN
-
 
1374
	jz	.continue
-
 
1375
 
-
 
1376
	; ...
-
 
1377
 
-
 
1378
	jmp	.continue
-
 
1379
 
-
 
1380
  .no_window:
-
 
1381
 
-
 
1382
;---------------------------
-
 
1383
; Check for Timestamp option
-
 
1384
 
-
 
1385
	cmp	byte [esi], TCP_OPT_TIMESTAMP
-
 
1386
	jne	.no_timestamp
-
 
1387
 
-
 
1388
	cmp	edi, 10 ; option length
-
 
1389
	jne	.continue
-
 
1390
 
-
 
1391
	; ...
-
 
1392
 
-
 
1393
 
-
 
1394
	jmp	.continue
-
 
1395
 
-
 
1396
  .no_timestamp:
-
 
1397
 
-
 
1398
;----------------------------------
-
 
1399
; Future options may be placed here
-
 
1400
 
-
 
1401
 
-
 
1402
 
-
 
1403
 
-
 
1404
;------------------------------
-
 
1405
; Continue scanning for options
-
 
1406
 
-
 
1407
  .continue:
-
 
1408
	add	esi, edi
-
 
1409
	sub	eax, edi
-
 
1410
	jg	.loop
-
 
1411
 
-
 
1412
  .no_options:
-
 
Line 1413... Line 1385...
1413
 
1385
	add	esp, 4
Line 1439... Line 1411...
1439
 
1411
 
Line 1440... Line -...
1440
	ret
-
 
1441
 
-
 
1442
 
-
 
1443
 
-
 
1444
 
-
 
1445
 
-
 
1446
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 
1447
 
-
 
1448
 
1412
	ret
1449
 
1413
 
1450
 
1414
 
1451
 
1415
 
1452
;-----------------------------------------------------------------
1416
;-----------------------------------------------------------------
Line 1492... Line 1456...
1492
	cmp	ecx, [eax + TCP_SOCKET.SND_CWND]	;
1456
	cmp	ecx, [eax + TCP_SOCKET.SND_CWND]	;
1493
	jl	@f					;
1457
	jl	@f					;
1494
	mov	ecx, [eax + TCP_SOCKET.SND_CWND]	;
1458
	mov	ecx, [eax + TCP_SOCKET.SND_CWND]	;
1495
       @@:						;
1459
       @@:						;
Line 1496... Line 1460...
1496
 
1460
 
Line 1497... Line 1461...
1497
	call	TCP_outflags
1461
	call	TCP_outflags	; in dl
1498
 
1462
 
1499
; If in persist timeout with window of 0, send 1 byte.
1463
; If in persist timeout with window of 0, send 1 byte.
Line 1504... Line 1468...
1504
	jz	.no_persist_timeout
1468
	jz	.no_persist_timeout
Line 1505... Line 1469...
1505
 
1469
 
1506
	test	ecx, ecx
1470
	test	ecx, ecx
Line 1507... Line 1471...
1507
	jnz	.no_zero_window
1471
	jnz	.no_zero_window
1508
 
1472
 
Line 1509... Line 1473...
1509
	cmp	ebx, [eax + SOCKET.SO_SND.SB_CC]
1473
	cmp	ebx, [eax + snd.size]
Line 1510... Line 1474...
1510
	jge	@f
1474
	jge	@f
1511
 
1475
 
1512
	and	dl, not (TH_FIN)	  ; clear the FIN flag    ??? how can it be set before?
1476
	and	dl, not (TH_FIN)	  ; clear the FIN flag    ??? how can it be set before?
Line 1513... Line 1477...
1513
 
1477
 
Line 1514... Line 1478...
1514
       @@:
1478
       @@:
1515
	inc	ecx
1479
	inc	ecx
Line 1516... Line 1480...
1516
	jmp	.no_persist_timeout
1480
	jmp	.no_persist_timeout
Line 1517... Line 1481...
1517
 
1481
 
Line 1518... Line 1482...
1518
  .no_zero_window:
1482
  .no_zero_window:
1519
 
1483
 
1520
;;;        mov     [eax + TCP_SOCKET.t_timer....TCPT_PERSIST], 0
1484
	mov	[eax + TCP_SOCKET.timer_persist], 0	;;;;
1521
	mov	[eax + TCP_SOCKET.t_rxtshift], 0
1485
	mov	[eax + TCP_SOCKET.t_rxtshift], 0
1522
 
1486
 
1523
  .no_persist_timeout:
1487
  .no_persist_timeout:
Line 1544... Line 1508...
1544
	xor	esi, esi
1508
	xor	esi, esi
Line 1545... Line 1509...
1545
 
1509
 
1546
	test	ecx, ecx
1510
	test	ecx, ecx
Line 1547... Line 1511...
1547
	jnz	@f
1511
	jnz	@f
Line 1548... Line 1512...
1548
 
1512
 
1549
;;;        mov     [eax + TCP_SOCKET.t_timer..TCPT_REXMT], 0
1513
	mov	[eax + TCP_SOCKET.timer_retransmission], 0   ; cancel retransmit
1550
 
1514
 
Line 1567... Line 1531...
1567
;;; 128
1531
;;; 128
Line 1568... Line 1532...
1568
 
1532
 
1569
	mov	edi, [eax + TCP_SOCKET.SND_NXT]
1533
	mov	edi, [eax + TCP_SOCKET.SND_NXT]
1570
	add	edi, esi	; len
1534
	add	edi, esi	; len
1571
	sub	edi, [eax + TCP_SOCKET.SND_UNA]
1535
	sub	edi, [eax + TCP_SOCKET.SND_UNA]
1572
	add	edi, [eax + SOCKET.SO_SND.SB_CC]
1536
	add	edi, [eax + snd.size]
1573
	cmp	edi, 0
1537
	cmp	edi, 0
Line 1574... Line 1538...
1574
	jle	@f
1538
	jle	@f
Line 1575... Line 1539...
1575
 
1539
 
Line 1576... Line 1540...
1576
	and	dl, not (TH_FIN)	  ; clear the FIN flag
1540
	and	dl, not (TH_FIN)	  ; clear the FIN flag
-
 
1541
 
Line -... Line 1542...
-
 
1542
       @@:
-
 
1543
 
Line 1577... Line 1544...
1577
 
1544
 
1578
       @@:
1545
; set ecx to space available in receive buffer
Line 1579... Line -...
1579
 
-
 
1580
 
-
 
1581
;;;; 130 TODO: set window (ecx) to space in send buffer
-
 
1582
 
-
 
1583
 
1546
; From now on, ecx will be the window we advertise to the other end
1584
;------------------------------
1547
 
Line 1585... Line 1548...
1585
; Sender silly window avoidance
1548
	mov	ecx, SOCKET_MAXDATA
Line 1586... Line 1549...
1586
 
1549
	sub	ecx, [eax + rcv.size]
1587
	test	esi, esi
1550
 
Line -... Line 1551...
-
 
1551
;------------------------------
1588
	jz	.zero_length
1552
; Sender silly window avoidance
1589
 
1553
 
1590
 
1554
	cmp	ecx, [eax + TCP_SOCKET.t_maxseg]
1591
	cmp	esi, [eax + TCP_SOCKET.t_maxseg]
1555
	je	.send
-
 
1556
 
-
 
1557
;;; TODO: 144-145
-
 
1558
 
Line 1592... Line 1559...
1592
	je	.send
1559
	test	[eax + TCP_SOCKET.t_force], -1
1593
 
1560
	jnz	.send
Line 1594... Line 1561...
1594
;;; TODO: 144-145
1561
 
1595
 
1562
	mov	ebx, [eax + TCP_SOCKET.max_sndwnd]
Line 1596... Line 1563...
1596
	test	[eax + TCP_SOCKET.t_force], -1
1563
	shr	ebx, 1
Line 1597... Line 1564...
1597
	jnz	.send
1564
	cmp	ecx, ebx
Line 1639... Line 1606...
1639
 
1606
 
Line 1640... Line 1607...
1640
  .enter_persist:
1607
  .enter_persist:
Line 1641... Line -...
1641
 
-
 
1642
	DEBUGF	1,"Entering persist state\n"
-
 
1643
 
1608
 
1644
 
1609
	DEBUGF	1,"Entering persist state\n"
Line 1645... Line 1610...
1645
 
1610
 
Line 1646... Line 1611...
1646
;--------------------------------------
1611
;--------------------------------------
Line 1647... Line -...
1647
; No reason to send a segment, just ret
-
 
1648
 
-
 
1649
	DEBUGF	1,"No reason to send a segment\n"
-
 
1650
 
1612
; No reason to send a segment, just ret
1651
	ret
1613
 
1652
 
1614
	DEBUGF	1,"No reason to send a segment\n"
1653
 
1615
 
1654
 
1616
	ret
1655
 
1617
 
1656
 
1618
 
1657
;-----------------------------------------------
1619
;-----------------------------------------------
Line 1658... Line 1620...
1658
;
1620
;
Line 1659... Line 1621...
1659
; Send a segment
1621
; Send a segment
Line 1660... Line 1622...
1660
;
1622
;
-
 
1623
; eax = socket pointer
-
 
1624
;  dl = flags
-
 
1625
;
Line 1661... Line 1626...
1661
; ebx = socket pointer
1626
;-----------------------------------------------
1662
;  dl = flags
1627
 
Line 1663... Line 1628...
1663
;
1628
  .send:
1664
;-----------------------------------------------
1629
 
Line 1665... Line 1630...
1665
 
1630
	DEBUGF	1,"Preparing to send a segment\n"
1666
.send:
1631
 
Line 1667... Line 1632...
1667
 
1632
	mov	edi, TCP_segment.Data	; edi will contain headersize
1668
	DEBUGF	1,"Preparing to send a segment\n"
1633
 
Line -... Line 1634...
-
 
1634
	sub	esp, 8			; create some space on stack
1669
 
1635
	push	eax			; save this too..
1670
	xor	edi, edi	; edi will contain the number of header option bytes
-
 
1671
 
1636
 
1672
;------------------------------------
1637
;------------------------------------
1673
; Send options with first SYN segment
-
 
1674
 
1638
; Send options with first SYN segment
Line 1675... Line 1639...
1675
	test	dl, TH_SYN
1639
 
1676
	jz	.no_options
1640
	test	dl, TH_SYN
Line 1677... Line 1641...
1677
 
1641
	jz	.no_options
1678
	mov	eax, [ebx + TCP_SOCKET.ISS]
1642
 
Line 1679... Line 1643...
1679
	mov	[ebx + TCP_SOCKET.SND_NXT], eax
1643
	push	[eax + TCP_SOCKET.ISS]
1680
 
1644
	pop	[eax + TCP_SOCKET.SND_NXT]
Line 1681... Line 1645...
1681
	test	[ebx + TCP_SOCKET.t_flags], TF_NOOPT
1645
 
1682
	jnz	.no_options
-
 
1683
 
-
 
1684
	mov	eax, TCP_OPT_MAXSEG shl 24 + 4 shl 16
1646
	test	[eax + TCP_SOCKET.t_flags], TF_NOOPT
-
 
1647
	jnz	.no_options
1685
	mov	 ax, 1280 ;;;;;;
1648
 
1686
	bswap	eax
1649
	mov	ecx, 1460
1687
	push	eax
-
 
1688
 
1650
	or	ecx, TCP_OPT_MAXSEG shl 24 + 4 shl 16
Line 1689... Line 1651...
1689
	mov	di, 4
1651
	bswap	ecx
Line 1690... Line 1652...
1690
 
1652
	push	ecx
1691
	test	[ebx + TCP_SOCKET.t_flags], TF_REQ_SCALE
1653
	add	di, 4
Line 1692... Line 1654...
1692
	jz	.no_syn
1654
 
1693
 
1655
	test	[eax + TCP_SOCKET.t_flags], TF_REQ_SCALE
Line 1694... Line 1656...
1694
	test	dl, TH_ACK
1656
	jz	.no_syn
1695
	jnz	.scale_opt
1657
 
Line 1696... Line 1658...
1696
 
1658
	test	dl, TH_ACK
1697
	test	[ebx + TCP_SOCKET.t_flags], TF_RCVD_SCALE
1659
	jnz	.scale_opt
Line 1698... Line 1660...
1698
	jz	.no_syn
1660
 
1699
 
1661
	test	[eax + TCP_SOCKET.t_flags], TF_RCVD_SCALE
Line 1700... Line 1662...
1700
  .scale_opt:
1662
	jz	.no_syn
1701
 
-
 
1702
	mov	eax, TCP_OPT_WINDOW shl 24 + 4 shl 16 + TCP_OPT_NOP
1663
 
-
 
1664
  .scale_opt:
1703
	mov	 ah, byte [ebx + TCP_SOCKET.request_r_scale]
1665
	movzx	ecx, byte [eax + TCP_SOCKET.request_r_scale]
1704
	bswap	eax
-
 
1705
	push	eax
1666
	or	ecx, TCP_OPT_WINDOW shl 24 + 4 shl 16 + TCP_OPT_NOP shl 8
1706
 
1667
	bswap	ecx
1707
	add	di, 4
-
 
1708
 
-
 
1709
  .no_syn:
-
 
1710
 
1668
	pushd	ecx
Line 1711... Line 1669...
1711
;------------------------------------
1669
	add	di, 4
1712
; Make the timestamp option if needed
-
 
1713
 
1670
 
Line 1714... Line 1671...
1714
	test	[ebx + TCP_SOCKET.t_flags], TF_REQ_TSTMP
1671
  .no_syn:
1715
	jz	.no_timestamp
1672
 
1716
 
-
 
1717
	test	dl, TH_RST
-
 
1718
	jnz	.no_timestamp
-
 
1719
 
-
 
1720
	test	dl, TH_ACK
-
 
1721
	jz	.timestamp
-
 
1722
 
1673
;------------------------------------
1723
	test	[ebx + TCP_SOCKET.t_flags], TF_RCVD_TSTMP
1674
; Make the timestamp option if needed
1724
	jz	.no_timestamp
-
 
1725
 
-
 
1726
  .timestamp:
-
 
1727
 
1675
 
1728
	DEBUGF	1,"Creating a timestamp\n"
-
 
1729
 
-
 
1730
	push	dword (TCP_OPT_TIMESTAMP shl 8 + 10 + TCP_OPT_NOP shl 16 + TCP_OPT_NOP shl 24)
-
 
1731
	pushw	0
-
 
1732
	mov	eax, [timer_ticks]
-
 
1733
	bswap	eax
-
 
1734
	push	eax
-
 
1735
 
-
 
1736
	add	di, 10
1676
	test	[eax + TCP_SOCKET.t_flags], TF_REQ_TSTMP
Line -... Line 1677...
-
 
1677
	jz	.no_timestamp
1737
 
1678
 
Line 1738... Line -...
1738
  .no_timestamp:
-
 
1739
 
-
 
1740
	;; TODO: check if we dont exceed the max segment size
-
 
1741
 
-
 
1742
  .no_options:
-
 
1743
	add	edi, TCP_segment.Data
-
 
1744
 
-
 
1745
;-----------------------------------
-
 
1746
; Check if we have some data to send
-
 
1747
 
-
 
1748
     ;;;   mov     ecx, [huppeldepup]
-
 
1749
 
-
 
1750
	test	ecx, ecx
-
 
1751
	jz	.no_data
-
 
1752
 
-
 
1753
	;;; 278-316
1679
	test	dl, TH_RST
1754
 
-
 
1755
	jmp	.header
-
 
1756
 
-
 
1757
  .no_data:
-
 
1758
 
1680
	jnz	.no_timestamp
1759
	;;; 317-338
-
 
Line -... Line 1681...
-
 
1681
 
1760
 
1682
	test	dl, TH_ACK
-
 
1683
	jz	.timestamp
-
 
1684
 
1761
 
1685
	test	[eax + TCP_SOCKET.t_flags], TF_RCVD_TSTMP
-
 
1686
	jz	.no_timestamp
-
 
1687
 
-
 
1688
  .timestamp:
-
 
1689
	mov	esi, [timer_ticks]
-
 
1690
	bswap	esi
1762
;----------
1691
	push	esi
-
 
1692
	pushw	0
1763
 
1693
	pushd	TCP_OPT_TIMESTAMP + 10 shl 8 + TCP_OPT_NOP shl 16 + TCP_OPT_NOP shl 24
-
 
1694
	add	di, 10
Line 1764... Line 1695...
1764
	push	di dx ebx
1695
 
1765
 
1696
  .no_timestamp:
1766
	add	ecx, edi	; total TCP segment size
-
 
1767
 
-
 
Line 1768... Line 1697...
1768
	mov	eax, [ebx + IP_SOCKET.RemoteIP]
1697
	;; TODO: check if we dont exceed the max segment size
1769
	mov	ebx, [ebx + IP_SOCKET.LocalIP]
1698
 
1770
	mov	di , IP_PROTO_TCP
-
 
Line 1771... Line -...
1771
	call	IPv4_create_packet
-
 
1772
 
1699
  .no_options:
1773
;;;;        jz      .fail
-
 
Line -... Line 1700...
-
 
1700
	; eax = socket ptr
-
 
1701
	; edx = flags
-
 
1702
	; ecx = data size
-
 
1703
	; edi = header size
-
 
1704
	; esi = snd ring buff ptr
-
 
1705
 
-
 
1706
	xor	ecx, ecx	;;;;;
-
 
1707
	add	ecx, edi	; total TCP segment size
Line 1774... Line -...
1774
 
-
 
1775
	push	edx eax
-
 
1776
	call	[ebx + NET_DEVICE.transmit]
1708
 
1777
	ret
-
 
1778
 
1709
; Start by pushing all TCP header values in reverse order on stack
Line -... Line 1710...
-
 
1710
; (essentially, creating the tcp header!)
-
 
1711
 
1779
;----------------
1712
	pushw	0	;        .UrgentPointer          dw ?
-
 
1713
	pushw	0	;        .Checksum               dw ?
-
 
1714
	pushw	0x00a0	;        .Window                 dw ?    ;;;;;;;
-
 
1715
	shl	edi, 2	;        .DataOffset             db ?  only 4 left-most bits
-
 
1716
	shl	dx, 8
-
 
1717
	or	dx, di	;        .Flags                  db ?
-
 
1718
	pushw	dx
-
 
1719
	shr	edi, 2	;        .DataOffset             db ? ;;;;
Line -... Line 1720...
-
 
1720
 
1780
 
1721
	push	[eax + TCP_SOCKET.RCV_NXT]	;        .AckNumber              dd ?
Line -... Line 1722...
-
 
1722
	ntohld	[esp]
1781
 
1723
 
Line -... Line 1724...
-
 
1724
	push	[eax + TCP_SOCKET.SND_NXT]	;        .SequenceNumber         dd ?
-
 
1725
	ntohld	[esp]
Line 1782... Line 1726...
1782
;-------------------------------
1726
 
1783
; Now, create the 20-byte header
1727
	push	[eax + TCP_SOCKET.RemotePort]	;        .DestinationPort        dw ?
Line 1784... Line 1728...
1784
 
1728
	ntohlw	[esp]
1785
  .header:
1729
 
1786
 
1730
	push	[eax + TCP_SOCKET.LocalPort]	;        .SourcePort             dw ?
1787
;-----------------------
-
 
1788
; Fill in the TCP header
1731
	ntohlw	[esp]
1789
	pop	esi
1732
 
1790
 
-
 
1791
	push	[esi + TCP_SOCKET.SND_NXT]
-
 
1792
	rol	word [esp], 8
-
 
1793
	rol	dword [esp], 16
1733
	push	edi	; header size
1794
	pop	[edi + TCP_segment.SequenceNumber]
-
 
1795
 
-
 
1796
	push	[esi + TCP_SOCKET.RCV_NXT]
-
 
1797
	rol	word [esp], 8
1734
 
1798
	rol	dword [esp], 16
1735
; Create the IP packet
1799
	pop	[edi + TCP_segment.AckNumber]
1736
	mov	ebx, [eax + IP_SOCKET.LocalIP]	; source ip
1800
 
-
 
1801
	push	[esi + TCP_SOCKET.LocalPort]
1737
	mov	eax, [eax + IP_SOCKET.RemoteIP] ; dest ip
Line 1802... Line 1738...
1802
	rol	word [esp], 8
1738
;        mov     ecx,                            ; data length
1803
	pop	[edi + TCP_segment.SourcePort]
1739
;        mov     dx,                             ; fragment id
-
 
1740
	mov	di, IP_PROTO_TCP shl 8 + 128
-
 
1741
	call	IPv4_output
-
 
1742
	jz	.fail
-
 
1743
 
Line 1804... Line -...
1804
 
-
 
1805
	push	[esi + TCP_SOCKET.RemotePort]
1744
;-----------------------------------------
1806
	rol	word [esp], 8
1745
; Move TCP header from stack to TCP packet
Line 1807... Line 1746...
1807
	pop	[edi + TCP_segment.DestinationPort]
1746
 
1808
 
1747
;        pop     ecx                     ; header size
Line 1809... Line -...
1809
 
-
 
1810
	mov	[edi + TCP_segment.Window], 0x0005
-
 
1811
	; 1280 bytes
-
 
1812
	mov	[edi + TCP_segment.UrgentPointer], 0
1748
;        mov     esi, esp
1813
 
1749
;        add     esp, ecx
1814
	mov	[edi + TCP_segment.DataOffset], 0x50
1750
;        shr     ecx, 2
Line -... Line 1751...
-
 
1751
;        rep     movsd
-
 
1752
 
-
 
1753
	mov	ecx, [esp]
-
 
1754
	lea	esi, [esp+4]
-
 
1755
	shr	ecx, 2
-
 
1756
	rep	movsd
-
 
1757
 
-
 
1758
	pop	ecx
-
 
1759
	add	esp, ecx
-
 
1760
 
1815
 
1761
	mov	[esp + 3*4+4], edx	; packet size
1816
	mov	[edi + TCP_segment.Flags], cl
1762
	mov	[esp + 3*4], eax	; packet ptr
1817
 
1763
 
1818
	mov	[edi + TCP_segment.Checksum], 0
1764
	mov	edx, edi
1819
 
1765
	sub	edx, ecx
Line 1891... Line 1837...
1891
	db	TH_SYN + TH_ACK 	; TCB_LAST_ACK
1837
	db	TH_SYN + TH_ACK 	; TCB_LAST_ACK
1892
	db		 TH_ACK 	; TCB_FIN_WAIT_2
1838
	db		 TH_ACK 	; TCB_FIN_WAIT_2
1893
	db		 TH_ACK 	; TCB_TIMED_WAIT
1839
	db		 TH_ACK 	; TCB_TIMED_WAIT
Line -... Line 1840...
-
 
1840
 
-
 
1841
 
1894
 
1842
 
1895
 
1843
 
1896
;-------------------------
1844
;-------------------------
1897
;
1845
;
1898
; TCP_drop
1846
; TCP_drop
Line 1922... Line 1870...
1922
 
1870
 
1923
 
1871
 
1924
 
-
 
1925
;---------------------------------------
-
 
1926
;
1872
 
1927
; TCP_ack
1873
;---------------------------------------
1928
;
1874
;
1929
; The easy way to send an ACK/RST/keepalive segment
-
 
1930
;
-
 
1931
;  IN:  eax = socket ptr
-
 
1932
;       -or-
1875
; The easy way to send an ACK/RST/keepalive segment
-
 
1876
;
1933
;       edx = packet ptr (eax must be 0)
1877
; TCP_respond_socket:
1934
;        cl = flags
1878
;
1935
;
1879
;  IN:  ebx = socket ptr
1936
;  OUT: /
1880
;        cl = flags
1937
;
1881
;
Line 1938... Line 1882...
1938
;---------------------------------------
1882
;--------------------------------------
Line 1939... Line 1883...
1939
align 4
1883
align 4
1940
TCP_respond:
1884
TCP_respond_socket:
Line 1941... Line 1885...
1941
 
1885
 
1942
	DEBUGF	1,"TCP_respond\n"
1886
	DEBUGF	1,"TCP_respond_socket\n"
1943
 
1887
 
1944
;---------------------
1888
;---------------------
1945
; Create the IP packet
1889
; Create the IP packet
1946
 
1890
 
1947
	push	cx eax edx
1891
	push	cx ebx
1948
	mov	ebx, [eax + IP_SOCKET.LocalIP]
1892
	mov	eax, [ebx + IP_SOCKET.RemoteIP]
1949
	mov	eax, [eax + IP_SOCKET.RemoteIP]
-
 
1950
	mov	ecx, TCP_segment.Data
-
 
1951
	mov	di , IP_PROTO_TCP
-
 
1952
	call	IPv4_create_packet
-
 
1953
	test	edi, edi
1893
	mov	ebx, [ebx + IP_SOCKET.LocalIP]
1954
	jz	.error
-
 
1955
 
-
 
1956
;---------------------------
-
 
1957
; Now fill in the TCP header
-
 
1958
 
-
 
1959
	pop	ecx
-
 
1960
	pop	esi
1894
	mov	ecx, TCP_segment.Data
Line -... Line 1895...
-
 
1895
	mov	di , IP_PROTO_TCP shl 8 + 128
-
 
1896
	call	IPv4_output
-
 
1897
	test	edi, edi
-
 
1898
	jz	.error
-
 
1899
	pop	esi cx
-
 
1900
	push	edx eax
-
 
1901
 
-
 
1902
;-----------------------------------------------
-
 
1903
; Fill in the TCP header by using the socket ptr
-
 
1904
 
-
 
1905
	mov	ax, [esi + TCP_SOCKET.LocalPort]
-
 
1906
	rol	ax, 8
-
 
1907
	stosw
-
 
1908
	mov	ax, [esi + TCP_SOCKET.RemotePort]
-
 
1909
	rol	ax, 8
-
 
1910
	stosw
-
 
1911
	mov	eax, [esi + TCP_SOCKET.SND_NXT]
-
 
1912
	bswap	eax
-
 
1913
	stosd
-
 
1914
	mov	eax, [esi + TCP_SOCKET.RCV_NXT]
-
 
1915
	bswap	eax
1961
 
1916
	stosd
1962
	test	esi, esi
1917
	mov	al, 0x50	; Dataoffset: 20 bytes
1963
;        jz
1918
	stosb
Line 1964... Line 1919...
1964
 
1919
	mov	al, cl
1965
 
1920
	stosb
Line 1966... Line 1921...
1966
	push	edx eax
1921
	mov	ax, [esi + TCP_SOCKET.RCV_WND]
1967
 
-
 
1968
	push	dword .checksum
1922
	rol	ax, 8
1969
	je    .use_segment
-
 
1970
	jmp   .use_socket
1923
	stosw			; window
1971
 
1924
	xor	eax, eax
-
 
1925
	stosd			; checksum + urgentpointer
1972
;---------------------
1926
 
Line 1973... Line 1927...
1973
; Fill in the checksum
1927
;---------------------
1974
 
1928
; Fill in the checksum
Line 1975... Line 1929...
1975
  .checksum:
1929
 
1976
 
1930
  .checksum:
Line 1977... Line 1931...
1977
	push	[esi + IP_SOCKET.LocalIP]
1931
	sub	edi, TCP_segment.Data
1978
	push	[esi + IP_SOCKET.RemoteIP]
1932
	mov	ecx, TCP_segment.Data
1979
	lea	esi, [edi - 20]
1933
	xchg	esi, edi
Line 1980... Line 1934...
1980
	xor	ecx, ecx
1934
	TCP_checksum (edi + IP_SOCKET.LocalIP), (esi + IP_SOCKET.RemoteIP)
Line -... Line 1935...
-
 
1935
	mov	[esi+TCP_segment.Checksum], dx
-
 
1936
 
-
 
1937
;--------------------
-
 
1938
; And send the segment
-
 
1939
 
-
 
1940
	call	[ebx + NET_DEVICE.transmit]
-
 
1941
	ret
-
 
1942
 
-
 
1943
  .error:
-
 
1944
	DEBUGF	1,"TCP_respond failed\n"
-
 
1945
	add	esp, 2+4
-
 
1946
 
-
 
1947
	ret
-
 
1948
 
-
 
1949
 
-
 
1950
 
-
 
1951
;-------------------------
-
 
1952
; TCP_respond.segment:
-
 
1953
;
-
 
1954
;  IN:  edx = segment ptr (a previously received segment)
-
 
1955
;        cl = flags
-
 
1956
 
-
 
1957
align 4
-
 
1958
TCP_respond_segment:
-
 
1959
 
-
 
1960
	DEBUGF	1,"TCP_respond_segment\n"
-
 
1961
 
-
 
1962
;---------------------
1981
	call	TCP_checksum
1963
; Create the IP packet
1982
 
1964
 
Line 1983... Line -...
1983
;--------------------
-
 
1984
; And send the segment
-
 
1985
 
1965
	push	cx edx
1986
	call	[ebx + NET_DEVICE.transmit]
1966
	mov	ebx, [edx - 20 + IPv4_Packet.SourceAddress]	 ;;;; and what if ip packet had options?!
1987
	ret
1967
	mov	eax, [edx - 20 + IPv4_Packet.DestinationAddress]   ;;;
1988
 
1968
	mov	ecx, TCP_segment.Data
1989
  .error:
1969
	mov	di , IP_PROTO_TCP shl 8 + 128
Line 2016... Line 1996...
2016
	rol	ax, 8
1996
	rol	ax, 8
2017
	stosw			; window
1997
	stosw			; window
2018
	xor	eax, eax
1998
	xor	eax, eax
2019
	stosd			; checksum + urgentpointer
1999
	stosd			; checksum + urgentpointer
Line 2020... Line -...
2020
 
-
 
2021
	ret
-
 
2022
 
-
 
2023
 
2000
 
2024
;-----------------------------------------------
2001
;---------------------
Line 2025... Line 2002...
2025
; Fill in the TCP header by using the socket ptr
2002
; Fill in the checksum
-
 
2003
 
-
 
2004
  .checksum:
-
 
2005
	lea	esi, [edi - TCP_segment.Data]
-
 
2006
	mov	ecx, TCP_segment.Data
Line 2026... Line -...
2026
 
-
 
2027
  .use_socket:
-
 
2028
 
-
 
2029
	mov	ax, [esi + TCP_SOCKET.LocalPort]
-
 
2030
	rol	ax, 8
-
 
2031
	stosw
-
 
2032
	mov	ax, [esi + TCP_SOCKET.RemotePort]
-
 
2033
	rol	ax, 8
-
 
2034
	stosw
-
 
2035
	mov	eax, [esi + TCP_SOCKET.SND_NXT]
-
 
2036
	bswap	eax
-
 
2037
	stosd
-
 
2038
	mov	eax, [esi + TCP_SOCKET.RCV_NXT]
-
 
2039
	bswap	eax
-
 
2040
	stosd
-
 
2041
	mov	al, 0x50	; Dataoffset: 20 bytes
-
 
2042
	stosb
-
 
2043
	mov	al, cl
-
 
2044
	stosb
2007
	TCP_checksum (esi - 20 + IPv4_Packet.DestinationAddress), (esi - 20 + IPv4_Packet.DestinationAddress)
2045
	mov	ax, [esi + TCP_SOCKET.RCV_WND]
-
 
2046
	rol	ax, 8
2008
	mov	[esi+TCP_segment.Checksum], dx
Line -... Line 2009...
-
 
2009
 
2047
	stosw			; window
2010
;--------------------
Line -... Line 2011...
-
 
2011
; And send the segment
-
 
2012
 
-
 
2013
	call	[ebx + NET_DEVICE.transmit]
Line 2048... Line -...
2048
	xor	eax, eax
-
 
2049
	stosd			; checksum + urgentpointer
-
 
2050
 
-
 
2051
	ret
-
 
2052
 
-
 
2053
 
-
 
2054
 
-
 
2055
;-----------------------------------------------------------------
-
 
2056
;
-
 
2057
; TCP_checksum
-
 
2058
;
-
 
2059
; This is the fast procedure to create or check a UDP header
-
 
2060
;  - To create a new checksum, the checksum field must be set to 0 before computation
-
 
2061
;  - To check an existing checksum, leave the checksum as is,
-
 
2062
;     and it will be 0 after this procedure, if it was correct
-
 
2063
;
-
 
2064
;  IN:  push source ip
-
 
2065
;       push dest ip
-
 
2066
;
-
 
2067
;       esi = packet ptr
-
 
2068
;
-
 
2069
;  OUT: checksum is filled in in packet! (but also in dx)
-
 
2070
;
-
 
2071
;-----------------------------------------------------------------
-
 
2072
align 4
-
 
2073
TCP_checksum:
-
 
2074
 
-
 
2075
;-------------
-
 
2076
; Pseudoheader
-
 
2077
 
-
 
2078
	; protocol type
-
 
2079
	mov	edx, IP_PROTO_TCP		; NO shl 8 here ! (it took me ages to figure this one out)
-
 
2080
 
-
 
2081
	; source address
-
 
2082
	add	dl, [esp+1+4]
-
 
2083
	adc	dh, [esp+0+4]
-
 
2084
	adc	dl, [esp+3+4]
-
 
2085
	adc	dh, [esp+2+4]
-
 
2086
 
-
 
2087
	; destination address
-
 
2088
	adc	dl, [esp+1+8]
-
 
2089
	adc	dh, [esp+0+8]
-
 
2090
	adc	dl, [esp+3+8]
-
 
2091
	adc	dh, [esp+2+8]
-
 
2092
 
-
 
2093
	; size
-
 
2094
	adc	dl, cl
-
 
2095
	adc	dh, ch
-
 
2096
 
-
 
2097
;---------------------
2014
	ret
2098
; Real header and data
-
 
2099
 
-
 
2100
	push	esi
-
 
2101
	call	checksum_1
-
 
2102
	call	checksum_2
-
 
Line 2103... Line 2015...
2103
	pop	esi
2015