Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1196 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2009. 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: 1337 $
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
;  IN:  /
44
;  OUT: /
45
;
46
;-----------------------------------------------------------------
47
align 4
48
UDP_init:
49
 
50
	xor	eax, eax
51
	mov	edi, UDP_PACKETS_TX
52
	mov	ecx, 2*MAX_IP
53
	rep	stosd
54
 
55
	ret
56
 
57
 
58
 
59
;-----------------------------------------------------------------
60
;
61
; UDP_Handler:
62
;
63
;  Called by IPv4_handler,
64
;  this procedure will inject the udp data diagrams in the application sockets.
65
;
66
;  IN:  Pointer to buffer in [esp]
67
;       size of buffer in [esp+4]
68
;       pointer to device struct in ebx
69
;       UDP Packet size in ecx
70
;       pointer to UDP Packet data in edx
71
;  OUT: /
72
;
73
;-----------------------------------------------------------------
1206 hidnplayr 74
align 4
1196 hidnplayr 75
UDP_handler:
1159 hidnplayr 76
 
77
	DEBUGF 1,"UDP_Handler\n"
1249 hidnplayr 78
	; First validate, checksum:
1159 hidnplayr 79
 
1249 hidnplayr 80
	pusha
81
 
82
	rol	cx, 8
83
	push	cx
84
	rol	cx, 8
85
	push	word IP_PROTO_UDP shl 8
86
	push	edi
87
	push	esi
88
 
1254 hidnplayr 89
	mov	di, [edx + UDP_Packet.Checksum]
90
	mov    [edx + UDP_Packet.Checksum], 0
91
 
1249 hidnplayr 92
	mov	esi, edx
93
	xor	edx, edx
94
	call	checksum_1
95
	mov	ecx, 12
96
	mov	esi, esp
97
	call	checksum_1
98
	add	esp, 12
99
	call	checksum_2
100
 
1254 hidnplayr 101
	cmp	di, dx
1249 hidnplayr 102
	popa
1254 hidnplayr 103
	jne	.dump
1249 hidnplayr 104
 
1254 hidnplayr 105
	DEBUGF 1,"UDP Checksum is correct\n"
1249 hidnplayr 106
 
1159 hidnplayr 107
	; Look for a socket where
108
	; IP Packet UDP Destination Port = local Port
109
	; IP Packet SA = Remote IP
110
 
1206 hidnplayr 111
	mov	eax, net_sockets
1159 hidnplayr 112
  .try_more:
1206 hidnplayr 113
	mov	bx , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
1159 hidnplayr 114
  .next_socket:
1249 hidnplayr 115
	mov	eax, [eax + SOCKET_head.NextPtr]
1206 hidnplayr 116
	or	eax, eax
1159 hidnplayr 117
	jz	.dump
1249 hidnplayr 118
	cmp	[eax + SOCKET_head.Domain], AF_INET4
1159 hidnplayr 119
	jne	.next_socket
1249 hidnplayr 120
	cmp	[eax + SOCKET_head.Type], IP_PROTO_UDP
1159 hidnplayr 121
	jne	.next_socket
1249 hidnplayr 122
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
1206 hidnplayr 123
	jne	.next_socket
1159 hidnplayr 124
 
1208 hidnplayr 125
	DEBUGF 1,"found socket with matching domain, type and localport\n"
126
 
1159 hidnplayr 127
	; For dhcp, we must allow any remote server to respond.
128
	; I will accept the first incoming response to be the one
129
	; I bind to, if the socket is opened with a destination IP address of
130
	; 255.255.255.255
1249 hidnplayr 131
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
1206 hidnplayr 132
	je	.ok1
1159 hidnplayr 133
 
1206 hidnplayr 134
	mov	ebx, [esp]
1208 hidnplayr 135
	mov	ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet   FIXME
1249 hidnplayr 136
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
1159 hidnplayr 137
	jne	.try_more					      ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
138
 
1208 hidnplayr 139
 
140
	DEBUGF 1,"Remote Ip matches\n"
1206 hidnplayr 141
  .ok1:
1159 hidnplayr 142
 
1335 hidnplayr 143
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0
144
	jz	.updateport
1159 hidnplayr 145
 
1335 hidnplayr 146
	mov	bx, [edx + UDP_Packet.SourcePort]
1249 hidnplayr 147
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
1206 hidnplayr 148
	jne	.dump
1159 hidnplayr 149
 
1337 hidnplayr 150
	lea	ebx, [eax + SOCKET_head.lock]
151
	call	wait_mutex
152
 
1206 hidnplayr 153
  .ok2:
1159 hidnplayr 154
 
1206 hidnplayr 155
	DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
156
	lea	esi, [edx + UDP_Packet.Data]
157
	movzx	ecx, [edx + UDP_Packet.Length]
158
	rol	cx , 8
159
	sub	cx , UDP_Packet.Data
1159 hidnplayr 160
 
1206 hidnplayr 161
	inc	[UDP_PACKETS_RX]
1159 hidnplayr 162
 
1249 hidnplayr 163
	pop	edi
164
	add	esp, 4
165
 
166
	sub	esi, edi
167
	xchg	esi, edi
168
	jmp	socket_internal_receiver
169
 
170
 
1335 hidnplayr 171
  .updateport:
172
 
1337 hidnplayr 173
	lea	ebx, [eax + SOCKET_head.lock]
174
	call	wait_mutex
175
 
1335 hidnplayr 176
	mov	bx, [edx + UDP_Packet.SourcePort]
