Subversion Repositories Kolibri OS

Rev

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

Rev 1257 Rev 1473
Line 14... Line 14...
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 18... Line 18...
18
 
18
 
Line 19... Line 19...
19
$Revision: 1257 $
19
$Revision: 1473 $
Line 20... Line 20...
20
 
20
 
Line 111... Line 111...
111
;       pointer to IP Packet data in edx
111
;       pointer to IP Packet data in edx
112
;  OUT: /
112
;  OUT: /
113
;
113
;
114
;-----------------------------------------------------------------
114
;-----------------------------------------------------------------
115
align 4
115
align 4
116
IPv4_handler:	 ; TODO: clean up this mess
116
IPv4_handler:	 ; TODO: implement handler for IP options
117
		 ; for instance, there should be only one piece of code wich make the jump to an underlying protocol, and not two..
-
 
118
		 ; TODO2: add code for IPv4 sockets (raw sockets)
117
		 ; TODO2: add code for IPv4 sockets (raw sockets)
Line 119... Line 118...
119
 
118
 
Line 120... Line -...
120
	DEBUGF	1,"IP_Handler - start\n"
-
 
Line -... Line 119...
-
 
119
	DEBUGF	1,"IP_Handler - start\n"
121
 
120
 
-
 
121
 
122
	push	edx ebx
122
;-------------------------------------------
-
 
123
; Check if the packet still has time to live
-
 
124
 
-
 
125
	cmp	byte [edx + IPv4_Packet.TimeToLive], 0
-
 
126
	je	.dump
-
 
127
 
123
 
128
;--------------------------------------
-
 
129
; First, check if IP packet has options
-
 
130
 
-
 
131
	movzx	eax, [edx + IPv4_Packet.VersionAndIHL]
-
 
132
	and	al , 0x0f					; get IHL(header length)
-
 
133
	cmp	al , 0x05					; IHL!= 5*4(20 bytes)
-
 
134
	jnz	.has_options
-
 
135
 
Line 124... Line 136...
124
	; save checksum, and clear it in original packet
136
 
125
	mov	di , [edx + IPv4_Packet.HeaderChecksum]
-
 
126
	mov	word [edx + IPv4_Packet.HeaderChecksum], 0
-
 
127
 
137
;-------------------------------
128
	; Re-calculate checksum
138
; Now, re-calcualte the checksum
129
	movzx	ecx, byte [edx + IPv4_Packet.VersionAndIHL]	; Calculate Header length by using IHL field
-
 
130
	and	ecx, 0x0000000F  ;
-
 
131
	shl	cx , 2		 ;
139
 
132
	mov	esi, edx
-
 
133
	xor	edx, edx
-
 
134
	call	checksum_1
-
 
135
	call	checksum_2
140
	; Re-calculate checksum
-
 
141
	push	edx ebx
-
 
142
	mov	esi, edx
-
 
143
	call	checksum_ip_header
136
 
144
	pop	ebx edx
Line 137... Line 145...
137
	; now compare the two..
145
 
-
 
146
	; now see if it was correct
-
 
147
	cmp	[edx + IPv4_Packet.HeaderChecksum], 0
-
 
148
	jne	.dump						; if checksum isn't valid then dump packet
-
 
149
 
-
 
150
	DEBUGF	1,"IPv4 Checksum is correct\n"
Line 138... Line 151...
138
	cmp	dx, di
151
 
139
	pop	ebx edx
152
;-------------------------------------------------------
140
	jne	.dump						; if checksum isn't valid then dump packet
153
; Time to find out what interface this packet belongs to
-
 
154
 
141
 
155
; Therefore we will scan the current list of IP's
-
 
156
 
142
	DEBUGF	1,"IPv4 Checksum is correct\n",di
157
	mov	eax, [edx + IPv4_Packet.DestinationAddress]
-
 
158
	mov	edi, BROADCAST
-
 
159
	mov	ecx, MAX_IP+1
-
 
160
 
Line -... Line 161...
-
 
161
  .find_ip_loop:
143
 
162
	cmp	eax, dword [edi]
144
	mov	eax, [edx + IPv4_Packet.DestinationAddress]
163
	jz	.ip_ok
