Subversion Repositories Kolibri OS

Rev

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

Rev 1530 Rev 1542
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2010. 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: 1530 $
17
$Revision: 1542 $
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
;-----------------------------------------------------------------
43
;-----------------------------------------------------------------
44
macro	UDP_init {
44
macro	UDP_init {
45
 
45
 
46
	xor	eax, eax
46
	xor	eax, eax
47
	mov	edi, UDP_PACKETS_TX
47
	mov	edi, UDP_PACKETS_TX
48
	mov	ecx, 2*MAX_IP
48
	mov	ecx, 2*MAX_IP
49
	rep	stosd
49
	rep	stosd
50
}
50
}
51
 
51
 
52
 
52
 
53
macro	UDP_checksum	IP1, IP2  { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx
53
macro	UDP_checksum	IP1, IP2  { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx
54
 
54
 
55
; Pseudoheader
55
; Pseudoheader
56
	mov	edx, IP_PROTO_UDP
56
	mov	edx, IP_PROTO_UDP
57
 
57
 
58
	add	dl, [IP1+1]
58
	add	dl, [IP1+1]
59
	adc	dh, [IP1+0]
59
	adc	dh, [IP1+0]
60
	adc	dl, [IP1+3]
60
	adc	dl, [IP1+3]
61
	adc	dh, [IP1+2]
61
	adc	dh, [IP1+2]
62
 
62
 
63
	adc	dl, [IP2+1]
63
	adc	dl, [IP2+1]
64
	adc	dh, [IP2+0]
64
	adc	dh, [IP2+0]
65
	adc	dl, [IP2+3]
65
	adc	dl, [IP2+3]
66
	adc	dh, [IP2+2]
66
	adc	dh, [IP2+2]
67
 
67
 
68
	adc	dl, cl ; byte[esi+UDP_Packet.Length+1]
68
	adc	dl, cl ; byte[esi+UDP_Packet.Length+1]
69
	adc	dh, ch ; byte[esi+UDP_Packet.Length+0]
69
	adc	dh, ch ; byte[esi+UDP_Packet.Length+0]
70
 
70
 
71
; Done with pseudoheader, now do real header
71
; Done with pseudoheader, now do real header
72
	adc	dl, byte[esi+UDP_Packet.SourcePort+1]
72
	adc	dl, byte[esi+UDP_Packet.SourcePort+1]
73
	adc	dh, byte[esi+UDP_Packet.SourcePort+0]
73
	adc	dh, byte[esi+UDP_Packet.SourcePort+0]
74
 
74
 
75
	adc	dl, byte[esi+UDP_Packet.DestinationPort+1]
75
	adc	dl, byte[esi+UDP_Packet.DestinationPort+1]
76
	adc	dh, byte[esi+UDP_Packet.DestinationPort+0]
76
	adc	dh, byte[esi+UDP_Packet.DestinationPort+0]
77
 
77
 
78
	adc	dl, byte[esi+UDP_Packet.Length+1]
78
	adc	dl, byte[esi+UDP_Packet.Length+1]
79
	adc	dh, byte[esi+UDP_Packet.Length+0]
79
	adc	dh, byte[esi+UDP_Packet.Length+0]
80
 
80
 
81
	adc	edx, 0
81
	adc	edx, 0
82
 
82
 
83
; Done with header, now do data
83
; Done with header, now do data
84
	push	esi
84
	push	esi
85
	movzx	ecx, [esi+UDP_Packet.Length]
85
	movzx	ecx, [esi+UDP_Packet.Length]
86
	rol	cx , 8
86
	rol	cx , 8
87
	sub	cx , UDP_Packet.Data
87
	sub	cx , UDP_Packet.Data
88
	add	esi, UDP_Packet.Data
88
	add	esi, UDP_Packet.Data
89
 
89
 
90
	call	checksum_1
90
	call	checksum_1
91
	call	checksum_2
91
	call	checksum_2
92
	pop	esi
92
	pop	esi
93
 
93
 
94
	add	[esi+UDP_Packet.Checksum], dx	; this final instruction will set or clear ZF :)
94
	add	[esi+UDP_Packet.Checksum], dx	; this final instruction will set or clear ZF :)
