Subversion Repositories Kolibri OS

Rev

Rev 1249 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1249 Rev 1251
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  UDP.INC                                                        ;;
6
;;  UDP.INC                                                        ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
10
;;    Written by hidnplayr@kolibrios.org                           ;;
11
;;                                                                 ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
16
 
17
$Revision: 1249 $
17
$Revision: 1251 $
18
 
18
 
19
 
19
 
20
struct	UDP_Packet
20
struct	UDP_Packet
21
	.SourcePort		dw  ?
21
	.SourcePort		dw  ?
22
	.DestinationPort	dw  ?
22
	.DestinationPort	dw  ?
23
	.Length 		dw  ?  ; Length of (UDP Header + Data)
23
	.Length 		dw  ?  ; Length of (UDP Header + Data)
24
	.Checksum		dw  ?
24
	.Checksum		dw  ?
25
	.Data:
25
	.Data:
26
 
26
 
27
ends
27
ends
28
 
28
 
29
 
29
 
30
align 4
30
align 4
31
uglobal
31
uglobal
32
	UDP_PACKETS_TX		rd  MAX_IP
32
	UDP_PACKETS_TX		rd  MAX_IP
33
	UDP_PACKETS_RX		rd  MAX_IP
33
	UDP_PACKETS_RX		rd  MAX_IP
34
endg
34
endg
35
 
35
 
36
 
36
 
37
;-----------------------------------------------------------------
37
;-----------------------------------------------------------------
38
;
38
;
39
; UDP_init
39
; UDP_init
40
;
40
;
41
;  This function resets all UDP variables
41
;  This function resets all UDP variables
42
;
42
;
43
;  IN:  /
43
;  IN:  /
44
;  OUT: /
44
;  OUT: /
45
;
45
;
46
;-----------------------------------------------------------------
46
;-----------------------------------------------------------------
47
align 4
47
align 4
48
UDP_init:
48
UDP_init:
49
 
49
 
50
	xor	eax, eax
50
	xor	eax, eax
51
	mov	edi, UDP_PACKETS_TX
51
	mov	edi, UDP_PACKETS_TX
52
	mov	ecx, 2*MAX_IP
52
	mov	ecx, 2*MAX_IP
53
	rep	stosd
53
	rep	stosd
54
 
54
 
55
	ret
55
	ret
56
 
56
 
57
 
57
 
58
 
58
 
59
;-----------------------------------------------------------------
59
;-----------------------------------------------------------------
60
;
60
;
61
; UDP_Handler:
61
; UDP_Handler:
62
;
62
;
63
;  Called by IPv4_handler,
63
;  Called by IPv4_handler,
64
;  this procedure will inject the udp data diagrams in the application sockets.
64
;  this procedure will inject the udp data diagrams in the application sockets.
65
;
65
;
66
;  IN:  Pointer to buffer in [esp]
66
;  IN:  Pointer to buffer in [esp]
67
;       size of buffer in [esp+4]
67
;       size of buffer in [esp+4]
68
;       pointer to device struct in ebx
68
;       pointer to device struct in ebx
69
;       UDP Packet size in ecx
69
;       UDP Packet size in ecx
70
;       pointer to UDP Packet data in edx
70
;       pointer to UDP Packet data in edx
71
;  OUT: /
71
;  OUT: /
72
;
72
;
73
;-----------------------------------------------------------------
73
;-----------------------------------------------------------------
74
align 4
74
align 4
75
UDP_handler:
75
UDP_handler:
76
 
76
 
77
	DEBUGF 1,"UDP_Handler\n"
77
	DEBUGF 1,"UDP_Handler\n"
78
	; First validate, checksum:
78
	; First validate, checksum:
79
 
79
 
80
	DEBUGF 1,"Real UDP checksum: %x\n", [edx + UDP_Packet.Checksum]:4
80
	DEBUGF 1,"Real UDP checksum: %x\n", [edx + UDP_Packet.Checksum]:4
81
	mov    [edx + UDP_Packet.Checksum], 0
81
	mov    [edx + UDP_Packet.Checksum], 0
82
 
82
 
83
	pusha
83
	pusha
84
 
84
 
85
	rol	cx, 8
85
	rol	cx, 8
86
	push	cx
86
	push	cx
87
	rol	cx, 8
87
	rol	cx, 8
88
	push	word IP_PROTO_UDP shl 8
