Subversion Repositories Kolibri OS

Rev

Rev 1257 | 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: 1335 $
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
	lea	ebx, [eax + SOCKET_head.lock]
144
	call	wait_mutex
1159 hidnplayr 145
 
1335 hidnplayr 146
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket], 0
147
	jz	.updateport
1159 hidnplayr 148
 
1335 hidnplayr 149
	mov	bx, [edx + UDP_Packet.SourcePort]
1249 hidnplayr 150
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
1206 hidnplayr 151
	jne	.dump
1159 hidnplayr 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
 
173
	mov	bx, [edx + UDP_Packet.SourcePort]
174
	DEBUGF 1,"Changing remote port to: %x\n", bx
175
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
176
	inc	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.firstpacket]
177
 
178
	jmp	.ok2
179
 
1206 hidnplayr 180
  .dump:
181
	DEBUGF 1,"Dumping UDP packet\n"
1159 hidnplayr 182
	call	kernel_free
183
	add	esp, 4 ; pop (balance stack)
184
 
185
	ret
186
 
187
 
188
 
189
 
190
;-----------------------------------------------------------------
191
;
1249 hidnplayr 192
; UDP_socket_send
1159 hidnplayr 193
;
1249 hidnplayr 194
; IN: eax = socket pointer
195
;     ecx = number of bytes to send
196
;     esi = pointer to data
1159 hidnplayr 197
;
198
;-----------------------------------------------------------------
199
 
1249 hidnplayr 200
align 4
201
UDP_socket_send:
1159 hidnplayr 202
 
1249 hidnplayr 203
	mov	edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once
204
	DEBUGF	1,"local port: %x, remote port: %x\n",\
205
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
206
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
207
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
208
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
209
 
1206 hidnplayr 210
	DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
1159 hidnplayr 211
 
1249 hidnplayr 212
	mov	di , IP_PROTO_UDP
1159 hidnplayr 213
 
1249 hidnplayr 214
	sub	esp, 8						; reserve some place in stack for later
215
 
1254 hidnplayr 216
; Create a part pseudoheader in stack,
1249 hidnplayr 217
	push	dword IP_PROTO_UDP shl 8
218
 
1159 hidnplayr 219
	add	ecx, UDP_Packet.Data
220
 
1249 hidnplayr 221
; TODO: fill in:   dx  = fragment id
1159 hidnplayr 222
 
1249 hidnplayr 223
	push	edx esi
1196 hidnplayr 224
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
1159 hidnplayr 225
	cmp	edi, -1
1206 hidnplayr 226
	je	.fail
1159 hidnplayr 227
 
1251 clevermous 228
	mov	[esp + 8 + 4], eax				; pointer to buffer start
1254 hidnplayr 229
	mov	[esp + 8 + 4 + 4], edx				; buffer size
1159 hidnplayr 230
 
1249 hidnplayr 231
	rol	cx, 8
232
	mov	[edi + UDP_Packet.Length], cx
1251 clevermous 233
	mov	[esp + 8 + 2], cx
1249 hidnplayr 234
	ror	cx, 8
235
 
1159 hidnplayr 236
	pop	esi
1249 hidnplayr 237
	push	edi ecx
238
	sub	ecx, UDP_Packet.Data
1159 hidnplayr 239
	add	edi, UDP_Packet.Data
240
	shr	ecx, 2
241
	rep	movsd
1249 hidnplayr 242
	mov	ecx, [esp]
1251 clevermous 243
	and	ecx, 3
1159 hidnplayr 244
	rep	movsb
1249 hidnplayr 245
	pop	ecx edi
1159 hidnplayr 246
 
1254 hidnplayr 247
	pop	dword [edi + UDP_Packet.SourcePort]		; fill in both portnumbers
1249 hidnplayr 248
	mov	[edi + UDP_Packet.Checksum], 0			; set it to zero, to calculate checksum
1159 hidnplayr 249
 
1249 hidnplayr 250
; Checksum for UDP header + data
251
	xor	edx, edx
252
	mov	esi, edi
253
	call	checksum_1
254
; Checksum for pseudoheader
1335 hidnplayr 255
	pushd	[edi-4] ; destination address           ; TODO: fix this, IPv4 packet could have options..
1254 hidnplayr 256
	pushd	[edi-8] ; source address
1249 hidnplayr 257
	mov	ecx, 12
258
	mov	esi, esp
259
	call	checksum_1
260
	add	esp, 12 					; remove the pseudoheader from stack
261
; Now create the final checksum and store it in UDP header
262
	call	checksum_2
263
	mov	[edi + UDP_Packet.Checksum], dx
1159 hidnplayr 264
 
1206 hidnplayr 265
	inc	[UDP_PACKETS_TX]
266
 
1159 hidnplayr 267
	DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
1249 hidnplayr 268
	jmp	ETH_sender				       ;
1159 hidnplayr 269
 
1206 hidnplayr 270
  .fail:
271
	; todo: queue the packet
1249 hidnplayr 272
	add	esp, 8+12+8
1206 hidnplayr 273
	ret
1159 hidnplayr 274
 
275
 
1206 hidnplayr 276
 
1249 hidnplayr 277
 
1159 hidnplayr 278
;---------------------------------------------------------------------------
279
;
280
; UDP_API
281
;
282
; This function is called by system function 75
283
;
284
; IN:  subfunction number in bl
285
;      device number in bh
286
;      ecx, edx, .. depends on subfunction
287
;
288
; OUT:
289
;
290
;---------------------------------------------------------------------------
291
 
292
align 4
293
UDP_API:
294
 
295
	movzx	eax, bh
296
	shl	eax, 2
297
 
298
	test	bl, bl
299
	jz	.packets_tx	; 0
300
	dec	bl
301
	jz	.packets_rx	; 1
302
 
303
.error:
304
	mov	eax, -1
305
	ret
306
 
307
.packets_tx:
308
	add	eax, UDP_PACKETS_TX
309
	mov	eax, [eax]
310
	ret
311
 
312
.packets_rx:
313
	add	eax, UDP_PACKETS_RX
314
	mov	eax, [eax]
315
	ret