95
 
95
 
96
}
96
}
97
 
97
 
98
 
98
 
99
;-----------------------------------------------------------------
99
;-----------------------------------------------------------------
100
;
100
;
101
; UDP_input:
101
; UDP_input:
102
;
102
;
103
;  Called by IPv4_input,
103
;  Called by IPv4_input,
104
;  this procedure will inject the udp data diagrams in the application sockets.
104
;  this procedure will inject the udp data diagrams in the application sockets.
105
;
105
;
106
;  IN:   [esp]  = Pointer to buffer
106
;  IN:   [esp]  = Pointer to buffer
107
;       [esp+4] = size of buffer
107
;       [esp+4] = size of buffer
108
;       ebx = ptr to device struct
108
;       ebx = ptr to device struct
109
;       ecx = UDP Packet size
109
;       ecx = UDP Packet size
110
;       edx = ptr to UDP header
110
;       edx = ptr to UDP header
111
;
111
;
112
;       esi = ipv4 source address
112
;       esi = ipv4 source address
113
;       edi = ipv4 dest   address
113
;       edi = ipv4 dest   address
114
;
114
;
115
;  OUT: /
115
;  OUT: /
116
;
116
;
117
;-----------------------------------------------------------------
117
;-----------------------------------------------------------------
118
align 4
118
align 4
119
UDP_input:
119
UDP_input:
120
 
120
 
121
	DEBUGF	1,"UDP_input, size:%u\n", ecx
121
	DEBUGF	1,"UDP_input, size:%u\n", ecx
122
 
122
 
123
; First validate, checksum:
123
; First validate, checksum:
124
	neg	[edx+UDP_Packet.Checksum]	; substract chechksum from 0
124
	neg	[edx+UDP_Packet.Checksum]	; substract chechksum from 0
125
	jz	.no_checksum			; if checksum is zero, it is considered valid and we continue processing
125
	jz	.no_checksum			; if checksum is zero, it is considered valid and we continue processing
126
						; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
126
						; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
127
 
127
 
128
	push	edx
128
	push	edx
129
	push	edi
129
	push	edi
130
	push	esi
130
	push	esi
131
	mov	esi, edx
131
	mov	esi, edx
132
	UDP_checksum (esp), (esp+4)
132
	UDP_checksum (esp), (esp+4)
133
	pop	edi
133
	pop	edi
134
	pop	esi	; we dont need it, but it is smaller then add esp, 4
134
	pop	esi	; we dont need it, but it is smaller then add esp, 4
135
	pop	edx
135
	pop	edx
136
	jnz	.checksum_mismatch
136
	jnz	.checksum_mismatch
137
 
137
 
138
  .no_checksum:
138
  .no_checksum:
139
	DEBUGF	1,"UDP Checksum is correct\n"
139
	DEBUGF	1,"UDP Checksum is correct\n"
140
 
140
 
141
	; Look for a socket where
141
	; Look for a socket where
142
	; IP Packet UDP Destination Port = local Port
142
	; IP Packet UDP Destination Port = local Port
143
	; IP Packet SA = Remote IP
143
	; IP Packet SA = Remote IP
144
 
144
 
145
	mov	eax, net_sockets
145
	mov	eax, net_sockets
146
  .try_more:
146
  .try_more:
147
	mov	si , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
147
	mov	si , [edx + UDP_Packet.DestinationPort]   ; get the local port from the IP Packet's UDP header
148
	rol	si , 8
148
	rol	si , 8
149
  .next_socket:
149
  .next_socket:
150
	mov	eax, [eax + SOCKET.NextPtr]
150
	mov	eax, [eax + SOCKET.NextPtr]
151
	or	eax, eax
151
	or	eax, eax
152
	jz	.dump
152
	jz	.dump
153
	cmp	[eax + SOCKET.Domain], AF_INET4