145
	mov	edi, BROADCAST
164
	add	edi, 4
Line 146... Line 165...
146
	mov	ecx, MAX_IP+1
165
	dec	ecx
Line -... Line 166...
-
 
166
	jnz	.find_ip_loop
-
 
167
 
147
	repnz	scasd
168
	; it was not on the list, perhaps it's a loopback ?
Line -... Line 169...
-
 
169
	not	eax
-
 
170
	test	eax, 127 shl 24 ; 127.x.x.x
-
 
171
	jz	.ip_ok
-
 
172
 
148
	jz	.ip_ok
173
	;  TODO: we need to check for broadcasts (other then 255.255.255.255)
149
 
174
 
150
	not	eax
175
	DEBUGF	2,"Destination address does not match!\n"
151
	test	eax, 127 shl 24 ; 127.x.x.x
176
 
152
	jz	.ip_ok
177
	jmp	.dump
Line 153... Line -...
153
 
-
 
154
;  TODO: we need to check for broadcasts (other then 255.255.255.255)
-
 
155
 
-
 
156
	jmp	.dump
-
 
Line 157... Line -...
157
 
-
 
158
  .ip_ok:
-
 
Line 159... Line -...
159
	call	ETH_struc2dev					; TODO: make this work on other protocols too!
-
 
160
	inc	[IP_PACKETS_RX+4*edi]
-
 
Line -... Line 178...
-
 
178
 
-
 
179
 
-
 
180
;---------------------------------------------------
161
	DEBUGF	1,"packet comes from %u.%u.%u.%u\n",\
