Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1514 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  UDP.INC                                                        ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
1206 hidnplayr 17
$Revision: 1529 $
1159 hidnplayr 18
 
19
 
20
struct	UDP_Packet
21
	.SourcePort		dw  ?
22
	.DestinationPort	dw  ?
23
	.Length 		dw  ?  ; Length of (UDP Header + Data)
24
	.Checksum		dw  ?
25
	.Data:
26
 
27
ends
28
 
29
 
30
align 4
31
uglobal
32
	UDP_PACKETS_TX		rd  MAX_IP
33
	UDP_PACKETS_RX		rd  MAX_IP
34
endg
35
 
36
 
37
;-----------------------------------------------------------------
38
;
39
; UDP_init
40
;
41
;  This function resets all UDP variables
42
;
43
;-----------------------------------------------------------------
1529 hidnplayr 44
macro	UDP_init {
1159 hidnplayr 45
 
46
	xor	eax, eax
47
	mov	edi, UDP_PACKETS_TX
48
	mov	ecx, 2*MAX_IP
49
	rep	stosd
1529 hidnplayr 50
}
1159 hidnplayr 51
 
52
 
53
 
1529 hidnplayr 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
 
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 :)
97
 
98
}
99
 
100
 
1159 hidnplayr 101
;-----------------------------------------------------------------
102
;
1514 hidnplayr 103
; UDP_input:
1159 hidnplayr 104
;
1514 hidnplayr 105
;  Called by IPv4_input,
1159 hidnplayr 106
;  this procedure will inject the udp data diagrams in the application sockets.
107
;
1529 hidnplayr 108
;  IN:   [esp]  = Pointer to buffer
109
;       [esp+4] = size of buffer
110
;       ebx = ptr to device struct
111
;       ecx = UDP Packet size
112
;       edx = ptr to UDP header
1484 hidnplayr 113
;
114
;       esi = ipv4 source address
115
;       edi = ipv4 dest   address
116
;
1159 hidnplayr 117
;  OUT: /
118
;
119
;-----------------------------------------------------------------
1206 hidnplayr 120
align 4
1514 hidnplayr 121
UDP_input:
1159 hidnplayr 122
 
1514 hidnplayr 123
	DEBUGF	1,"UDP_input, size:%u\n", ecx
1473 hidnplayr 124
 
1482 hidnplayr 125
; First validate, checksum:
1529 hidnplayr 126
	neg	[esi+UDP_Packet.Checksum]	; substract chechksum from 0
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
1159 hidnplayr 129
 
1483 hidnplayr 130
	push	edx
1529 hidnplayr 131
	push	edi
132
	push	esi
1249 hidnplayr 133
	mov	esi, edx
1529 hidnplayr 134
	UDP_checksum (esp), (esp+4)
135
	pop	edi
136
	pop	esi	; we dont need it, but it is smaller then add esp, 4
1483 hidnplayr 137
	pop	edx
1484 hidnplayr 138
	jnz	.checksum_mismatch
1249 hidnplayr 139
 
1473 hidnplayr 140
  .no_checksum:
141
	DEBUGF	1,"UDP Checksum is correct\n"
142
 
1159 hidnplayr 143
	; Look for a socket where
144
	; IP Packet UDP Destination Port = local Port
145
	; IP Packet SA = Remote IP
146
 
1206 hidnplayr 147
	mov	eax, net_sockets
1159 hidnplayr 148
  .try_more:
1473 hidnplayr 149
	mov	si , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
1514 hidnplayr 150
	rol	si , 8
1159 hidnplayr 151
  .next_socket:
1514 hidnplayr 152
	mov	eax, [eax + SOCKET.NextPtr]
1206 hidnplayr 153
	or	eax, eax
1159 hidnplayr 154
	jz	.dump
1514 hidnplayr 155
	cmp	[eax + SOCKET.Domain], AF_INET4
1159 hidnplayr 156
	jne	.next_socket
1514 hidnplayr 157
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
1159 hidnplayr 158
	jne	.next_socket
1514 hidnplayr 159
	cmp	[eax + UDP_SOCKET.LocalPort], si
