Subversion Repositories Kolibri OS

Rev

Rev 2308 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1763 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2362 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved.    ;;
1763 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
7
;;                                                                 ;;
8
;;   Written by hidnplayr@kolibrios.org                            ;;
9
;;                                                                 ;;
10
;;    Based on the code of 4.4BSD                                  ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1733 hidnplayr 16
 
1763 hidnplayr 17
$Revision: 2362 $
1733 hidnplayr 18
 
2362 hidnplayr 19
macro	TCP_checksum IP1, IP2 {
1733 hidnplayr 20
 
21
;-------------
22
; Pseudoheader
23
 
2362 hidnplayr 24
	; protocol type
25
	mov	edx, IP_PROTO_TCP
1733 hidnplayr 26
 
2362 hidnplayr 27
	; source address
28
	add	dl, byte [IP1+1]
29
	adc	dh, byte [IP1+0]
30
	adc	dl, byte [IP1+3]
31
	adc	dh, byte [IP1+2]
1733 hidnplayr 32
 
2362 hidnplayr 33
	; destination address
34
	adc	dl, byte [IP2+1]
35
	adc	dh, byte [IP2+0]
36
	adc	dl, byte [IP2+3]
37
	adc	dh, byte [IP2+2]
1733 hidnplayr 38
 
2362 hidnplayr 39
	; size
40
	adc	dl, cl
41
	adc	dh, ch
1733 hidnplayr 42
 
43
;---------------------
44
; Real header and data
45
 
2362 hidnplayr 46
	push	esi
47
	call	checksum_1
48
	call	checksum_2
49
	pop	esi
1733 hidnplayr 50
 
2362 hidnplayr 51
}	; returns in dx only
1733 hidnplayr 52
 
53
 
54
 
55
 
2362 hidnplayr 56
macro	TCP_sendseqinit ptr {
1733 hidnplayr 57
 
2362 hidnplayr 58
	push	edi			;;;; i dont like this static use of edi
59
	mov	edi, [ptr + TCP_SOCKET.ISS]
60
	mov	[ptr + TCP_SOCKET.SND_UP], edi
61
	mov	[ptr + TCP_SOCKET.SND_MAX], edi
62
	mov	[ptr + TCP_SOCKET.SND_NXT], edi
63
	mov	[ptr + TCP_SOCKET.SND_UNA], edi
64
	pop	edi
1733 hidnplayr 65
 
66
}
67
 
68
 
69
 
2362 hidnplayr 70
macro	TCP_rcvseqinit ptr {
1733 hidnplayr 71
 
2362 hidnplayr 72
	push	edi
73
	mov	edi, [ptr + TCP_SOCKET.IRS]
74
	inc	edi
75
	mov	[ptr + TCP_SOCKET.RCV_NXT], edi
76
	mov	[ptr + TCP_SOCKET.RCV_ADV], edi
77
	pop	edi
1733 hidnplayr 78
 
79
}
80
 
81
 
82
 
83
 
84
 
85
 
86
 
87
 
88
 
89
 
90
;---------------------------
91
;
92
; TCP_pull_out_of_band
93
;
94
; IN:  eax =
95
;      ebx = socket ptr
96
;      edx = tcp packet ptr
97
;
98
; OUT: /
99
;
100
;---------------------------
101
 
102
align 4
103
TCP_pull_out_of_band:
104
 
2362 hidnplayr 105
	DEBUGF	1,"TCP_pull_out_of_band\n"
1733 hidnplayr 106
 
2362 hidnplayr 107
	;;;; 1282-1305
1733 hidnplayr 108
 
2362 hidnplayr 109
	ret
1733 hidnplayr 110
 
111
 
112
 
113
 
114
 
115
 
116
 
117
 
118
;-------------------------
119
;
120
; TCP_drop
121
;
122
;  IN:  eax = socket ptr
123
;       ebx = error number
124
;
125
;  OUT: eax = socket ptr
126
;
127
;-------------------------
128
align 4
129
TCP_drop:
130
 
2362 hidnplayr 131
	DEBUGF	1,"TCP_drop\n"
1733 hidnplayr 132
 