177
	DEBUGF 1,"Changing remote port to: %x\n", bx
178
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
179
	inc	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket]
180
 
181
	jmp	.ok2
182
 
1206 hidnplayr 183
  .dump:
184
	DEBUGF 1,"Dumping UDP packet\n"
1159 hidnplayr 185
	call	kernel_free
186
	add	esp, 4 ; pop (balance stack)
187
 
188
	ret
189
 
190
 
191
 
192
 
193
;-----------------------------------------------------------------
194
;
1249 hidnplayr 195
; UDP_socket_send
1159 hidnplayr 196
;
1249 hidnplayr 197
; IN: eax = socket pointer
198
;     ecx = number of bytes to send
199
;     esi = pointer to data
1159 hidnplayr 200
;
201
;-----------------------------------------------------------------
202
 
1249 hidnplayr 203
align 4
204
UDP_socket_send:
1159 hidnplayr 205
 
1249 hidnplayr 206
	mov	edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once
207
	DEBUGF	1,"local port: %x, remote port: %x\n",\
208
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
209
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
210
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
211
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
212
 
1206 hidnplayr 213
	DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
1159 hidnplayr 214
 
1249 hidnplayr 215
	mov	di , IP_PROTO_UDP
1159 hidnplayr 216
 
1249 hidnplayr 217
	sub	esp, 8						; reserve some place in stack for later
218
 
1254 hidnplayr 219
; Create a part pseudoheader in stack,
1249 hidnplayr 220
	push	dword IP_PROTO_UDP shl 8
221
 
1159 hidnplayr 222
	add	ecx, UDP_Packet.Data
223
 
1249 hidnplayr 224
; TODO: fill in:   dx  = fragment id
1159 hidnplayr 225
 
1249 hidnplayr 226
	push	edx esi
1196 hidnplayr 227
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
1159 hidnplayr 228
	cmp	edi, -1
1206 hidnplayr 229
	je	.fail
1159 hidnplayr 230
 
1251 clevermous 231
	mov	[esp + 8 + 4], eax				; pointer to buffer start
1254 hidnplayr 232
	mov	[esp + 8 + 4 + 4], edx				; buffer size
1159 hidnplayr 233
 
1249 hidnplayr 234
	rol	cx, 8
235
	mov	[edi + UDP_Packet.Length], cx
1251 clevermous 236
	mov	[esp + 8 + 2], cx
1249 hidnplayr 237
	ror	cx, 8
238
 
1159 hidnplayr 239
	pop	esi
1249 hidnplayr 240
	push	edi ecx
241
	sub	ecx, UDP_Packet.Data
1159 hidnplayr 242
	add	edi, UDP_Packet.Data
243
	shr	ecx, 2
244
	rep	movsd
1249 hidnplayr 245
	mov	ecx, [esp]
1251 clevermous 246
	and	ecx, 3
1159 hidnplayr 247
	rep	movsb
1249 hidnplayr 248
	pop	ecx edi
1159 hidnplayr 249
 
1254 hidnplayr 250
	pop	dword [edi + UDP_Packet.SourcePort]		; fill in both portnumbers
1249 hidnplayr 251
	mov	[edi + UDP_Packet.Checksum], 0			; set it to zero, to calculate checksum
1159 hidnplayr 252
 
1249 hidnplayr 253
; Checksum for UDP header + data
254
	xor	edx, edx
255
	mov	esi, edi
256
	call	checksum_1
257
; Checksum for pseudoheader
1335 hidnplayr 258
	pushd	[edi-4] ; destination address           ; TODO: fix this, IPv4 packet could have options..
1254 hidnplayr 259
	pushd	[edi-8] ; source address
1249 hidnplayr 260
	mov	ecx, 12
261
	mov	esi, esp
262
	call	checksum_1
263
	add	esp, 12 					; remove the pseudoheader from stack
264
; Now create the final checksum and store it in UDP header
265
	call	checksum_2
266
	mov	[edi + UDP_Packet.Checksum], dx
1159 hidnplayr 267
 
1206 hidnplayr 268
	inc	[UDP_PACKETS_TX]
269
 
1159 hidnplayr 270
	DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
1249 hidnplayr 271
	jmp	ETH_sender				       ;
1159 hidnplayr 272
 
1206 hidnplayr 273
  .fail:
274
	; todo: queue the packet
1249 hidnplayr 275
	add	esp, 8+12+8
1206 hidnplayr 276
	ret
1159 hidnplayr 277
 
278
 
1206 hidnplayr 279
 
1249 hidnplayr 280
 
1159 hidnplayr 281
;---------------------------------------------------------------------------
282
;
283
; UDP_API
284
;
285
; This function is called by system function 75
286
;
287
; IN:  subfunction number in bl
288
;      device number in bh
289
;      ecx, edx, .. depends on subfunction
290
;
291
; OUT:
292
;
293
;---------------------------------------------------------------------------
294
 
295
align 4
296
UDP_API:
297
 
298
	movzx	eax, bh
299
	shl	eax, 2
300
 
301
	test	bl, bl
302
	jz	.packets_tx	; 0
303
	dec	bl
304
	jz	.packets_rx	; 1
305
 
306
.error:
307
	mov	eax, -1
308
	ret
309
 
310
.packets_tx:
311
	add	eax, UDP_PACKETS_TX
312
	mov	eax, [eax]
313
	ret
314
 
315
.packets_rx:
316
	add	eax, UDP_PACKETS_RX
317
	mov	eax, [eax]
318
	ret