Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved.    ;;
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
 
17
$Revision: 983 $
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
 
48
align 4
49
UDP_init:
50
 
51
	xor	eax, eax
52
	mov	edi, UDP_PACKETS_TX
53
	mov	ecx, 2*MAX_IP
54
	rep	stosd
55
 
56
	ret
57
 
58
 
59
 
60
;-----------------------------------------------------------------
61
;
62
; UDP_Handler:
63
;
64
;  Called by IPv4_handler,
65
;  this procedure will inject the udp data diagrams in the application sockets.
66
;
67
;  IN:  Pointer to buffer in [esp]
68
;       size of buffer in [esp+4]
69
;       pointer to device struct in ebx
70
;       UDP Packet size in ecx
71
;       pointer to UDP Packet data in edx
72
;  OUT: /
73
;
74
;-----------------------------------------------------------------
75
 
76
UDP_Handler:
77
 
78
	DEBUGF 1,"UDP_Handler\n"
79
	; TODO: First validate the header & checksum. Discard buffer if error
80
 
81
	; Look for a socket where
82
	; IP Packet UDP Destination Port = local Port
83
	; IP Packet SA = Remote IP
84
 
85
	mov	esi, net_sockets
86
  .try_more:
87
	mov	ax , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
88
	rol	ax , 8
89
  .next_socket:
90
	mov	esi, [esi + SOCKET.NextPtr]
91
	or	esi, esi
92
	jz	.dump
93
	cmp	[esi + SOCKET.Type], IP_PROTO_UDP
94
	jne	.next_socket
95
	cmp	[esi + SOCKET.LocalPort], ax
96
	jne	.next_socket
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
102
	cmp	[esi + SOCKET.RemoteIP], 0xffffffff
103
	je	@f
104
 
105
	mov	eax, [esp]
106
	mov	eax, [eax + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet
107
	cmp	[esi + SOCKET.RemoteIP], eax
108
	jne	.try_more					      ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
109
 
110
    @@:
111
	DEBUGF 1,"Found valid UDP packet for socket %x\n", esi
112
 
113
 
114
;        sub     ecx, UDP_Packet.Data                    ; get # of bytes in ecx
115
;        mov     eax, ecx
116
 
117
	movzx	ecx, [edx + UDP_Packet.Length]
118
	xchg	cl , ch
119
 
120
;        cmp     ecx, eax                                ; If UDP packet size is bigger then IP packet told us,
121
;        jg      .error                                  ; Something must went wrong!
122
 
123
	lea	ebx, [esi + SOCKET.lock]
124
	call	wait_mutex
125
 
126
	; OK - we have a valid UDP Packet for this socket.
127
	; First, update the sockets remote port number with the incoming msg
128
	; - it will have changed
129
	; from the original ( 69 normally ) to allow further connects
130
	mov	ax, [edx + UDP_Packet.SourcePort]	   ; get the UDP source port
131
	xchg	al, ah
132
	mov	[esi + SOCKET.RemotePort], ax
133
 
134
	; Now, copy data to socket. We have socket address as [eax + sockets].
135
	; We have IP Packet in edx
136
 
137
	add	edx, UDP_Packet.Data
138
	mov	eax, [esi + SOCKET.rxDataCount] 	; get # of bytes already in buffer
139
	DEBUGF 1,"bytes in socket: %u ", eax
140
	lea	edi, [ecx + eax]			; check for buffer overflow
141
	cmp	edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE	;
142
	jg	.dump					;
143
	add	[esi + SOCKET.rxDataCount], ecx 	; increment the count of bytes in buffer
144
	DEBUGF 1,"adding %u bytes\n", ecx
145
 
146
	; ecx has count, edx points to data
147
 
148
	lea	edi, [esi + eax + SOCKETHEADERSIZE]
149
	push	esi
150
	push	ecx
151
	mov	esi, edx
152
	shr	ecx, 2
153
	rep	movsd	       ; copy the data across
154
	pop	ecx
155
	and	ecx, 3
156
	rep	movsb
157
	pop	esi
158
 
159
	DEBUGF 1,"UDP socket updated\n"
160
 
161
	mov	[esi + SOCKET.lock], 0
162
 
163
	; flag an event to the application
164
	mov	eax, [esi + SOCKET.PID] 		; get socket owner PID
165
	mov	ecx, 1
166
	mov	esi, TASK_DATA + TASKDATA.pid
167
 
168
       .next_pid:
169
	cmp	[esi], eax
170
	je	.found_pid
171
	inc	ecx
172
	add	esi, 0x20
173
	cmp	ecx, [TASK_COUNT]
174
	jbe	.next_pid
175
 
176
	jmp	.dump
177
 
178
       .found_pid:
179
	shl	ecx, 8
180
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
181
 
182
	mov	[check_idle_semaphore], 200
183
 
184
       .dump:
185
	DEBUGF 1,"UDP_handler - dumping\n"
186
 
187
	call	kernel_free
188
	add	esp, 4 ; pop (balance stack)
189
 
190
	ret
191
 
192
 
193
 
194
 
195
;-----------------------------------------------------------------
196
;
197
; Note: UDP works only on top of IP protocol :)
198
;
199
; IN: eax = dest ip
200
;     ebx = source ip
201
;     ecx = data length
202
;     edx = remote port shl 16 + local port
203
;     esi = data offset
204
;
205
;-----------------------------------------------------------------
206
 