1206 hidnplayr 160
	jne	.next_socket
1159 hidnplayr 161
 
1514 hidnplayr 162
	DEBUGF	1,"using socket: %x\n", eax
1208 hidnplayr 163
 
1514 hidnplayr 164
	;;; TODO: when packet is processed, check more sockets!
1159 hidnplayr 165
 
1514 hidnplayr 166
	cmp	[eax + IP_SOCKET.RemoteIP], 0xffffffff
167
	je	@f
168
	cmp	[eax + IP_SOCKET.RemoteIP], edi 	; edi is the packets source address
169
	jne	.try_more
170
       @@:
1159 hidnplayr 171
 
1514 hidnplayr 172
	cmp	[eax + UDP_SOCKET.firstpacket], 0
1335 hidnplayr 173
	jz	.updateport
1159 hidnplayr 174
 
1473 hidnplayr 175
	mov	si, [edx + UDP_Packet.SourcePort]
1514 hidnplayr 176
	rol	si, 8
177
	cmp	[eax + UDP_SOCKET.RemotePort], si
1206 hidnplayr 178
	jne	.dump
1159 hidnplayr 179
 
1473 hidnplayr 180
	push	ebx
1514 hidnplayr 181
	lea	ebx, [eax + SOCKET.lock]
1337 hidnplayr 182
	call	wait_mutex
1473 hidnplayr 183
	pop	ebx
1337 hidnplayr 184
 
1514 hidnplayr 185
  .updatesock:
186
	inc	[UDP_PACKETS_RX]
1473 hidnplayr 187
	DEBUGF	1,"Found valid UDP packet for socket %x\n", eax
1206 hidnplayr 188
	lea	esi, [edx + UDP_Packet.Data]
189
	movzx	ecx, [edx + UDP_Packet.Length]
190
	rol	cx , 8
191
	sub	cx , UDP_Packet.Data
1159 hidnplayr 192
 
1514 hidnplayr 193
	jmp	SOCKET_input
1159 hidnplayr 194
 
1335 hidnplayr 195
  .updateport:
1473 hidnplayr 196
	push	ebx
1514 hidnplayr 197
	lea	ebx, [eax + SOCKET.lock]
1337 hidnplayr 198
	call	wait_mutex
1473 hidnplayr 199
	pop	ebx
1337 hidnplayr 200
 
1473 hidnplayr 201
	mov	si, [edx + UDP_Packet.SourcePort]
1514 hidnplayr 202
	rol	si, 8
203
	DEBUGF	1,"Changing remote port to: %u\n", si
204
	mov	[eax + UDP_SOCKET.RemotePort], si
205
	inc	[eax + UDP_SOCKET.firstpacket]
1335 hidnplayr 206
 
1514 hidnplayr 207
	jmp	.updatesock
1335 hidnplayr 208
 
1483 hidnplayr 209
 
1473 hidnplayr 210
  .checksum_mismatch:
211
 
212
	DEBUGF	2,"UDP_Handler - checksum mismatch\n"
213
 
1206 hidnplayr 214
  .dump:
1159 hidnplayr 215
	call	kernel_free
216
	add	esp, 4 ; pop (balance stack)
1473 hidnplayr 217
	DEBUGF	2,"UDP_Handler - dumping\n"
1159 hidnplayr 218
 
219
	ret
220
 
221
 
222
 
223
 
224
;-----------------------------------------------------------------
225
;
1514 hidnplayr 226
; UDP_output
1159 hidnplayr 227
;
1249 hidnplayr 228
; IN: eax = socket pointer
229
;     ecx = number of bytes to send
230
;     esi = pointer to data
1159 hidnplayr 231
;
232
;-----------------------------------------------------------------
233
 
1249 hidnplayr 234
align 4
1514 hidnplayr 235
UDP_output:
1159 hidnplayr 236
 
1514 hidnplayr 237
	DEBUGF	1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
1249 hidnplayr 238
 
1514 hidnplayr 239
	mov	dx, [eax + UDP_SOCKET.RemotePort]
