Subversion Repositories Kolibri OS

Rev

Rev 1197 | 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: 1206 $
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"
1206 hidnplayr 78
	; TODO: First validate the header & checksum!
1159 hidnplayr 79
 
80
	; Look for a socket where
81
	; IP Packet UDP Destination Port = local Port
82
	; IP Packet SA = Remote IP
83
 
1206 hidnplayr 84
	mov	eax, net_sockets
1159 hidnplayr 85
  .try_more:
1206 hidnplayr 86
	mov	bx , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
1159 hidnplayr 87
  .next_socket:
1206 hidnplayr 88
	mov	eax, [eax + SOCKET.NextPtr]
89
	or	eax, eax
1159 hidnplayr 90
	jz	.dump
1206 hidnplayr 91
	cmp	[eax + SOCKET.Domain], AF_INET4
1159 hidnplayr 92
	jne	.next_socket
1206 hidnplayr 93
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
1159 hidnplayr 94
	jne	.next_socket
1206 hidnplayr 95
	cmp	[eax + SOCKET.LocalPort], bx
96
	jne	.next_socket
1159 hidnplayr 97
 
98
	; For dhcp, we must allow any remote server to respond.
99
	; I will accept the first incoming response to be the one
100
	; I bind to, if the socket is opened with a destination IP address of
101
	; 255.255.255.255
1206 hidnplayr 102
	cmp	[eax + SOCKET.RemoteIP], 0xffffffff
103
	je	.ok1
1159 hidnplayr 104
 
1206 hidnplayr 105
	mov	ebx, [esp]
106
	mov	ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet
107
	cmp	[eax + SOCKET.RemoteIP], eax
1159 hidnplayr 108
	jne	.try_more					      ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
109
 
1206 hidnplayr 110
  .ok1:
1159 hidnplayr 111
 
1206 hidnplayr 112
	mov	bx, [edx + UDP_Packet.SourcePort]		      ; Remote port must be 0, or equal to sourceport of packet
1159 hidnplayr 113
 
1206 hidnplayr 114
	cmp	[eax + SOCKET.RemotePort],0
115
	je	.ok2
1159 hidnplayr 116
 
1206 hidnplayr 117
	cmp	[eax + SOCKET.RemotePort], bx
118
	jne	.dump
1159 hidnplayr 119
 
1206 hidnplayr 120
  .ok2:
1159 hidnplayr 121
 
1206 hidnplayr 122
	DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
123
	lea	esi, [edx + UDP_Packet.Data]
124
	movzx	ecx, [edx + UDP_Packet.Length]
125
	rol	cx , 8
126
	sub	cx , UDP_Packet.Data
127
	mov	dx , bx
1159 hidnplayr 128
 
1206 hidnplayr 129
	call	socket_internal_receiver
1159 hidnplayr 130
 
1206 hidnplayr 131
	inc	[UDP_PACKETS_RX]
1159 hidnplayr 132
 
1206 hidnplayr 133
  .dump:
134
	DEBUGF 1,"Dumping UDP packet\n"
1159 hidnplayr 135
	call	kernel_free
136
	add	esp, 4 ; pop (balance stack)
137
 
138
	ret
139
 
140
 
141
 
142
 
143
;-----------------------------------------------------------------
144
;
145
; Note: UDP works only on top of IP protocol :)
146
;
147
; IN: eax = dest ip
148
;     ebx = source ip
149
;     ecx = data length
1196 hidnplayr 150
;     edx = remote port shl 16 + local port (both in INET order)
1159 hidnplayr 151
;     esi = data offset
152
;
153
;-----------------------------------------------------------------
154
 
1196 hidnplayr 155
UDP_create_packet:
1159 hidnplayr 156
 
1206 hidnplayr 157
	DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
1159 hidnplayr 158
 
159
	push	edx esi
160
 
161
	add	ecx, UDP_Packet.Data
162
	mov	di , IP_PROTO_UDP
163
 
164
;       dx  = fragment id
165
 
1196 hidnplayr 166
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
1159 hidnplayr 167
	cmp	edi, -1
1206 hidnplayr 168
	je	.fail
1159 hidnplayr 169
 
170
	mov	byte[edi + UDP_Packet.Length], ch
171
	mov	byte[edi + UDP_Packet.Length+1], cl
1197 clevermous 172
	sub	ecx , UDP_Packet.Data
1159 hidnplayr 173
 
174
	pop	esi
175
	push	edi
176
	add	edi, UDP_Packet.Data
177
	push	cx
178
	shr	ecx, 2
179
	rep	movsd
180
	pop	cx
181
	and	cx , 3
182
	rep	movsb
183
	pop	edi
184
 
185
	pop	ecx
186
	mov	dword [edi + UDP_Packet.SourcePort], ecx	; notice: we write both port's at once
187
 
188
	mov	[edi + UDP_Packet.Checksum], 0
189
 
190
	; TODO: calculate checksum using Pseudo-header  (However, using a 0 as checksum shouldnt generate any errors :)
191
 
1206 hidnplayr 192
	inc	[UDP_PACKETS_TX]
193
 
194
	push	edx eax 		     ; TODO: make this work on other protocols besides ethernet
1159 hidnplayr 195
	DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
196
	jmp	ETH_Sender		     ;
197
 
198
  .exit:
199
	ret
200
 
1206 hidnplayr 201
  .fail:
202
	; todo: queue the packet
203
	add	esp, 8
204
	ret
1159 hidnplayr 205
 
206
 
1206 hidnplayr 207
 
1159 hidnplayr 208
;---------------------------------------------------------------------------
209
;
210
; UDP_API
211
;
212
; This function is called by system function 75
213
;
214
; IN:  subfunction number in bl
215
;      device number in bh
216
;      ecx, edx, .. depends on subfunction
217
;
218
; OUT:
219
;
220
;---------------------------------------------------------------------------
221
 
222
align 4
223
UDP_API:
224
 
225
	movzx	eax, bh
226
	shl	eax, 2
227
 
228
	test	bl, bl
229
	jz	.packets_tx	; 0
230
	dec	bl
231
	jz	.packets_rx	; 1
232
 
233
.error:
234
	mov	eax, -1
235
	ret
236
 
237
.packets_tx:
238
	add	eax, UDP_PACKETS_TX
239
	mov	eax, [eax]
240
	ret
241
 
242
.packets_rx:
243
	add	eax, UDP_PACKETS_RX
244
	mov	eax, [eax]
245
	ret