88
	push	word IP_PROTO_UDP shl 8
89
	push	edi
89
	push	edi
90
	push	esi
90
	push	esi
91
 
91
 
92
	mov	esi, edx
92
	mov	esi, edx
93
	xor	edx, edx
93
	xor	edx, edx
94
	call	checksum_1
94
	call	checksum_1
95
; Checksum for pseudoheader
95
; Checksum for pseudoheader
96
	mov	ecx, 12
96
	mov	ecx, 12
97
	mov	esi, esp
97
	mov	esi, esp
98
	call	checksum_1
98
	call	checksum_1
99
	add	esp, 12
99
	add	esp, 12
100
	call	checksum_2
100
	call	checksum_2
101
 
101
 
102
	popa
102
	popa
103
 
103
 
104
 
104
 
105
 
105
 
106
	; Look for a socket where
106
	; Look for a socket where
107
	; IP Packet UDP Destination Port = local Port
107
	; IP Packet UDP Destination Port = local Port
108
	; IP Packet SA = Remote IP
108
	; IP Packet SA = Remote IP
109
 
109
 
110
	mov	eax, net_sockets
110
	mov	eax, net_sockets
111
  .try_more:
111
  .try_more:
112
	mov	bx , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
112
	mov	bx , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
113
  .next_socket:
113
  .next_socket:
114
	mov	eax, [eax + SOCKET_head.NextPtr]
114
	mov	eax, [eax + SOCKET_head.NextPtr]
115
	or	eax, eax
115
	or	eax, eax
116
	jz	.dump
116
	jz	.dump
117
	cmp	[eax + SOCKET_head.Domain], AF_INET4
117
	cmp	[eax + SOCKET_head.Domain], AF_INET4
118
	jne	.next_socket
118
	jne	.next_socket
119
	cmp	[eax + SOCKET_head.Type], IP_PROTO_UDP
119
	cmp	[eax + SOCKET_head.Type], IP_PROTO_UDP
120
	jne	.next_socket
120
	jne	.next_socket
121
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
121
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
122
	jne	.next_socket
122
	jne	.next_socket
123
 
123
 
124
	DEBUGF 1,"found socket with matching domain, type and localport\n"
124
	DEBUGF 1,"found socket with matching domain, type and localport\n"
125
 
125
 
126
	; For dhcp, we must allow any remote server to respond.
126
	; For dhcp, we must allow any remote server to respond.
127
	; I will accept the first incoming response to be the one
127
	; I will accept the first incoming response to be the one
128
	; I bind to, if the socket is opened with a destination IP address of
128
	; I bind to, if the socket is opened with a destination IP address of
129
	; 255.255.255.255
129
	; 255.255.255.255
130
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
130
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
131
	je	.ok1
131
	je	.ok1
132
 
132
 
133
	mov	ebx, [esp]
133
	mov	ebx, [esp]
134
	mov	ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet   FIXME
134
	mov	ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet   FIXME
135
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
135
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
136
	jne	.try_more					      ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
136
	jne	.try_more					      ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
137
 
137
 
138
 
138
 
139
	DEBUGF 1,"Remote Ip matches\n"
139
	DEBUGF 1,"Remote Ip matches\n"
140
  .ok1:
140
  .ok1:
141
 
141
 
142
	mov	bx, [edx + UDP_Packet.SourcePort]		      ; Remote port must be 0, or equal to sourceport of packet
142
	mov	bx, [edx + UDP_Packet.SourcePort]		      ; Remote port must be 0, or equal to sourceport of packet
143
 
143
 
144
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], 0
144
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], 0
145
	je	.ok2
145
	je	.ok2
146
 
146
 
147
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
147
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
148
	jne	.dump
148
	jne	.dump
149
 
149
 
150
  .ok2:
150
  .ok2:
151
 
151
 
152
	DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
152
	DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
153
	lea	esi, [edx + UDP_Packet.Data]
153
	lea	esi, [edx + UDP_Packet.Data]
154
	movzx	ecx, [edx + UDP_Packet.Length]
154
	movzx	ecx, [edx + UDP_Packet.Length]
155
	rol	cx , 8
155
	rol	cx , 8
156
	sub	cx , UDP_Packet.Data
156
	sub	cx , UDP_Packet.Data
157
	mov	dx , bx
157
	mov	dx , bx
158
 
158
 
159
 
159
 
