Subversion Repositories Kolibri OS

Rev

Rev 1208 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1208 Rev 1249
Line 12... Line 12...
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 16... Line 16...
16
 
16
 
Line 17... Line 17...
17
$Revision: 1208 $
17
$Revision: 1249 $
18
 
18
 
19
 
19
 
Line 73... Line 73...
73
;-----------------------------------------------------------------
73
;-----------------------------------------------------------------
74
align 4
74
align 4
75
UDP_handler:
75
UDP_handler:
Line 76... Line 76...
76
 
76
 
77
	DEBUGF 1,"UDP_Handler\n"
77
	DEBUGF 1,"UDP_Handler\n"
-
 
78
	; First validate, checksum:
-
 
79
 
-
 
80
	DEBUGF 1,"Real UDP checksum: %x\n", [edx + UDP_Packet.Checksum]:4
-
 
81
	mov    [edx + UDP_Packet.Checksum], 0
-
 
82
 
-
 
83
	pusha
-
 
84
 
-
 
85
	rol	cx, 8
-
 
86
	push	cx
-
 
87
	rol	cx, 8
-
 
88
	push	word IP_PROTO_UDP shl 8
-
 
89
	push	edi
-
 
90
	push	esi
-
 
91
 
-
 
92
	mov	esi, edx
-
 
93
	xor	edx, edx
-
 
94
	call	checksum_1
-
 
95
; Checksum for pseudoheader
-
 
96
	mov	ecx, 12
-
 
97
	mov	esi, esp
-
 
98
	call	checksum_1
-
 
99
	add	esp, 12
-
 
100
	call	checksum_2
-
 
101
 
-
 
102
	popa
-
 
103
 
Line 78... Line 104...
78
	; TODO: First validate the header & checksum!
104
 
79
 
105
 
80
	; Look for a socket where
106
	; Look for a socket where
Line 81... Line 107...
81
	; IP Packet UDP Destination Port = local Port
107
	; IP Packet UDP Destination Port = local Port
82
	; IP Packet SA = Remote IP
108
	; IP Packet SA = Remote IP
83
 
109
 
84
	mov	eax, net_sockets
110
	mov	eax, net_sockets
85
  .try_more:
111
  .try_more:
86
	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
87
  .next_socket:
113
  .next_socket:
88
	mov	eax, [eax + SOCKET.NextPtr]
114
	mov	eax, [eax + SOCKET_head.NextPtr]
89
	or	eax, eax
115
	or	eax, eax
90
	jz	.dump
116
	jz	.dump
91
	cmp	[eax + SOCKET.Domain], AF_INET4
117
	cmp	[eax + SOCKET_head.Domain], AF_INET4
92
	jne	.next_socket
118
	jne	.next_socket
93
	cmp	[eax + SOCKET.Type], IP_PROTO_UDP
119
	cmp	[eax + SOCKET_head.Type], IP_PROTO_UDP
Line 94... Line 120...
94
	jne	.next_socket
120
	jne	.next_socket
Line 95... Line 121...
95
	cmp	[eax + SOCKET.LocalPort], bx
121
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
96
	jne	.next_socket
122
	jne	.next_socket
97
 
123
 
98
	DEBUGF 1,"found socket with matching domain, type and localport\n"
124
	DEBUGF 1,"found socket with matching domain, type and localport\n"
99
 
125
 
100
	; For dhcp, we must allow any remote server to respond.
126
	; For dhcp, we must allow any remote server to respond.
Line 101... Line 127...
101
	; I will accept the first incoming response to be the one
127
	; 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
128
	; I bind to, if the socket is opened with a destination IP address of
103
	; 255.255.255.255
129
	; 255.255.255.255
104
	cmp	[eax + SOCKET.RemoteIP], 0xffffffff
130
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
Line 105... Line 131...
105
	je	.ok1
131
	je	.ok1
106
 
132
 
Line 107... Line 133...
107
	mov	ebx, [esp]
133
	mov	ebx, [esp]
Line 108... Line 134...
108
	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
109
	cmp	[eax + SOCKET.RemoteIP], ebx
135
	cmp	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
Line 110... Line 136...
110
	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
111
 
137
 
Line 112... Line 138...
112
 
138
 
Line 113... Line 139...
113
	DEBUGF 1,"Remote Ip matches\n"
139
	DEBUGF 1,"Remote Ip matches\n"
Line 128... Line 154...
128
	movzx	ecx, [edx + UDP_Packet.Length]
154
	movzx	ecx, [edx + UDP_Packet.Length]
129
	rol	cx , 8
155
	rol	cx , 8
130
	sub	cx , UDP_Packet.Data
156
	sub	cx , UDP_Packet.Data
131
	mov	dx , bx
157
	mov	dx , bx
Line 132... Line -...
132
 
-
 
Line -... Line 158...
-
 
158
 
-
 
159
 
-
 
160
	lea	ebx, [eax + SOCKET_head.lock]
-
 
161
	call	wait_mutex
133
	call	socket_internal_receiver
162
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], dx	       ; update remote port number
Line -... Line 163...
-
 