153
	cmp	[eax + SOCKET.Domain], AF_INET4
154
	jne	.next_socket
154
	jne	.next_socket
155
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
155
	cmp	[eax + SOCKET.Protocol], IP_PROTO_UDP
156
	jne	.next_socket
156
	jne	.next_socket
157
	cmp	[eax + UDP_SOCKET.LocalPort], si
157
	cmp	[eax + UDP_SOCKET.LocalPort], si
158
	jne	.next_socket
158
	jne	.next_socket
159
 
159
 
160
	DEBUGF	1,"using socket: %x\n", eax
160
	DEBUGF	1,"using socket: %x\n", eax
161
 
161
 
162
	;;; TODO: when packet is processed, check more sockets!
162
	;;; TODO: when packet is processed, check more sockets!
163
 
163
 
164
	cmp	[eax + IP_SOCKET.RemoteIP], 0xffffffff
164
	cmp	[eax + IP_SOCKET.RemoteIP], 0xffffffff
165
	je	@f
165
	je	@f
166
	cmp	[eax + IP_SOCKET.RemoteIP], edi 	; edi is the packets source address
166
	cmp	[eax + IP_SOCKET.RemoteIP], edi 	; edi is the packets source address
167
	jne	.try_more
167
	jne	.try_more
168
       @@:
168
       @@:
169
 
169
 
170
	cmp	[eax + UDP_SOCKET.firstpacket], 0
170
	cmp	[eax + UDP_SOCKET.firstpacket], 0
171
	jz	.updateport
171
	jz	.updateport
172
 
172
 
173
	mov	si, [edx + UDP_Packet.SourcePort]
173
	mov	si, [edx + UDP_Packet.SourcePort]
174
	rol	si, 8
174
	rol	si, 8
175
	cmp	[eax + UDP_SOCKET.RemotePort], si
175
	cmp	[eax + UDP_SOCKET.RemotePort], si
176
	jne	.dump
176
	jne	.dump
177
 
177
 
178
	push	ebx
178
	push	ebx
179
	lea	ebx, [eax + SOCKET.lock]
179
	lea	ebx, [eax + SOCKET.lock]
180
	call	wait_mutex
180
	call	wait_mutex
181
	pop	ebx
181
	pop	ebx
182
 
182
 
183
  .updatesock:
183
  .updatesock:
184
	inc	[UDP_PACKETS_RX]
184
	inc	[UDP_PACKETS_RX]
185
	DEBUGF	1,"Found valid UDP packet for socket %x\n", eax
185
	DEBUGF	1,"Found valid UDP packet for socket %x\n", eax
186
	lea	esi, [edx + UDP_Packet.Data]
186
	lea	esi, [edx + UDP_Packet.Data]
187
	movzx	ecx, [edx + UDP_Packet.Length]
187
	movzx	ecx, [edx + UDP_Packet.Length]
188
	rol	cx , 8
188
	rol	cx , 8
189
	sub	cx , UDP_Packet.Data
189
	sub	cx , UDP_Packet.Data
190
 
190
 
191
	jmp	SOCKET_input
191
	jmp	SOCKET_input
192
 
192
 
193
  .updateport:
193
  .updateport:
194
	push	ebx
194
	push	ebx
195
	lea	ebx, [eax + SOCKET.lock]
195
	lea	ebx, [eax + SOCKET.lock]
196
	call	wait_mutex
196
	call	wait_mutex
197
	pop	ebx
197
	pop	ebx
198
 
198
 
199
	mov	si, [edx + UDP_Packet.SourcePort]
199
	mov	si, [edx + UDP_Packet.SourcePort]
200
	rol	si, 8
200
	rol	si, 8
201
	DEBUGF	1,"Changing remote port to: %u\n", si
201
	DEBUGF	1,"Changing remote port to: %u\n", si
202
	mov	[eax + UDP_SOCKET.RemotePort], si
202
	mov	[eax + UDP_SOCKET.RemotePort], si
203
	inc	[eax + UDP_SOCKET.firstpacket]