160
	lea	ebx, [eax + SOCKET_head.lock]
160
	lea	ebx, [eax + SOCKET_head.lock]
161
	call	wait_mutex
161
	call	wait_mutex
162
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], dx	       ; update remote port number
162
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], dx	       ; update remote port number
163
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi
163
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi
164
	inc	[UDP_PACKETS_RX]
164
	inc	[UDP_PACKETS_RX]
165
 
165
 
166
	pop	edi
166
	pop	edi
167
	add	esp, 4
167
	add	esp, 4
168
 
168
 
169
	sub	esi, edi
169
	sub	esi, edi
170
	xchg	esi, edi
170
	xchg	esi, edi
171
	jmp	socket_internal_receiver
171
	jmp	socket_internal_receiver
172
 
172
 
173
 
173
 
174
  .dump:
174
  .dump:
175
	DEBUGF 1,"Dumping UDP packet\n"
175
	DEBUGF 1,"Dumping UDP packet\n"
176
	call	kernel_free
176
	call	kernel_free
177
	add	esp, 4 ; pop (balance stack)
177
	add	esp, 4 ; pop (balance stack)
178
 
178
 
179
	ret
179
	ret
180
 
180
 
181
 
181
 
182
 
182
 
183
 
183
 
184
;-----------------------------------------------------------------
184
;-----------------------------------------------------------------
185
;
185
;
186
; UDP_socket_send
186
; UDP_socket_send
187
;
187
;
188
; IN: eax = socket pointer
188
; IN: eax = socket pointer
189
;     ecx = number of bytes to send
189
;     ecx = number of bytes to send
190
;     esi = pointer to data
190
;     esi = pointer to data
191
;
191
;
192
;-----------------------------------------------------------------
192
;-----------------------------------------------------------------
193
 
193
 
194
align 4
194
align 4
195
UDP_socket_send:
195
UDP_socket_send:
196
 
196
 
197
	mov	edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once
197
	mov	edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once
198
	DEBUGF	1,"local port: %x, remote port: %x\n",\
198
	DEBUGF	1,"local port: %x, remote port: %x\n",\
199
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
199
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
200
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
200
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
201
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
201
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
202
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
202
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
203
 
203
 
204
	DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
204
	DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
205
 
205
 
206
	mov	di , IP_PROTO_UDP
206
	mov	di , IP_PROTO_UDP
207
 
207
 
208
	sub	esp, 8						; reserve some place in stack for later
208
	sub	esp, 8						; reserve some place in stack for later
209
 
209
 
210
; Create the pseudoheader in stack,
210
; Create the pseudoheader in stack,
211
; (now that we still have all the variables that are needed.)
211
; (now that we still have all the variables that are needed.)
212
	push	dword IP_PROTO_UDP shl 8
212
	push	dword IP_PROTO_UDP shl 8
213
	push	eax
-
 
214
	push	ebx
-
 
215
 
213
 
216
	add	ecx, UDP_Packet.Data
214
	add	ecx, UDP_Packet.Data
217
 
215
 
218
; TODO: fill in:   dx  = fragment id
216
; TODO: fill in:   dx  = fragment id
219
 
217
 
220
	push	edx esi
218
	push	edx esi
221
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
219
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
222
	cmp	edi, -1
220
	cmp	edi, -1
223
	je	.fail
221
	je	.fail
224
 
222
 
225
	mov	[esp + 8 + 12], eax				; pointer to buffer start
223
	mov	[esp + 8 + 4], eax				; pointer to buffer start
226
	mov	[esp + 8 + 12 + 4], edx 			; buffer size
224
	mov	[esp + 8 + 4 + 4], edx 				; buffer size
227
 
225
 
228
	rol	cx, 8
226
	rol	cx, 8
229
	mov	[edi + UDP_Packet.Length], cx
227
	mov	[edi + UDP_Packet.Length], cx
230
	mov	[esp + 8 + 10], cx
228
	mov	[esp + 8 + 2], cx
231
	ror	cx, 8
229
	ror	cx, 8
232
 
230
 
233
	pop	esi
231
	pop	esi
234
	push	edi ecx
232
	push	edi ecx
235
	sub	ecx, UDP_Packet.Data
233
	sub	ecx, UDP_Packet.Data
236
	add	edi, UDP_Packet.Data
234
	add	edi, UDP_Packet.Data
237
	shr	ecx, 2