181
; Now we can update stats and find the device number
162
	[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
182
 
-
 
183
  .ip_ok:
-
 
184
	call	ETH_struc2dev					; TODO: make this work on other protocols too!
-
 
185
	inc	[IP_PACKETS_RX+4*edi]
-
 
186
	DEBUGF	1,"Packet comes from %u.%u.%u.%u\n",\
Line -... Line 187...
-
 
187
	[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
-
 
188
 
163
 
189
 
164
	mov	al , [edx + IPv4_Packet.VersionAndIHL]
-
 
Line 165... Line 190...
165
	and	al , 0x0f					; get IHL(header length)
190
 
166
	cmp	al , 0x05					; IHL!= 5*4(20 bytes)
191
 
167
	jnz	.dump						; TODO: dont dump packets wich have optional fiels !!!                   /!\
192
;----------------------------------
168
 
193
; Check if the packet is fragmented
169
	cmp	byte [edx + IPv4_Packet.TimeToLive], 0
-
 
170
	je	.dump
194
 
171
 
195
	test	[edx + IPv4_Packet.FlagsAndFragmentOffset], 1 shl 5	; Is 'more fragments' flag set ?
172
	movzx	eax, word [edx + IPv4_Packet.FlagsAndFragmentOffset]
196
	jnz	.has_fragments						; If so, we definately have a fragmented packet
Line 173... Line 197...
173
	xchg	al , ah
197
 
174
 
198
	test	[edx + IPv4_Packet.FlagsAndFragmentOffset], 0xff1f	; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
-
 
199
	jnz	.is_last_fragment
-
 
200
 
-
 
201
 
175
	test	ax , 1 shl 13					; Is 'more fragments' flag set ?
202
 
176
	jnz	.yes_fragments					; If so, we definately have a fragmented packet
-
 
177
 
-
 
178
	test	ax , 0x1fff					; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
203
;-------------------------------------------------------------------
Line 179... Line 204...
179
	jnz	.last_fragment
204
; No, it's just a regular IP packet, pass it to the higher protocols
180
 
205
 
Line 201... Line 226...
201
	je	UDP_handler
226
	je	UDP_handler
Line 202... Line 227...
202
 
227
 
203
	cmp	al , IP_PROTO_ICMP
228
	cmp	al , IP_PROTO_ICMP
Line 204... Line 229...
204
	je	ICMP_handler
229
	je	ICMP_handler
Line 205... Line 230...
205
 
230
 
206
	DEBUGF	1,"unknown protocol: %u\n",al
231
	DEBUGF	2,"unknown Internet protocol: %u\n", al
207
 
232
 
208
  .dump:
233
  .dump:
209
	DEBUGF	1,"IP_Handler - done\n"
234
	DEBUGF	2,"IP_Handler - dumping\n"
210
;        inc     [dumped_rx_count]
235
;        inc     [dumped_rx_count]
Line -... Line 236...
-
 
236
	call	kernel_free
-
 
237
	add	esp, 4						; pop (balance stack)
-
 
238
	ret
-
 
239
 
211
	call	kernel_free
240
 
-
 
241
;---------------------------
-
 
242
; Fragmented packet handler
212
	add	esp, 4						; pop (balance stack)
243
 
-
 
244
 
213
	ret
245
  .has_fragments:
Line 214... Line 246...
214
 
246
	movzx	eax, [edx + IPv4_Packet.FlagsAndFragmentOffset]
215
 
247
	xchg	al , ah
-
 
248
	shl	ax , 3
-
 
249
 
-
 
250
	DEBUGF	1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4
-
 
251
 
-
 
252
	test	ax , ax 					; Is this the first packet of the fragment?
-
 
253
	jz	.is_first_fragment
-
 
254
 
-
 
255
 
-
 
256
;-------------------------------------------------------
-
 
257
; We have a fragmented IP packet, but it's not the first
-
 
258
 
-
 
259
	DEBUGF	1,"Middle fragmented packet received!\n"
-
 
260
 
-
 
261
	call	IPv4_find_fragment_slot
-
 
262
	cmp	esi, -1
-
 
263
	je	.dump
-
 
264
 
-
 
265
	mov	word [esi + FRAGMENT_slot.ttl], 15		; Reset the ttl
-
 
266
	mov	esi, [esi + FRAGMENT_slot.ptr]
-
 
267
	or	edi, -1
-
 
268
  .find_last_entry:						; The following routine will try to find the last entry
-
 
269
	cmp	edi, [esi + FRAGMENT_entry.PrevPtr]
-
 
270
	jne	.destroy_slot					; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
-
 
271
	mov	edi, esi
-
 
272
	mov	esi, [esi + FRAGMENT_entry.NextPtr]
-
 
273
	cmp	esi, -1
-
 
274
	jne	.find_last_entry
-
 
275
								; We found the last entry (pointer is now in edi)
-
 
276
								; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
-
 
277
 
-
 
278
	pop	eax						; pointer to packet
-
 
279
	mov	[edi + FRAGMENT_entry.NextPtr], eax		; update pointer of previous entry to the new entry
-
 
280
	mov	[eax + FRAGMENT_entry.NextPtr], -1
Line -... Line 281...
-
 
281
	mov	[eax + FRAGMENT_entry.PrevPtr], edi
-
 
282
	mov	[eax + FRAGMENT_entry.Owner], ebx
-
 
283
 
-
 
284
	add	esp, 4
216
  .yes_fragments:
285
	ret
217
	shl	ax , 3
286
 
218
	DEBUGF	1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4
287
 
219
 
288
;------------------------------------
220
	test	ax , ax 					; Is this the first packet of the fragment?
289
; We have received the first fragment
Line 248... Line 317...
248
 
317
 
249
	add	esp, 4						; balance stack and exit
318
	add	esp, 4						; balance stack and exit
Line -... Line 319...
-
 
319
	ret
-
 
320
 
Line 250... Line -...
250
	ret
-
 
251
 
-
 
252
 
-
 
253
 
-
 
254
  .not_first_fragment:
-
 
255
	DEBUGF	1,"Middle fragmented packet received!\n"
-
 
256
 
-
 
257
	call	.find_fragment_slot
-
 
258
	cmp	esi, -1
-
 
259
	je	.dump
-
 
260
 
-
 
261
	mov	word [esi + FRAGMENT_slot.ttl], 15		; Reset the ttl
-
 
262
	mov	esi, [esi + FRAGMENT_slot.ptr]
-
 
263
	or	edi, -1
-
 
264
     .find_last_entry:						; The following routine will try to find the last entry
-
 
265
	cmp	edi, [esi + FRAGMENT_entry.PrevPtr]
-
 
266
	jne	.destroy_slot					; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
-
 
267
	mov	edi, esi
-
 
268
	mov	esi, [esi + FRAGMENT_entry.NextPtr]
-
 
269
	cmp	esi, -1
-
 
270
	jne	.find_last_entry
-
 
271
								; We found the last entry (pointer is noww in edi)
-
 
272
								; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
-
 
273
 
-
 
274
	pop	eax						; pointer to packet
-
 
275
	mov	[edi + FRAGMENT_entry.NextPtr], eax		; update pointer of previous entry to the new entry
-
 
276
	mov	[eax + FRAGMENT_entry.NextPtr], -1
-
 
277
	mov	[eax + FRAGMENT_entry.PrevPtr], edi
-
 
278
	mov	[eax + FRAGMENT_entry.Owner], ebx
-
 
279
 
-
 
280
	add	esp, 4
-
 
281
	ret
321
 
282
 
322
;-----------------------------------
-
 
323
; We have received the last fragment
283
 
324
 
284
 
325
  .is_last_fragment:
285
  .last_fragment:
326
	DEBUGF	1,"Last fragmented packet received!\n"
Line 286... Line 327...
286
	DEBUGF	1,"Last fragmented packet received!\n"
327
 
287
	call	.find_fragment_slot
328
	call	IPv4_find_fragment_slot
288
	cmp	esi, -1
329
	cmp	esi, -1
289
	je	.dump
330
	je	.dump
-
 
331
 
290
 
332
	mov	esi, [esi + FRAGMENT_slot.ptr]			; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
291
	mov	esi, [esi + FRAGMENT_slot.ptr]			; We found the first entry, let's calculate total size of the packet in eax, so we can allocate a buffer
333
	push	esi
292
	push	esi
334
	xor	eax, eax
293
	xor	eax, eax					;
335
	or	edi, -1
294
	or	edi, -1
336
 
Line 367... Line 409...
367
	and	cx, 3										;
409
	and	cx, 3										;
368
	rep	movsb										;
410
	rep	movsb										;
Line 369... Line 411...
369
 
411
 
370
	push	eax
412
	push	eax
-
 
413
	push	edx										; Push pointer to fragment onto stack
371
	push	edx										; Push pointer to fragment onto stack
414
	mov	ebx, [edx + FRAGMENT_entry.Owner]						; we need to remeber the owner, in case this is the last packet
372
	mov	edx, [edx + FRAGMENT_entry.NextPtr]						; Set edx to the next pointer
415
	mov	edx, [edx + FRAGMENT_entry.NextPtr]						; Set edx to the next pointer
373
	call	kernel_free									; free the previous fragment buffer (this uses the value from stack)
416
	call	kernel_free									; free the previous fragment buffer (this uses the value from stack)
374
	pop	eax
417
	pop	eax
375
	cmp	edx, -1 									; Check if it is last fragment in chain
418
	cmp	edx, -1 									; Check if it is last fragment in chain
Line 379... Line 422...
379
	xchg	cl, ch
422
	xchg	cl, ch
380
	mov	edx, eax
423
	mov	edx, eax
381
	mov	word [edx + IPv4_Packet.TotalLength], cx
424
	mov	word [edx + IPv4_Packet.TotalLength], cx
382
	add	esp, 8
425
	add	esp, 8
Line 383... Line 426...
383
 
426
 
-
 
427
	xchg	cl, ch		    ;
384
	xchg	cl, ch		   ;  This prints the IP packet to the debug board (usefull when using serial output debug..)
428
 
385
	push	ecx  ;;;;
429
	push	ecx		   ;;;;
-
 
430
	push	eax		   ;;;;
386
	push	eax	;;;;
431
 
387
;        mov     esi, edx           ;
432
;        mov     esi, edx           ;  This prints the IP packet to the debug board (usefull when using serial output debug..)
388
;                                   ;
433
;                                   ;
389
;       @@:                         ;
434
;       @@:                         ;
390
;        lodsb                      ;
435
;        lodsb                      ;
391
;        DEBUGF  1,"%x ", eax:2     ;
436
;        DEBUGF  1,"%x ", eax:2     ;
Line 392... Line 437...
392
;        loop    @r                 ;
437
;        loop    @r                 ;
393
 
-
 
394
	movzx	eax, byte [edx + IPv4_Packet.VersionAndIHL]	; Calculate Header length by using IHL field
-
 
395
	and	ax, 0x000F					;
-
 
396
	shl	ax, 2						;
-
 
397
 
-
 
Line -... Line 438...
-
 
438
 
398
	sub	ecx, eax
439
	jmp	.handle_it	    ; edx = buf ptr, ecx = size, [esp] buf ptr, [esp+4], total size, ebx=device ptr
399
 
440
 
400
 
441
  .destroy_slot_pop:
401
	add	eax, edx
442
	add	esp, 4
402
	push	eax
-
 
403
	mov	al , [edx + IPv4_Packet.Protocol]
443
  .destroy_slot:
Line 404... Line -...
404
	mov	esi, [edx + IPv4_Packet.SourceAddress]
-
 
405
	mov	edi, [edx + IPv4_Packet.DestinationAddress]
-
 
Line 406... Line -...
406
	pop	edx						; Offset to data (tcp/udp/icmp/.. Packet)
-
 
407
 
-
 
Line 408... Line -...
408
	cmp	al , IP_PROTO_TCP
-
 
409
	je	TCP_handler
-
 
Line -... Line 444...
-
 
444
	DEBUGF	1,"Destroy fragment slot!\n"
410
 
445
	; TODO!
Line 411... Line 446...
411
	cmp	al , IP_PROTO_UDP
446
	jmp	.dump
412
	je	UDP_handler
447
 
Line 413... Line -...
413
 
-
 
Line 414... Line -...
414
	cmp	al , IP_PROTO_ICMP
-
 
415
	je	ICMP_handler_fragments
-
 
416
 
-
 
417
	DEBUGF	1,"IP_Handler - unknown protocol:%u\n",al
-
 
418
 
-
 
419
	call	kernel_free
-
 
Line 420... Line 448...
420
	add	esp, 8						; pop (balance stack)
448
 
421
 
449
 
Line 437... Line 465...
437
;
465
;
438
; IN: pointer to fragmented packet in edx         ; TODO: the RFC says we should check protocol too
466
; IN: pointer to fragmented packet in edx         ; TODO: the RFC says we should check protocol too
439
; OUT: pointer to slot in edi, -1 on error
467
; OUT: pointer to slot in edi, -1 on error
440
;
468
;
441
;-----------------------------------------------------------------
469
;-----------------------------------------------------------------
442
 
470
align 4
443
  .find_fragment_slot:
471
IPv4_find_fragment_slot:
Line 444... Line 472...
444
 
472
 
445
	push	eax ebx ecx edx
473
	push	eax ebx ecx edx
446
	mov	ax , word [edx + IPv4_Packet.Identification]
474
	mov	ax , word [edx + IPv4_Packet.Identification]
447
	mov	ecx, MAX_FRAGMENTS
475
	mov	ecx, MAX_FRAGMENTS
Line 579... Line 607...
579
	pop	ecx
607
	pop	ecx
580
	mov	[edi + IPv4_Packet.SourceAddress], ecx
608
	mov	[edi + IPv4_Packet.SourceAddress], ecx
581
	pop	ecx
609
	pop	ecx
582
	mov	[edi + IPv4_Packet.DestinationAddress], ecx
610
	mov	[edi + IPv4_Packet.DestinationAddress], ecx
Line 583... Line 611...
583
 
611
 
584
	push	eax ebx edx
-
 
585
	; calculate checksum
-
 
586
	xor	edx, edx
612
	push	eax edx esi
587
	mov	esi, edi
-
 
588
	mov	ecx, IPv4_Packet.DataOrOptional
-
 
589
	call	checksum_1
613
	mov	esi, edi
590
	call	checksum_2
-
 
591
	mov	[edi + IPv4_Packet.HeaderChecksum], dx
614
	call	checksum_ip_header
592
	pop	edx ebx eax ecx
615
	pop	esi edx eax ecx
Line 593... Line 616...
593
	add	edi, IPv4_Packet.DataOrOptional
616
	add	edi, IPv4_Packet.DataOrOptional
Line 594... Line 617...
594
 
617