203
	inc	[eax + UDP_SOCKET.firstpacket]
204
 
204
 
205
	jmp	.updatesock
205
	jmp	.updatesock
206
 
206
 
207
 
207
 
208
  .checksum_mismatch:
208
  .checksum_mismatch:
209
 
209
 
210
	DEBUGF	2,"UDP_Handler - checksum mismatch\n"
210
	DEBUGF	2,"UDP_Handler - checksum mismatch\n"
211
 
211
 
212
  .dump:
212
  .dump:
213
	call	kernel_free
213
	call	kernel_free
214
	add	esp, 4 ; pop (balance stack)
214
	add	esp, 4 ; pop (balance stack)
215
	DEBUGF	2,"UDP_Handler - dumping\n"
215
	DEBUGF	2,"UDP_Handler - dumping\n"
216
 
216
 
217
	ret
217
	ret
218
 
218
 
219
 
219
 
220
 
220
 
221
 
221
 
222
;-----------------------------------------------------------------
222
;-----------------------------------------------------------------
223
;
223
;
224
; UDP_output
224
; UDP_output
225
;
225
;
226
; IN: eax = socket pointer
226
; IN: eax = socket pointer
227
;     ecx = number of bytes to send
227
;     ecx = number of bytes to send
228
;     esi = pointer to data
228
;     esi = pointer to data
229
;
229
;
230
;-----------------------------------------------------------------
230
;-----------------------------------------------------------------
231
 
231
 
232
align 4
232
align 4
233
UDP_output:
233
UDP_output:
234
 
234
 
235
	DEBUGF	1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
235
	DEBUGF	1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
236
 
236
 
237
	mov	dx, [eax + UDP_SOCKET.RemotePort]
237
	mov	dx, [eax + UDP_SOCKET.RemotePort]
238
	DEBUGF	1,"remote port: %u\n", dx
238
	DEBUGF	1,"remote port: %u\n", dx
239
	rol	dx, 8
239
	rol	dx, 8
240
	rol	edx, 16
240
	rol	edx, 16
241
	mov	dx, [eax + UDP_SOCKET.LocalPort]
241
	mov	dx, [eax + UDP_SOCKET.LocalPort]
242
	DEBUGF	1,"local port: %u\n", dx
242
	DEBUGF	1,"local port: %u\n", dx
243
	rol	dx, 8
243
	rol	dx, 8
244
 
244
 
245
	mov	ebx, [eax + IP_SOCKET.LocalIP]
245
	mov	ebx, [eax + IP_SOCKET.LocalIP]
246
	mov	eax, [eax + IP_SOCKET.RemoteIP]
246
	mov	eax, [eax + IP_SOCKET.RemoteIP]
247
 
247
 
248
	mov	di, IP_PROTO_UDP shl 8 + 128
248
	mov	di, IP_PROTO_UDP shl 8 + 128
249
	sub	esp, 8						; Data ptr and data size will be placed here
249
	sub	esp, 8						; Data ptr and data size will be placed here
250
	add	ecx, UDP_Packet.Data
250
	add	ecx, UDP_Packet.Data
251
 
251
 
252
;;; TODO: fragment id
252
;;; TODO: fragment id
253
	push	edx esi
253
	push	edx esi
254
	call	IPv4_output
254
	call	IPv4_output
255
	jz	.fail
255
	jz	.fail
256
 
256
 
257
	mov	[esp + 8], eax					; pointer to buffer start
257
	mov	[esp + 8], eax					; pointer to buffer start
258
	mov	[esp + 8 + 4], edx				; buffer size
258
	mov	[esp + 8 + 4], edx				; buffer size
259
 
259
 
260
	mov	[edi + UDP_Packet.Length], cx
260
	mov	[edi + UDP_Packet.Length], cx
261
	rol	[edi + UDP_Packet.Length], 8
261
	rol	[edi + UDP_Packet.Length], 8
262
 
262
 
263
	pop	esi
263
	pop	esi
264
	push	edi ecx
