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 12... Line 12...
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
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
$Revision: 1519 $
17
$Revision: 1529 $
18
 
18
 
19
 
19
 
Line 38... Line 38...
38
;
38
;
39
; UDP_init
39
; UDP_init
40
;
40
;
41
;  This function resets all UDP variables
41
;  This function resets all UDP variables
42
;
42
;
43
;  IN:  /
-
 
44
;  OUT: /
-
 
45
;
-
 
46
;-----------------------------------------------------------------
43
;-----------------------------------------------------------------
47
align 4
-
 
48
UDP_init:
44
macro	UDP_init {
Line 49... Line 45...
49
 
45
 
50
	xor	eax, eax
46
	xor	eax, eax
51
	mov	edi, UDP_PACKETS_TX
47
	mov	edi, UDP_PACKETS_TX
52
	mov	ecx, 2*MAX_IP
48
	mov	ecx, 2*MAX_IP
-
 
49
	rep	stosd
Line -... Line 50...
-
 
50
}
-
 
51
 
-
 
52
 
-
 
53
 
-
 
54
 
-
 
55
macro	UDP_checksum	IP1, IP2  { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx
-
 
56
 
-
 
57
; Pseudoheader
-
 
58
	mov	edx, IP_PROTO_UDP
-
 
59
 
-
 
60
	add	dl, [IP1+1+4]
-
 
61
	adc	dh, [IP1+0+4]
-
 
62
	adc	dl, [IP1+3+4]
-
 
63
	adc	dh, [IP1+2+4]
-
 
64
 
-
 
65
	adc	dl, [IP2+1+8]
-
 
66
	adc	dh, [IP2+0+8]
-
 
67
	adc	dl, [IP2+3+8]
-
 
68
	adc	dh, [IP2+2+8]
-
 
69
 
-
 
70
	adc	dl, cl ; byte[esi+UDP_Packet.Length+1]
-
 
71
	adc	dh, ch ; byte[esi+UDP_Packet.Length+0]
-
 
72
 
-
 
73
; Done with pseudoheader, now do real header
-
 
74
	adc	dl, byte[esi+UDP_Packet.SourcePort+1]
-
 
75
	adc	dh, byte[esi+UDP_Packet.SourcePort+0]
-
 
76
 
-
 
77
	adc	dl, byte[esi+UDP_Packet.DestinationPort+1]
-
 
78
	adc	dh, byte[esi+UDP_Packet.DestinationPort+0]
-
 
79
 
-
 
80
	adc	dl, byte[esi+UDP_Packet.Length+1]
-
 
81
	adc	dh, byte[esi+UDP_Packet.Length+0]
-
 
82
 
-
 
83
	adc	edx, 0
-
 
84
 
-
 
85
; Done with header, now do data
-
 
86
	push	esi
-
 
87
	movzx	ecx, [esi+UDP_Packet.Length]
-
 
88
	rol	cx , 8
-
 
89
	sub	cx , UDP_Packet.Data
-
 
90
	add	esi, UDP_Packet.Data
-
 
91
 
53
	rep	stosd
92
	call	checksum_1
-
 
93
	call	checksum_2
-
 
94
	pop	esi
-
 
95
 
-
 
96
	add	[esi+UDP_Packet.Checksum], dx	; this final instruction will set or clear ZF :)
Line 54... Line 97...
54
 
97
 
55
	ret
98
}
56
 
99
 
57
 
100
 
58
;-----------------------------------------------------------------
101
;-----------------------------------------------------------------
59
;
102
;
60
; UDP_input:
103
; UDP_input:
61
;
104
;
62
;  Called by IPv4_input,
105
;  Called by IPv4_input,
63
;  this procedure will inject the udp data diagrams in the application sockets.
106
;  this procedure will inject the udp data diagrams in the application sockets.
64
;
107
;
65
;  IN:  Pointer to buffer in [esp]
108
;  IN:   [esp]  = Pointer to buffer
66
;       size of buffer in [esp+4]
109
;       [esp+4] = size of buffer
67
;       pointer to device struct in ebx
110
;       ebx = ptr to device struct
68
;       UDP Packet size in ecx
111
;       ecx = UDP Packet size
69
;       pointer to UDP Packet in edx
112
;       edx = ptr to UDP header
70
;
113
;
Line 78... Line 121...
78
UDP_input:
121
UDP_input:
Line 79... Line 122...
79
 
122
 
Line 80... Line 123...
80
	DEBUGF	1,"UDP_input, size:%u\n", ecx
123
	DEBUGF	1,"UDP_input, size:%u\n", ecx