235
	shr	ecx, 2
238
	rep	movsd
236
	rep	movsd
239
	mov	ecx, [esp]
237
	mov	ecx, [esp]
240
	and	cx , 3
238
	and	ecx, 3
241
	rep	movsb
239
	rep	movsb
242
	pop	ecx edi
240
	pop	ecx edi
243
 
241
 
244
	pop	dword [edi + UDP_Packet.SourcePort]		      ; fill in both portnumbers
242
	pop	dword [edi + UDP_Packet.SourcePort]		      ; fill in both portnumbers
245
	mov	[edi + UDP_Packet.Checksum], 0			; set it to zero, to calculate checksum
243
	mov	[edi + UDP_Packet.Checksum], 0			; set it to zero, to calculate checksum
246
 
244
 
247
; Checksum for UDP header + data
245
; Checksum for UDP header + data
248
	xor	edx, edx
246
	xor	edx, edx
249
	mov	esi, edi
247
	mov	esi, edi
250
	call	checksum_1
248
	call	checksum_1
251
; Checksum for pseudoheader
249
; Checksum for pseudoheader
-
 
250
	pushd	[edi-4]	; destination address
-
 
251
	pushd	[edi-8]	; source address
252
	mov	ecx, 12
252
	mov	ecx, 12
253
	mov	esi, esp
253
	mov	esi, esp
254
	call	checksum_1
254
	call	checksum_1
255
	add	esp, 12 					; remove the pseudoheader from stack
255
	add	esp, 12 					; remove the pseudoheader from stack
256
; Now create the final checksum and store it in UDP header
256
; Now create the final checksum and store it in UDP header
257
	call	checksum_2
257
	call	checksum_2
258
	mov	[edi + UDP_Packet.Checksum], dx
258
	mov	[edi + UDP_Packet.Checksum], dx
259
 
259
 
260
	inc	[UDP_PACKETS_TX]
260
	inc	[UDP_PACKETS_TX]
261
 
261
 
262
	DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
262
	DEBUGF 1,"Sending UDP Packet to device %x\n", ebx      ;
263
	jmp	ETH_sender				       ;
263
	jmp	ETH_sender				       ;
264
 
264
 
265
  .fail:
265
  .fail:
266
	; todo: queue the packet
266
	; todo: queue the packet
267
	add	esp, 8+12+8
267
	add	esp, 8+12+8
268
	ret
268
	ret
269
 
269
 
270
 
270
 
271
 
271
 
272
 
272
 
273
;---------------------------------------------------------------------------
273
;---------------------------------------------------------------------------
274
;
274
;
275
; UDP_API
275
; UDP_API
276
;
276
;
277
; This function is called by system function 75
277
; This function is called by system function 75
278
;
278
;
279
; IN:  subfunction number in bl
279
; IN:  subfunction number in bl
280
;      device number in bh
280
;      device number in bh
281
;      ecx, edx, .. depends on subfunction
281
;      ecx, edx, .. depends on subfunction
282
;
282
;
283
; OUT:
283
; OUT:
284
;
284
;
285
;---------------------------------------------------------------------------
285
;---------------------------------------------------------------------------
286
 
286
 
287
align 4
287
align 4
288
UDP_API:
288
UDP_API:
289
 
289
 
290
	movzx	eax, bh
290
	movzx	eax, bh
291
	shl	eax, 2
291
	shl	eax, 2
292
 
292
 
293
	test	bl, bl
293
	test	bl, bl
294
	jz	.packets_tx	; 0
294
	jz	.packets_tx	; 0
295
	dec	bl
295
	dec	bl
296
	jz	.packets_rx	; 1
296
	jz	.packets_rx	; 1
297
 
297
 
298
.error:
298
.error:
299
	mov	eax, -1
299
	mov	eax, -1
300
	ret
300
	ret
301
 
301
 
302
.packets_tx:
302
.packets_tx:
303
	add	eax, UDP_PACKETS_TX
303
	add	eax, UDP_PACKETS_TX
304
	mov	eax, [eax]
304
	mov	eax, [eax]
305
	ret
305
	ret
306
 
306
 
307
.packets_rx:
307
.packets_rx:
308
	add	eax, UDP_PACKETS_RX
308
	add	eax, UDP_PACKETS_RX
309
	mov	eax, [eax]
309
	mov	eax, [eax]
310
	ret
310
	ret