264
	push	edi ecx
265
	sub	ecx, UDP_Packet.Data
265
	sub	ecx, UDP_Packet.Data
266
	add	edi, UDP_Packet.Data
266
	add	edi, UDP_Packet.Data
267
	shr	ecx, 2
267
	shr	ecx, 2
268
	rep	movsd
268
	rep	movsd
269
	mov	ecx, [esp]
269
	mov	ecx, [esp]
270
	and	ecx, 3
270
	and	ecx, 3
271
	rep	movsb
271
	rep	movsb
272
	pop	ecx edi
272
	pop	ecx edi
273
 
273
 
274
	pop	dword [edi + UDP_Packet.SourcePort]
274
	pop	dword [edi + UDP_Packet.SourcePort]
275
 
275
 
276
; Checksum
276
; Checksum
277
	mov	esi, edi
277
	mov	esi, edi
278
	mov	[edi + UDP_Packet.Checksum], 0
278
	mov	[edi + UDP_Packet.Checksum], 0
279
	UDP_checksum (edi-4), (edi-8)				; TODO: fix this, IPv4 packet could have options..
279
	UDP_checksum (edi-4), (edi-8)				; TODO: fix this, IPv4 packet could have options..
280
 
280
 
281
	inc	[UDP_PACKETS_TX]
281
	inc	[UDP_PACKETS_TX]
282
 
282
 
283
	DEBUGF	1,"Sending UDP Packet to device %x\n", ebx
283
	DEBUGF	1,"Sending UDP Packet to device %x\n", ebx
284
 
284
 
285
	call	[ebx + NET_DEVICE.transmit]
285
	call	[ebx + NET_DEVICE.transmit]
286
	ret
286
	ret
287
 
287
 
288
  .fail:
288
  .fail:
289
	DEBUGF	1,"UDP_output: failed\n"
289
	DEBUGF	1,"UDP_output: failed\n"
290
	add	esp, 4+4+8
290
	add	esp, 4+4+8
291
	xor	eax, eax
291
	xor	eax, eax
292
	ret
292
	ret
293
 
293
 
294
 
294
 
295
 
295
 
296
;---------------------------------------------------------------------------
296
;---------------------------------------------------------------------------
297
;
297
;
298
; UDP_API
298
; UDP_API
299
;
299
;
300
; This function is called by system function 75
300
; This function is called by system function 75
301
;
301
;
302
; IN:  subfunction number in bl
302
; IN:  subfunction number in bl
303
;      device number in bh
303
;      device number in bh
304
;      ecx, edx, .. depends on subfunction
304
;      ecx, edx, .. depends on subfunction
305
;
305
;
306
; OUT:
306
; OUT:
307
;
307
;
308
;---------------------------------------------------------------------------
308
;---------------------------------------------------------------------------
309
 
309
 
310
align 4
310
align 4
311
UDP_API:
311
UDP_API:
312
 
312
 
313
	movzx	eax, bh
313
	movzx	eax, bh
314
	shl	eax, 2
314
	shl	eax, 2
315
 
315
 
316
	test	bl, bl
316
	test	bl, bl
317
	jz	.packets_tx	; 0
317
	jz	.packets_tx	; 0
318
	dec	bl
318
	dec	bl
319
	jz	.packets_rx	; 1
319
	jz	.packets_rx	; 1
320
 
320
 
321
.error:
321
.error:
322
	mov	eax, -1
322
	mov	eax, -1
323
	ret
323
	ret
324
 
324
 
325
.packets_tx:
325
.packets_tx:
326
	add	eax, UDP_PACKETS_TX
326
	add	eax, UDP_PACKETS_TX
327
	mov	eax, [eax]
327
	mov	eax, [eax]
328
	ret
328
	ret
329
 
329
 
330
.packets_rx:
330
.packets_rx:
331
	add	eax, UDP_PACKETS_RX
331
	add	eax, UDP_PACKETS_RX
332
	mov	eax, [eax]
332
	mov	eax, [eax]
333
	ret
333
	ret