240
	DEBUGF	1,"remote port: %u\n", dx
241
	rol	dx, 8
242
	rol	edx, 16
243
	mov	dx, [eax + UDP_SOCKET.LocalPort]
244
	DEBUGF	1,"local port: %u\n", dx
245
	rol	dx, 8
1159 hidnplayr 246
 
1514 hidnplayr 247
	mov	ebx, [eax + IP_SOCKET.LocalIP]
248
	mov	eax, [eax + IP_SOCKET.RemoteIP]
249
 
1529 hidnplayr 250
	mov	di, IP_PROTO_UDP shl 8 + 128
1482 hidnplayr 251
	sub	esp, 8						; Data ptr and data size will be placed here
1159 hidnplayr 252
	add	ecx, UDP_Packet.Data
253
 
1514 hidnplayr 254
;;; TODO: fragment id
1249 hidnplayr 255
	push	edx esi
1529 hidnplayr 256
	call	IPv4_output
1514 hidnplayr 257
	jz	.fail
1159 hidnplayr 258
 
1482 hidnplayr 259
	mov	[esp + 8], eax					; pointer to buffer start
260
	mov	[esp + 8 + 4], edx				; buffer size
1159 hidnplayr 261
 
1249 hidnplayr 262
	mov	[edi + UDP_Packet.Length], cx
1529 hidnplayr 263
	rol	[edi + UDP_Packet.Length], 8
1249 hidnplayr 264
 
1159 hidnplayr 265
	pop	esi
1249 hidnplayr 266
	push	edi ecx
267
	sub	ecx, UDP_Packet.Data
1159 hidnplayr 268
	add	edi, UDP_Packet.Data
269
	shr	ecx, 2
270
	rep	movsd
1249 hidnplayr 271
	mov	ecx, [esp]
1251 clevermous 272
	and	ecx, 3
1159 hidnplayr 273
	rep	movsb
1249 hidnplayr 274
	pop	ecx edi
1159 hidnplayr 275
 
1514 hidnplayr 276
	pop	dword [edi + UDP_Packet.SourcePort]
1159 hidnplayr 277
 
1482 hidnplayr 278
; Checksum
1249 hidnplayr 279
	mov	esi, edi
1529 hidnplayr 280
	mov	[edi + UDP_Packet.Checksum], 0
281
	UDP_checksum (edi-4), (edi-8)				; TODO: fix this, IPv4 packet could have options..
1159 hidnplayr 282
 
1206 hidnplayr 283
	inc	[UDP_PACKETS_TX]
284
 
1482 hidnplayr 285
	DEBUGF	1,"Sending UDP Packet to device %x\n", ebx
1159 hidnplayr 286
 
1519 hidnplayr 287
	call	[ebx + NET_DEVICE.transmit]
288
	ret
1529 hidnplayr 289
 
1206 hidnplayr 290
  .fail:
1529 hidnplayr 291
	DEBUGF	1,"UDP_output: failed\n"
292
	add	esp, 4+4+8
293
	xor	eax, eax
1206 hidnplayr 294
	ret
1159 hidnplayr 295
 
296
 
1206 hidnplayr 297
 
1159 hidnplayr 298
;---------------------------------------------------------------------------
299
;
300
; UDP_API
301
;
302
; This function is called by system function 75
303
;
304
; IN:  subfunction number in bl
305
;      device number in bh
306
;      ecx, edx, .. depends on subfunction
307
;
308
; OUT:
309
;
310
;---------------------------------------------------------------------------
311
 
312
align 4
313
UDP_API:
314
 
315
	movzx	eax, bh
316
	shl	eax, 2
317
 
318
	test	bl, bl
319
	jz	.packets_tx	; 0
320
	dec	bl
321
	jz	.packets_rx	; 1
322
 
323
.error:
324
	mov	eax, -1
325
	ret
326
 
327
.packets_tx:
328
	add	eax, UDP_PACKETS_TX
329
	mov	eax, [eax]
330
	ret
331
 
332
.packets_rx:
333
	add	eax, UDP_PACKETS_RX
334
	mov	eax, [eax]
335
	ret