Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1763 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.    ;;
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: 1763 $
1733 hidnplayr 18
 
19
macro	TCP_checksum IP1, IP2 {
20
 
21
;-------------
22
; Pseudoheader
23
 
24
	; protocol type
25
	mov	edx, IP_PROTO_TCP
26
 
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]
32
 
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]
38
 
39
	; size
40
	adc	dl, cl
41
	adc	dh, ch
42
 
43
;---------------------
44
; Real header and data
45
 
46
	push	esi
47
	call	checksum_1
48
	call	checksum_2
49
	pop	esi
50
 
51
}	; returns in dx only
52
 
53
 
54
 
55
 
56
macro	TCP_sendseqinit ptr {
57
 
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
65
 
66
}
67
 
68
 
69
 
70
macro	TCP_rcvseqinit ptr {
71
 
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
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
 
105
	DEBUGF	1,"TCP_pull_out_of_band\n"
106
 
107
	;;;; 1282-1305
108
 
109
	ret
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
 
131
	DEBUGF	1,"TCP_drop\n"
132
 
133
	cmp	[eax + TCP_SOCKET.t_state], TCB_SYN_RECEIVED
134
	jl	.no_syn_received
135
 
136
	mov	[eax + TCP_SOCKET.t_state], TCB_CLOSED
137
 
138
	call	TCP_output
139
 
140
;;; TODO: update stats
141
 
142
	jmp	TCP_close
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
 
150
	mov	[eax + SOCKET.errorcode], ebx
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
 
170
	DEBUGF	1,"TCP_close\n"
171
 
172
;;; TODO: update RTT and mean deviation
173
;;; TODO: update slow start threshold
174
;;; TODO: release connection resources
175
 
176
; Now, mark the socket as being disconnected
177
 
178
	mov	[eax + SOCKET.state], 0 ;;; FIXME
179
 
180
	ret
181
 
182
 
183
 
184
 
185
 
186
 
187
 
188
 
189
 
190
 
191
;-------------------------
192
;
193
; TCP_outflags
194
;
195
;  IN:  eax = socket ptr
196
;
197
;  OUT: edx = flags
198
;
199
;-------------------------
200
align 4
201
TCP_outflags:
202
 
203
	mov	edx, [eax + TCP_SOCKET.t_state]
204
	movzx	edx, byte [edx + .flaglist]
205
 
206
	DEBUGF	1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl
207
 
208
	ret
209
 
210
  .flaglist:
211
 
212
	db	TH_RST + TH_ACK 	; TCB_CLOSED
213
	db	0			; TCB_LISTEN
214
	db	TH_SYN			; TCB_SYN_SENT
215
	db	TH_SYN + TH_ACK 	; TCB_SYN_RECEIVED
216
	db		 TH_ACK 	; TCB_ESTABLISHED
217
	db		 TH_ACK 	; TCB_CLOSE_WAIT
218
	db	TH_SYN + TH_ACK 	; TCB_FIN_WAIT_1
219
	db	TH_SYN + TH_ACK 	; TCB_CLOSING
220
	db	TH_SYN + TH_ACK 	; TCB_LAST_ACK
221
	db		 TH_ACK 	; TCB_FIN_WAIT_2
222
	db		 TH_ACK 	; TCB_TIMED_WAIT
223
 
224
 
225
 
226
 
227
 
228
 
229
;---------------------------------------
230
;
231
; The easy way to send an ACK/RST/keepalive segment
232
;
233
; TCP_respond_socket:
234
;
235
;  IN:  ebx = socket ptr
236
;        cl = flags
237
;
238
;--------------------------------------
239
align 4
240
TCP_respond_socket:
241
 
242
	DEBUGF	1,"TCP_respond_socket\n"
243
 
244
;---------------------
245
; Create the IP packet
246
 
247
	push	cx ebx
248
	mov	eax, [ebx + IP_SOCKET.RemoteIP]
249
	mov	ebx, [ebx + IP_SOCKET.LocalIP]
250
	mov	ecx, TCP_segment.Data
251
	mov	di , IP_PROTO_TCP shl 8 + 128
252
	call	IPv4_output
253
	test	edi, edi
254
	jz	.error
255
	pop	esi cx
256
	push	edx eax
257
 
258
;-----------------------------------------------
259
; Fill in the TCP header by using the socket ptr
260
 
261
	mov	ax, [esi + TCP_SOCKET.LocalPort]
262
	rol	ax, 8
263
	stosw
264
	mov	ax, [esi + TCP_SOCKET.RemotePort]
265
	rol	ax, 8
266
	stosw
267
	mov	eax, [esi + TCP_SOCKET.SND_NXT]
268
	bswap	eax
269
	stosd
270
	mov	eax, [esi + TCP_SOCKET.RCV_NXT]
271
	bswap	eax
272
	stosd
273
	mov	al, 0x50	; Dataoffset: 20 bytes
274
	stosb
275
	mov	al, cl
276
	stosb
277
	mov	ax, [esi + TCP_SOCKET.RCV_WND]
278
	rol	ax, 8
279
	stosw			; window
280
	xor	eax, eax
281
	stosd			; checksum + urgentpointer
282
 
283
;---------------------
284
; Fill in the checksum
285
 
286
  .checksum:
287
	sub	edi, TCP_segment.Data
288
	mov	ecx, TCP_segment.Data
289
	xchg	esi, edi
290
	TCP_checksum (edi + IP_SOCKET.LocalIP), (esi + IP_SOCKET.RemoteIP)
291
	mov	[esi+TCP_segment.Checksum], dx
292
 
293
;--------------------
294
; And send the segment
295
 
296
	call	[ebx + NET_DEVICE.transmit]
297
	ret
298
 
299
  .error:
300
	DEBUGF	1,"TCP_respond failed\n"
301
	add	esp, 2+4
302
 
303
	ret
304
 
305
 
306
 
307
 
308
 
309
 
310
 
311
 
312
;-------------------------
313
; TCP_respond.segment:
314
;
315
;  IN:  edx = segment ptr (a previously received segment)
316
;        cl = flags
317
 
318
align 4
319
TCP_respond_segment:
320
 
321
	DEBUGF	1,"TCP_respond_segment\n"
322
 
323
;---------------------
324
; Create the IP packet
325
 
326
	push	cx edx
327
	mov	ebx, [edx - 20 + IPv4_Packet.SourceAddress]	 ;;;; and what if ip packet had options?!
328
	mov	eax, [edx - 20 + IPv4_Packet.DestinationAddress]   ;;;
329
	mov	ecx, TCP_segment.Data
330
	mov	di , IP_PROTO_TCP shl 8 + 128
331
	call	IPv4_output
332
	jz	.error
333
	pop	esi cx
334
 
335
	push	edx eax
336
 
337
;---------------------------------------------------
338
; Fill in the TCP header by using a received segment
339
 
340
	mov	ax, [esi + TCP_segment.DestinationPort]
341
	rol	ax, 8
342
	stosw
343
	mov	ax, [esi + TCP_segment.SourcePort]
344
	rol	ax, 8
345
	stosw
346
	mov	eax, [esi + TCP_segment.AckNumber]
347
	bswap	eax
348
	stosd
349
	xor	eax, eax
350
	stosd
351
	mov	al, 0x50	; Dataoffset: 20 bytes
352
	stosb
353
	mov	al, cl
354
	stosb
355
	mov	ax, 1280
356
	rol	ax, 8
357
	stosw			; window
358
	xor	eax, eax
359
	stosd			; checksum + urgentpointer
360
 
361
;---------------------
362
; Fill in the checksum
363
 
364
  .checksum:
365
	lea	esi, [edi - TCP_segment.Data]
366
	mov	ecx, TCP_segment.Data
367
	TCP_checksum (esi - 20 + IPv4_Packet.DestinationAddress), (esi - 20 + IPv4_Packet.DestinationAddress)
368
	mov	[esi+TCP_segment.Checksum], dx
369
 
370
;--------------------
371
; And send the segment
372
 
373
	call	[ebx + NET_DEVICE.transmit]
374
	ret
375
 
376
  .error:
377
	DEBUGF	1,"TCP_respond failed\n"
378
	add	esp, 2+4
379
 
380
	ret