81
 
124
 
82
; First validate, checksum:
125
; First validate, checksum:
83
	cmp	[edx + UDP_Packet.Checksum], 0
-
 
84
	jz	.no_checksum
126
	neg	[esi+UDP_Packet.Checksum]	; substract chechksum from 0
Line 85... Line 127...
85
 
127
	jz	.no_checksum			; if checksum is zero, it is considered valid and we continue processing
-
 
128
						; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
86
	xchg	edi, esi	; save ipv4 source address to edi so we can use it later
129
 
87
 
130
	push	edx
-
 
131
	push	edi
-
 
132
	push	esi
88
	push	edx
133
	mov	esi, edx
89
	push	esi edi
134
	UDP_checksum (esp), (esp+4)
90
	mov	esi, edx
-
 
91
	call	UDP_checksum	; this destroys edx, ecx and esi (but not edi...)
-
 
92
	pop	edx
135
	pop	edi
Line 93... Line 136...
93
 
136
	pop	esi	; we dont need it, but it is smaller then add esp, 4
94
	cmp	[edx + UDP_Packet.Checksum], 0
137
	pop	edx
Line 166... Line 209...
166
 
209
 
Line 167... Line 210...
167
  .checksum_mismatch:
210
  .checksum_mismatch:
Line 168... Line -...
168
 
-
 
169
	DEBUGF	2,"UDP_Handler - checksum mismatch\n"
-
 
170
 
-
 
171
;        mov     esi, edx
-
 
172
;       @@:                         ;
-
 
173
;        lodsb                      ;
-
 
174
;        DEBUGF  2,"%x ", eax:2     ;
211
 
175
;        loop    @r                 ;
212
	DEBUGF	2,"UDP_Handler - checksum mismatch\n"
176
 
213
 
177
  .dump:
214
  .dump:
Line 205... Line 242...
205
	rol	edx, 16
242
	rol	edx, 16
206
	mov	dx, [eax + UDP_SOCKET.LocalPort]
243
	mov	dx, [eax + UDP_SOCKET.LocalPort]
207
	DEBUGF	1,"local port: %u\n", dx
244
	DEBUGF	1,"local port: %u\n", dx
208
	rol	dx, 8
245
	rol	dx, 8
Line 209... Line -...
209
 
-
 
210
 
246
 
211
	mov	ebx, [eax + IP_SOCKET.LocalIP]
247
	mov	ebx, [eax + IP_SOCKET.LocalIP]
Line 212... Line 248...
212
	mov	eax, [eax + IP_SOCKET.RemoteIP]
248
	mov	eax, [eax + IP_SOCKET.RemoteIP]
213
 
249
 
214
	mov	di , IP_PROTO_UDP
250
	mov	di, IP_PROTO_UDP shl 8 + 128
Line 215... Line 251...
215
	sub	esp, 8						; Data ptr and data size will be placed here
251
	sub	esp, 8						; Data ptr and data size will be placed here
216
	add	ecx, UDP_Packet.Data
-
 
217
 
252
	add	ecx, UDP_Packet.Data
218
;;; TODO: fragment id
253
 
219
 
254
;;; TODO: fragment id
Line 220... Line 255...
220
	push	edx esi
255
	push	edx esi
221
	call	IPv4_create_packet
256
	call	IPv4_output
Line 222... Line -...
222
	jz	.fail
-
 
223
 
257
	jz	.fail
224
	mov	[esp + 8], eax					; pointer to buffer start
258
 
Line 225... Line 259...
225
	mov	[esp + 8 + 4], edx				; buffer size
259
	mov	[esp + 8], eax					; pointer to buffer start
226
 
260
	mov	[esp + 8 + 4], edx				; buffer size
227
	rol	cx, 8
261
 
228
	mov	[edi + UDP_Packet.Length], cx
262
	mov	[edi + UDP_Packet.Length], cx
Line 238... Line 272...
238
	and	ecx, 3
272
	and	ecx, 3
239
	rep	movsb
273
	rep	movsb
240
	pop	ecx edi
274
	pop	ecx edi
Line 241... Line 275...
241
 
275
 
242
	pop	dword [edi + UDP_Packet.SourcePort]
-
 
Line 243... Line 276...
243
	mov	[edi + UDP_Packet.Checksum], 0			; set it to zero, to calculate checksum
276
	pop	dword [edi + UDP_Packet.SourcePort]
244
 
277
 
-
 
278
; Checksum
245
; Checksum
279
	mov	esi, edi
246
	mov	esi, edi
-
 