163
	mov	[eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi
-
 
164
	inc	[UDP_PACKETS_RX]
-
 
165
 
-
 
166
	pop	edi
-
 
167
	add	esp, 4
-
 
168
 
-
 
169
	sub	esi, edi
-
 
170
	xchg	esi, edi
134
 
171
	jmp	socket_internal_receiver
135
	inc	[UDP_PACKETS_RX]
172
 
136
 
173
 
137
  .dump:
174
  .dump:
Line 144... Line 181...
144
 
181
 
145
 
182
 
146
 
183
 
147
;-----------------------------------------------------------------
184
;-----------------------------------------------------------------
148
;
185
;
149
; Note: UDP works only on top of IP protocol :)
-
 
150
;
186
; UDP_socket_send
151
; IN: eax = dest ip
-
 
152
;     ebx = source ip
187
;
153
;     ecx = data length
188
; IN: eax = socket pointer
154
;     edx = remote port shl 16 + local port (both in INET order)
189
;     ecx = number of bytes to send
Line -... Line 190...
-
 
190
;     esi = pointer to data
155
;     esi = data offset
191
;
-
 
192
;-----------------------------------------------------------------
-
 
193
 
-
 
194
align 4
-
 
195
UDP_socket_send:
-
 
196
 
-
 
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",\
Line 156... Line 199...
156
;
199
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
Line -... Line 200...
-
 
200
	[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
-
 
201
	mov	ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
-
 
202
	mov	eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
-
 
203
 
-
 
204
	DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
-
 
205
 
-
 
206
	mov	di , IP_PROTO_UDP
-
 
207
 
157
;-----------------------------------------------------------------
208
	sub	esp, 8						; reserve some place in stack for later
Line 158... Line 209...
158
 
209
 
159
UDP_create_packet:
-
 
Line 160... Line 210...
160
 
210
; Create the pseudoheader in stack,
Line -... Line 211...
-
 
211
; (now that we still have all the variables that are needed.)
161
	DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
212
	push	dword IP_PROTO_UDP shl 8
162
 
213
	push	eax
163
	push	edx esi
214
	push	ebx
Line -... Line 215...
-
 
215
 
164
 
216
	add	ecx, UDP_Packet.Data
-
 
217
 
-
 
218
; TODO: fill in:   dx  = fragment id
165
	add	ecx, UDP_Packet.Data
219
 
166
	mov	di , IP_PROTO_UDP
220
	push	edx esi
-
 
221
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
Line 167... Line 222...
167
 
222
	cmp	edi, -1
168
;       dx  = fragment id
223
	je	.fail
-
 
224
 
169
 
225
	mov	[esp + 8 + 12], eax				; pointer to buffer start
170
	call	IPv4_create_packet				; TODO: figure out a way to choose between IPv4 and IPv6
-
 
171
	cmp	edi, -1
226
	mov	[esp + 8 + 12 + 4], edx 			; buffer size
172
	je	.fail
227
 
173
 
228
	rol	cx, 8
174
	mov	byte[edi + UDP_Packet.Length], ch
229
	mov	[edi + UDP_Packet.Length], cx
175
	mov	byte[edi + UDP_Packet.Length+1], cl
230
	mov	[esp + 8 + 10], cx
176
	sub	ecx , UDP_Packet.Data
231
	ror	cx, 8
Line 177... Line -...
177
 
-
 
178
	pop	esi
232
 
-
 
233
	pop	esi
Line -... Line 234...
-
 
234
	push	edi ecx
-
 
235
	sub	ecx, UDP_Packet.Data
-
 
236
	add	edi, UDP_Packet.Data
-
 
237
	shr	ecx, 2
-
 
238
	rep	movsd
-
 
239
	mov	ecx, [esp]
-
 
240
	and	cx , 3
-
 
241
	rep	movsb
-
 
242
	pop	ecx edi
-
 
243
 
-
 
244
	pop	dword [edi + UDP_Packet.SourcePort]		      ; fill in both portnumbers
179
	push	edi
245
	mov	[edi + UDP_Packet.Checksum], 0			; set it to zero, to calculate checksum
180
	add	edi, UDP_Packet.Data
-
 
181
	push	cx
-
 
Line 182... Line 246...
182
	shr	ecx, 2
246
 
Line 183... Line -...
183
	rep	movsd
-
 
184
	pop	cx
247
; Checksum for UDP header + data
185
	and	cx , 3
248
	xor	edx, edx
186
	rep	movsb
-
 
187
	pop	edi
-
 
188
 
-
 
Line 189... Line 249...
189
	pop	ecx
249
	mov	esi, edi
190
	mov	dword [edi + UDP_Packet.SourcePort], ecx	; notice: we write both port's at once
250
	call	checksum_1
191
 
251
; Checksum for pseudoheader
192
	mov	[edi + UDP_Packet.Checksum], 0
252
	mov	ecx, 12
Line -... Line 253...
-
 
253
	mov	esi, esp
193
 
254
	call	checksum_1
194
	; TODO: calculate checksum using Pseudo-header  (However, using a 0 as checksum shouldnt generate any errors :)
255
	add	esp, 12 					; remove the pseudoheader from stack
195
 
256
; Now create the final checksum and store it in UDP header
196
	inc	[UDP_PACKETS_TX]
257
	call	checksum_2
197
 
258
	mov	[edi + UDP_Packet.Checksum], dx