Subversion Repositories Kolibri OS

Rev

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