Subversion Repositories Kolibri OS

Rev

Rev 1173 | 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
 
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
 
1196 hidnplayr 76
UDP_handler:
1159 hidnplayr 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
;        sub     ecx, UDP_Packet.Data                    ; get # of bytes in ecx
114
;        mov     eax, ecx
115
 
116
	movzx	ecx, [edx + UDP_Packet.Length]
117
	xchg	cl , ch
118
 
119
;        cmp     ecx, eax                                ; If UDP packet size is bigger then IP packet told us,
120
;        jg      .error                                  ; Something must went wrong!
121
 
122
	lea	ebx, [esi + SOCKET.lock]
123
	call	wait_mutex
124
 
125
	; OK - we have a valid UDP Packet for this socket.
126
	; First, update the sockets remote port number with the incoming msg
127
	; - it will have changed
128
	; from the original ( 69 normally ) to allow further connects
129
	mov	ax, [edx + UDP_Packet.SourcePort]	   ; get the UDP source port
130
	xchg	al, ah
131
	mov	[esi + SOCKET.RemotePort], ax
132
 
133
	; Now, copy data to socket. We have socket address as [eax + sockets].
134
	; We have IP Packet in edx
135
 
136
	add	edx, UDP_Packet.Data
137
	mov	eax, [esi + SOCKET.rxDataCount] 	; get # of bytes already in buffer
138
	DEBUGF 1,"bytes in socket: %u ", eax
139
	lea	edi, [ecx + eax]			; check for buffer overflow
140
	cmp	edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE	;
141
	jg	.dump					;
142
	add	[esi + SOCKET.rxDataCount], ecx 	; increment the count of bytes in buffer
143
	DEBUGF 1,"adding %u bytes\n", ecx
144
 
145
	; ecx has count, edx points to data
146
 
147
	lea	edi, [esi + eax + SOCKETHEADERSIZE]
148
	push	esi
149
	push	ecx
150
	mov	esi, edx
151
	shr	ecx, 2
152
	rep	movsd	       ; copy the data across
153
	pop	ecx
154
	and	ecx, 3
155
	rep	movsb
156
	pop	esi
157
 
158
	DEBUGF 1,"UDP socket updated\n"
159
 
160
	mov	[esi + SOCKET.lock], 0
161
 
162
	; flag an event to the application
163
	mov	eax, [esi + SOCKET.PID] 		; get socket owner PID
164
	mov	ecx, 1
165
	mov	esi, TASK_DATA + TASKDATA.pid
166
 
167
       .next_pid:
168
	cmp	[esi], eax
169
	je	.found_pid
170
	inc	ecx
171
	add	esi, 0x20
172
	cmp	ecx, [TASK_COUNT]
173
	jbe	.next_pid
174
 
175
	jmp	.dump
176
 
177
       .found_pid:
178
	shl	ecx, 8
179
	or	[ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
180
 
181
	mov	[check_idle_semaphore], 200
182
 
183
       .dump:
184
	DEBUGF 1,"UDP_handler - dumping\n"
185
 
186
	call	kernel_free
187
	add	esp, 4 ; pop (balance stack)
188
 
189
	ret
190
 
191
 
192
 
193
 
194
;-----------------------------------------------------------------
195
;
196
; Note: UDP works only on top of IP protocol :)
197
;
198
; IN: eax = dest ip
199
;     ebx = source ip
200
;     ecx = data length
1196 hidnplayr 201
;     edx = remote port shl 16 + local port (both in INET order)
1159 hidnplayr 202
;     esi = data offset
203
;
204
;-----------------------------------------------------------------
205
 
1196 hidnplayr 206
UDP_create_packet:
1159 hidnplayr 207
 
208
	DEBUGF 1,"Create UDP Packet\n"
209
 
210
	push	edx esi
211
 
212
	add	ecx, UDP_Packet.Data
213
	mov	di , IP_PROTO_UDP
214
 
215
;       dx  = fragment id
216
 
1196 hidnplayr 217
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
1159 hidnplayr 218
	cmp	edi, -1
219
	je	.exit
220
 
1196 hidnplayr 221
	sub	ecx , UDP_Packet.Data
1159 hidnplayr 222
	mov	byte[edi + UDP_Packet.Length], ch
223
	mov	byte[edi + UDP_Packet.Length+1], cl
224
 
225
	pop	esi
226
	push	edi
227
	add	edi, UDP_Packet.Data
228
	push	cx
229
	shr	ecx, 2
230
	rep	movsd
231
	pop	cx
232
	and	cx , 3
233
	rep	movsb
234
	pop	edi
235
 
236
	pop	ecx
1196 hidnplayr 237
;        bswap   ecx                                             ; convert little endian - big endian
238
;        rol     ecx, 16                                         ;
1159 hidnplayr 239
	mov	dword [edi + UDP_Packet.SourcePort], ecx	; notice: we write both port's at once
240
 
241
 
242
	mov	[edi + UDP_Packet.Checksum], 0
243
 
244
	; TODO: calculate checksum using Pseudo-header  (However, using a 0 as checksum shouldnt generate any errors :)
245
 
246
	push	ebx eax 		     ; TODO: make this work on other protocols besides ethernet
247
	mov	ebx,edx 		     ;
248
	DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
249
	jmp	ETH_Sender		     ;
250
 
251
  .exit:
252
	ret
253
 
254
 
255
 
256
;---------------------------------------------------------------------------
257
;
258
; UDP_API
259
;
260
; This function is called by system function 75
261
;
262
; IN:  subfunction number in bl
263
;      device number in bh
264
;      ecx, edx, .. depends on subfunction
265
;
266
; OUT:
267
;
268
;---------------------------------------------------------------------------
269
 
270
align 4
271
UDP_API:
272
 
273
	movzx	eax, bh
274
	shl	eax, 2
275
 
276
	test	bl, bl
277
	jz	.packets_tx	; 0
278
	dec	bl
279
	jz	.packets_rx	; 1
280
 
281
.error:
282
	mov	eax, -1
283
	ret
284
 
285
.packets_tx:
286
	add	eax, UDP_PACKETS_TX
287
	mov	eax, [eax]
288
	ret
289
 
290
.packets_rx:
291
	add	eax, UDP_PACKETS_RX
292
	mov	eax, [eax]
293
	ret