207
UDP_create_Packet:
208
 
209
	DEBUGF 1,"Create UDP Packet\n"
210
 
211
	push	edx esi
212
 
213
	add	ecx, UDP_Packet.Data
214
	mov	di , IP_PROTO_UDP
215
 
216
;       dx  = fragment id
217
 
218
	call	IPv4_create_Packet				; TODO: figure out a way to choose between IPv4 and IPv6
219
	cmp	edi, -1
220
	je	.exit
221
 
222
	sub	ecx , UDP_Packet.Data
223
	mov	byte[edi + UDP_Packet.Length], ch
224
	mov	byte[edi + UDP_Packet.Length+1], cl
225
 
226
	pop	esi
227
	push	edi
228
	add	edi, UDP_Packet.Data
229
	push	cx
230
	shr	ecx, 2
231
	rep	movsd
232
	pop	cx
233
	and	cx , 3
234
	rep	movsb
235
	pop	edi
236
 
237
	pop	ecx
238
	bswap	ecx						; convert little endian - big endian
239
	rol	ecx, 16 					;
240
	mov	dword [edi + UDP_Packet.SourcePort], ecx	; notice: we write both port's at once
241
 
242
 
243
	mov	[edi + UDP_Packet.Checksum], 0
244
 
245
	; TODO: calculate checksum using Pseudo-header  (However, using a 0 as checksum shouldnt generate any errors :)
246
 
247
	push	ebx eax 		     ; TODO: make this work on other protocols besides ethernet
248
	mov	ebx,edx 		     ;
249
	DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
250
	jmp	ETH_Sender		     ;
251
 
252
  .exit:
253
	ret
254
 
255
 
256
 
257
;---------------------------------------------------------------------------
258
;
259
; UDP_API
260
;
261
; This function is called by system function 75
262
;
263
; IN:  subfunction number in bl
264
;      device number in bh
265
;      ecx, edx, .. depends on subfunction
266
;
267
; OUT:
268
;
269
;---------------------------------------------------------------------------
270
 
271
align 4
272
UDP_API:
273
 
274
	movzx	eax, bh
275
	shl	eax, 2
276
 
277
	test	bl, bl
278
	jz	.packets_tx	; 0
279
	dec	bl
280
	jz	.packets_rx	; 1
281
 
282
.error:
283
	mov	eax, -1
284
	ret
285
 
286
.packets_tx:
287
	add	eax, UDP_PACKETS_TX
288
	mov	eax, [eax]
289
	ret
290
 
291
.packets_rx:
292
	add	eax, UDP_PACKETS_RX
293
	mov	eax, [eax]
294
	ret