247
	pushd	[edi-4] ; destination address                   ; TODO: fix this, IPv4 packet could have options..
-
 
Line 248... Line 280...
248
	pushd	[edi-8] ; source address
280
	mov	[edi + UDP_Packet.Checksum], 0
Line 249... Line 281...
249
	call	UDP_checksum
281
	UDP_checksum (edi-4), (edi-8)				; TODO: fix this, IPv4 packet could have options..
Line 250... Line 282...
250
 
282
 
251
	inc	[UDP_PACKETS_TX]
283
	inc	[UDP_PACKETS_TX]
-
 
284
 
252
 
285
	DEBUGF	1,"Sending UDP Packet to device %x\n", ebx
-
 
286
 
253
	DEBUGF	1,"Sending UDP Packet to device %x\n", ebx
287
	call	[ebx + NET_DEVICE.transmit]
-
 
288
	ret
254
 
289
 
Line 255... Line -...
255
	call	[ebx + NET_DEVICE.transmit]
-
 
256
	ret
-
 
257
  .fail:
-
 
258
	add	esp, 8+8
-
 
259
	ret
-
 
260
 
-
 
261
 
-
 
262
 
-
 
263
 
-
 
264
;-----------------------------------------------------------------
-
 
265
;
-
 
266
; UDP_checksum
-
 
267
;
-
 
268
; This is the fast procedure to create or check a UDP header
-
 
269
;  - To create a new checksum, the checksum field must be set to 0 before computation
-
 
270
;  - To check an existing checksum, leave the checksum as is,
-
 
271
;     and it will be 0 after this procedure, if it was correct
-
 
272
;
-
 
273
;  IN:  push source ip
-
 
274
;       push dest ip
-
 
275
;       esi = packet ptr
-
 
276
;
-
 
277
;  OUT: checksum is filled in in packet! (but also in dx)
-
 
278
;
-
 
279
;-----------------------------------------------------------------
-
 
280
 
-
 
281
align 4
-
 
282
UDP_checksum:
-
 
283
 
-
 
284
; Pseudoheader
-
 
285
	mov	edx, IP_PROTO_UDP		; NO shl 8 here ! (it took me ages to figure this one out)
-
 
286
 
-
 
287
	add	dl, [esp+1+4]
-
 
288
	adc	dh, [esp+0+4]
-
 
289
	adc	dl, [esp+3+4]
-
 
290
	adc	dh, [esp+2+4]
-
 
291
 
-
 
292
	adc	dl, [esp+1+8]
-
 
293
	adc	dh, [esp+0+8]
-
 
294
	adc	dl, [esp+3+8]
-
 
295
	adc	dh, [esp+2+8]
-
 
296
 
-
 
297
 
-
 
298
	adc	dl, cl ; byte[esi+UDP_Packet.Length+1]
-
 
299
	adc	dh, ch ; byte[esi+UDP_Packet.Length+0]
-
 
300
 
-
 
301
; Done with pseudoheader, now do real header
-
 
302
	adc	dl, byte[esi+UDP_Packet.SourcePort+1]
-
 
303
	adc	dh, byte[esi+UDP_Packet.SourcePort+0]
-
 
304
 
-
 
305
	adc	dl, byte[esi+UDP_Packet.DestinationPort+1]
-
 
306
	adc	dh, byte[esi+UDP_Packet.DestinationPort+0]
-
 
307
 
-
 
308
	adc	dl, byte[esi+UDP_Packet.Length+1]
-
 
309
	adc	dh, byte[esi+UDP_Packet.Length+0]
-
 
310
 
-
 
311
	adc	edx, 0
-
 
312
 
-
 
313
; Done with header, now do data
-
 
314
	push	esi
-
 
315
	movzx	ecx, [esi+UDP_Packet.Length]
-
 
316
	rol	cx , 8
-
 
317
	sub	cx , UDP_Packet.Data
-
 
318
	add	esi, UDP_Packet.Data
-
 
319
 
-
 
320
	call	checksum_1
-
 
321
	call	checksum_2
-
 
322
	pop	esi
-
 
323
 
-
 
324
	neg	[esi+UDP_Packet.Checksum]	    ; zero will stay zero so we just get the checksum
290
  .fail:
325
	add	[esi+UDP_Packet.Checksum], dx	    ;  , else we will get (new checksum - old checksum) in the end, wich should be 0 :)
291
	DEBUGF	1,"UDP_output: failed\n"
326
 
292
	add	esp, 4+4+8
327
	ret	8
293
	xor	eax, eax
328
 
294
	ret