Subversion Repositories Kolibri OS

Rev

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