2362 hidnplayr 133
	cmp	[eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
134
	jb	.no_syn_received
1733 hidnplayr 135
 
2362 hidnplayr 136
	mov	[eax + TCP_SOCKET.t_state], TCPS_CLOSED
1733 hidnplayr 137
 
2362 hidnplayr 138
	call	TCP_output
1733 hidnplayr 139
 
140
;;; TODO: update stats
141
 
2362 hidnplayr 142
	jmp	TCP_close
1733 hidnplayr 143
 
144
  .no_syn_received:
145
 
146
;;; TODO: update stats
147
 
148
;;; TODO: check if error code is "Connection timed out' and handle accordingly
149
 
2362 hidnplayr 150
	mov	[eax + SOCKET.errorcode], ebx
1733 hidnplayr 151
 
152
 
153
 
154
 
155
 
156
 
157
 
158
 
159
;-------------------------
160
;
161
; TCP_close
162
;
163
;  IN:  eax = socket ptr
164
;  OUT: eax = socket ptr
165
;
166
;-------------------------
167
align 4
168
TCP_close:
169
 
2362 hidnplayr 170
	DEBUGF	1,"TCP_close\n"
1733 hidnplayr 171
 
172
;;; TODO: update RTT and mean deviation
173
;;; TODO: update slow start threshold
174
;;; TODO: release connection resources
175
 
2362 hidnplayr 176
	call	SOCKET_is_disconnected
1733 hidnplayr 177
 
2362 hidnplayr 178
	ret
1733 hidnplayr 179
 
180
 
181
 
182
 
183
 
184
 
185
 
186
 
187
 
188
 
189
;-------------------------
190
;
191
; TCP_outflags
192
;
193
;  IN:  eax = socket ptr
194
;
195
;  OUT: edx = flags
196
;
197
;-------------------------
198
align 4
199
TCP_outflags:
200
 
2362 hidnplayr 201
	mov	edx, [eax + TCP_SOCKET.t_state]
202
	movzx	edx, byte [edx + .flaglist]
1733 hidnplayr 203
 
2362 hidnplayr 204
	DEBUGF	1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl
1733 hidnplayr 205
 
2362 hidnplayr 206
	ret
1733 hidnplayr 207
 
208
  .flaglist:
209
 
2362 hidnplayr 210
	db	TH_RST + TH_ACK 	; TCPS_CLOSED
211
	db	0			; TCPS_LISTEN
212
	db	TH_SYN			; TCPS_SYN_SENT
213
	db	TH_SYN + TH_ACK 	; TCPS_SYN_RECEIVED
214
	db		 TH_ACK 	; TCPS_ESTABLISHED
215
	db		 TH_ACK 	; TCPS_CLOSE_WAIT
216
	db	TH_SYN + TH_ACK 	; TCPS_FIN_WAIT_1
217
	db	TH_SYN + TH_ACK 	; TCPS_CLOSING
218
	db	TH_SYN + TH_ACK 	; TCPS_LAST_ACK
219
	db		 TH_ACK 	; TCPS_FIN_WAIT_2
220
	db		 TH_ACK 	; TCPS_TIMED_WAIT
1733 hidnplayr 221
 
222
 
223
 
224
 
225
 
226
 
227
;---------------------------------------
228
;
1830 hidnplayr 229
; The fast way to send an ACK/RST/keepalive segment
1733 hidnplayr 230
;
231
; TCP_respond_socket:
232
;
233
;  IN:  ebx = socket ptr
234
;        cl = flags
235
;
236
;--------------------------------------
237
align 4
238
TCP_respond_socket:
239
 
2362 hidnplayr 240
	DEBUGF	1,"TCP_respond_socket\n"
1733 hidnplayr 241
 
242
;---------------------
243
; Create the IP packet
244
 
2362 hidnplayr 245
	push	cx ebx
246
	mov	eax, [ebx + IP_SOCKET.RemoteIP]
247
	mov	ebx, [ebx + IP_SOCKET.LocalIP]
248
	mov	ecx, sizeof.TCP_header
249
	mov	di , IP_PROTO_TCP shl 8 + 128
250
	call	IPv4_output
251
	test	edi, edi
252
	jz	.error
253
	pop	esi cx
254
	push	edx eax
1733 hidnplayr 255
 
256
;-----------------------------------------------
257
; Fill in the TCP header by using the socket ptr
258
 
2362 hidnplayr 259
	mov	ax, [esi + TCP_SOCKET.LocalPort]
260
	rol	ax, 8
261
	stosw
262
	mov	ax, [esi + TCP_SOCKET.RemotePort]
263
	rol	ax, 8
264
	stosw
265
	mov	eax, [esi + TCP_SOCKET.SND_NXT]
266
	bswap	eax
267
	stosd
268
	mov	eax, [esi + TCP_SOCKET.RCV_NXT]
269
	bswap	eax
270
	stosd
271
	mov	al, 0x50	; Dataoffset: 20 bytes (TCP_header.DataOffset)
272
	stosb
273
	mov	al, cl
274
	stosb
1830 hidnplayr 275
;        mov     ax, [esi + TCP_SOCKET.RCV_WND]
276
;        rol     ax, 8
2362 hidnplayr 277
	mov	ax, 0x00a0	;;;;;;; FIXME
278
	stosw			; window
279
	xor	eax, eax
280
	stosd			; checksum + urgentpointer
1733 hidnplayr 281
 
282
;---------------------
283
; Fill in the checksum
284
 
285
  .checksum:
2362 hidnplayr 286
	sub	edi, sizeof.TCP_header
287
	mov	ecx, sizeof.TCP_header
288
	xchg	esi, edi
289
	TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
290
	mov	[esi+TCP_header.Checksum], dx
1733 hidnplayr 291
 
292
;--------------------
293
; And send the segment
294
 
2362 hidnplayr 295
	call	[ebx + NET_DEVICE.transmit]
296
	ret
1733 hidnplayr 297
 
298
  .error:
2362 hidnplayr 299
	DEBUGF	1,"TCP_respond failed\n"
300
	add	esp, 2+4
1733 hidnplayr 301
 
2362 hidnplayr 302
	ret
1733 hidnplayr 303
 
304
 
305
 
306
 
307
 
308
 
309
 
310
 
311
;-------------------------
312
; TCP_respond.segment:
313
;
2308 hidnplayr 314
;  IN:  ebx = ptr to driver
315
;       edx = segment ptr (a previously received segment)
316
;       edi = ptr to dest and src IPv4 addresses
1733 hidnplayr 317
;        cl = flags
318
 
319
align 4
320
TCP_respond_segment:
321
 
2362 hidnplayr 322
	DEBUGF	1,"TCP_respond_segment\n"
1733 hidnplayr 323
 
324
;---------------------
325
; Create the IP packet
326
 
2362 hidnplayr 327
	push	cx edx ebx
328
	mov	ebx, [edi + 4]
329
	mov	eax, [edi]
330
	mov	ecx, sizeof.TCP_header
331
	mov	di , IP_PROTO_TCP shl 8 + 128
332
	call	IPv4_output
333
	jz	.error
334
	pop	ebx esi cx
1733 hidnplayr 335
 
2362 hidnplayr 336
	push	edx eax
1733 hidnplayr 337
 
338
;---------------------------------------------------
339
; Fill in the TCP header by using a received segment
340
 
2362 hidnplayr 341
	mov	ax, [esi + TCP_header.DestinationPort]
342
	rol	ax, 8
343
	stosw
344
	mov	ax, [esi + TCP_header.SourcePort]
345
	rol	ax, 8
346
	stosw
347
	mov	eax, [esi + TCP_header.AckNumber]
348
	bswap	eax
349
	stosd
350
	xor	eax, eax
351
	stosd
352
	mov	al, 0x50	; Dataoffset: 20 bytes (sizeof.TCP_header)
353
	stosb
354
	mov	al, cl
355
	stosb
356
	mov	ax, 1280
357
	rol	ax, 8
358
	stosw			; window
359
	xor	eax, eax
360
	stosd			; checksum + urgentpointer
1733 hidnplayr 361
 
362
;---------------------
363
; Fill in the checksum
364
 
365
  .checksum:
2362 hidnplayr 366
	lea	esi, [edi - sizeof.TCP_header]
367
	mov	ecx, sizeof.TCP_header
368
	TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\	; FIXME
369
		     (esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
370
	mov	[esi+TCP_header.Checksum], dx
1733 hidnplayr 371
 
372
;--------------------
373
; And send the segment
374
 
2362 hidnplayr 375
	call	[ebx + NET_DEVICE.transmit]
376
	ret
1733 hidnplayr 377
 
378
  .error:
2362 hidnplayr 379
	DEBUGF	1,"TCP_respond failed\n"
380
	add	esp, 2+4
1733 hidnplayr 381
 
2362 hidnplayr 382
	ret
383
 
384
 
385
 
386
macro TCP_set_persist socket {
387
 
388
;int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
389
;int tt;
390
;
391
;tp->t_flags &= ~TF_PREVVALID;
392
;
393
;if (tcp_timer_active(tp, TT_REXMT))
394
;        panic("tcp_setpersist: retransmit pending");
395
;
396
;; Start/restart persistance timer.
397
;
398
;TCPT_RANGESET(tt, t * tcp_backoff[tp->t_rxtshift], TCPTV_PERSMIN, TCPTV_PERSMAX);
399
;tcp_timer_activate(tp, TT_PERSIST, tt);
400
;
401
;if (tp->t_rxtshift < TCP_MAXRXTSHIFT)
402
;        tp->t_rxtshift++;
403
 
404
}