Subversion Repositories Kolibri OS

Rev

Rev 1171 | 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
;;  IP.INC                                                         ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
9
;;                                                                 ;;
10
;;  Based on the work of [Johnny_B] and [smb]                      ;;
11
;;                                                                 ;;
12
;;    Written by hidnplayr@kolibrios.org                           ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
19
$Revision: 922 $
20
 
21
; IP underlying protocols numbers
22
 
23
ETHER_IPv4	equ 0x0008	; Reversed from 0800 for intel
24
 
25
MAX_FRAGMENTS	equ 16
26
MAX_IP		equ MAX_NET_DEVICES
27
 
28
struct	IPv4_Packet
29
	.VersionAndIHL		db  ?  ; Version[0-3 bits] and IHL(header length)[4-7 bits]
30
	.TypeOfService		db  ?
31
	.TotalLength		dw  ?
32
	.Identification 	dw  ?
33
	.FlagsAndFragmentOffset dw  ?  ; Flags[0-2] and FragmentOffset[3-15]
34
	.TimeToLive		db  ?  ;
35
	.Protocol		db  ?
36
	.HeaderChecksum 	dw  ?
37
	.SourceAddress		dd  ?
38
	.DestinationAddress	dd  ?
39
	.DataOrOptional:
40
ends
41
 
42
struct	FRAGMENT_slot
43
	.ttl			dw  ?  ; Time to live for this entry, 0 for empty slot's
44
	.id			dw  ?  ; Identification field from IP header
45
	.SrcIP			dd  ?  ; .. from IP header
46
	.DstIP			dd  ?  ; .. from IP header
47
	.ptr			dd  ?  ; Pointer to first packet
48
	.size:
49
ends
50
 
51
struct	FRAGMENT_entry		       ; This structure will replace the ethernet header in fragmented ip packets
52
	.PrevPtr		dd  ?  ; Pointer to previous fragment entry  (-1 for first packet)
53
	.NextPtr		dd  ?  ; Pointer to next fragment entry (-1 for last packet)
54
	.Owner			dd  ?  ; Pointer to structure of driver
55
				rb  2  ; to match ethernet header size
56
	.Data:			       ; Ip header begins here (we will need the IP header to re-construct the complete packet)
57
ends
58
 
59
align 4
60
uglobal
61
	BROADCAST	dd  ?
62
	IP_LIST 	rd  MAX_IP
63
	SUBNET_LIST	rd  MAX_IP
64
	DNS_LIST	rd  MAX_IP
65
	GATEWAY_LIST	rd  MAX_IP
66
	IP_PACKETS_TX	rd  MAX_IP
67
	IP_PACKETS_RX	rd  MAX_IP
68
	FRAGMENT_LIST	rb  MAX_FRAGMENTS*FRAGMENT_slot.size
69
endg
70
 
71
 
72
;-----------------------------------------------------------------
73
;
74
; IPv4_init
75
;
76
;  This function resets all IP variables
77
;
78
;  IN:  /
79
;  OUT: /
80
;
81
;-----------------------------------------------------------------
82
 
83
align 4
84
IPv4_init:
85
 
86
	or	eax, -1
87
	mov	edi, BROADCAST
1196 hidnplayr 88
	stosd
89
	xor	eax, eax
90
	mov	ecx, 4*MAX_IP
1159 hidnplayr 91
	rep	stosd
92
 
93
	xor	eax, eax
94
	mov	edi, FRAGMENT_LIST
95
	mov	ecx, FRAGMENT_slot.size*MAX_FRAGMENTS/4 + 2*MAX_IP
96
	rep	stosd
97
 
98
	ret
99
 
100
 
101
 
102
;-----------------------------------------------------------------
103
;
104
; IP_Handler:
105
;
106
;  Called by eth_handler,
107
;  will check if IP Packet isnt damaged
108
;  and call appropriate handler. (TCP/UDP/ICMP/..)
109
;
110
;  It will also re-construct fragmented packets
111
;
112
;  IN:  Pointer to buffer in [esp]
113
;       size of buffer in [esp+4]
114
;       pointer to device struct in ebx
115
;       pointer to IP Packet data in edx
116
;  OUT: /
117
;
118
;-----------------------------------------------------------------
119
 
120
align 4
1196 hidnplayr 121
IPv4_handler:
1159 hidnplayr 122
 
123
	DEBUGF	1,"IP_Handler - start\n"
124
	mov	cx , [edx + IPv4_Packet.HeaderChecksum]
125
	xchg	ch , cl 					; Get the checksum in intel format
126
 
127
	mov	word [edx + IPv4_Packet.HeaderChecksum], 0	; Clear checksum field to recalculating checksum
128
 
129
	movzx	eax, byte [edx + IPv4_Packet.VersionAndIHL]	; Calculate Header length by using IHL field
130
	and	eax, 0x0000000F  ;
131
	shl	eax, 2		 ;
132
 
133
	push	edx
134
	stdcall checksum_jb, edx, eax				; buf_ptr, buf_size
135
	pop	edx
136
	cmp	cx , ax
137
	jnz	.dump						; if CHECKSUM isn't valid then dump Packet
138
 
139
	mov	eax, [edx + IPv4_Packet.DestinationAddress]
140
	mov	edi, BROADCAST
141
	mov	ecx, MAX_IP+1
142
	repnz	scasd
143
	jz	.ip_ok
144
 
145
	not	eax
146
	test	eax, 127 shl 24 ; 127.x.x.x
147
	jz	.ip_ok
148
 
149
;  TODO: we need to check for broadcasts (other then 255.255.255.255)
150
 
151
	jmp	.dump
152
 
153
  .ip_ok:
1171 hidnplayr 154
	call	ETH_struc2dev					; TODO: make this work on other protocols too!
155
	inc	[IP_PACKETS_RX+4*edi]
1159 hidnplayr 156
	DEBUGF	1,"IP_Handler - packet from %u.%u.%u.%u\n",\
157
	[edx + IPv4_Packet.SourceAddress]:1,[edx + IPv4_Packet.SourceAddress + 1]:1,[edx + IPv4_Packet.SourceAddress + 2]:1,[edx + IPv4_Packet.SourceAddress + 3]:1
158
 
159
	mov	al , [edx + IPv4_Packet.VersionAndIHL]
160
	and	al , 0x0f					; get IHL(header length)
161
	cmp	al , 0x05					; IHL!= 5*4(20 bytes)
162
	jnz	.dump						; TODO: dont dump packets wich have optional fiels !!!                   /!\
163
 
164
	cmp	byte [edx + IPv4_Packet.TimeToLive], 0
165
	je	.dump
166
 
167
	movzx	eax, word [edx + IPv4_Packet.FlagsAndFragmentOffset]
168
	xchg	al , ah
169
 
170
	test	ax , 1 shl 13					; Is 'more fragments' flag set ?
171
	jnz	.yes_fragments					; If so, we definately have a fragmented packet
172
 
173
	test	ax , 0x1fff					; If flag is not set, but there is a fragment offset, the packet is last in series of fragmented packets
174
	jnz	.last_fragment
175
 
176
   .handle_it:							; We reach here if packet hasnt been fragmented, or when it already has been re-constructed
177
	movzx	eax, byte [edx + IPv4_Packet.VersionAndIHL]	; Calculate Header length by using IHL field
178
	and	eax, 0x0000000F 				;
179
	shl	eax, 2						;
180
 
181
	movzx	ecx, word [edx + IPv4_Packet.TotalLength]	; Calculate length of encapsulated Packet
182
	xchg	cl , ch 					;
183
	sub	ecx, eax					;
184
 
185
	add	eax, edx
186
	push	eax
187
	mov	al , [edx + IPv4_Packet.Protocol]
188
	pop	edx						; Offset to data (tcp/udp/icmp/.. Packet)
189
 
190
	cmp	al , IP_PROTO_TCP
1196 hidnplayr 191
;        je      TCP_handler
1159 hidnplayr 192
 
193
	cmp	al , IP_PROTO_UDP
1196 hidnplayr 194
	je	UDP_handler
1159 hidnplayr 195
 
196
	cmp	al , IP_PROTO_ICMP
1196 hidnplayr 197
	je	ICMP_handler
1159 hidnplayr 198
 
199
	DEBUGF	1,"IP_Handler - unknown protocol:%u\n",al
200
 
201
  .dump:
202
	DEBUGF	1,"IP_Handler - done\n"
203
;        inc     [dumped_rx_count]
204
	call	kernel_free
205
	add	esp, 4						; pop (balance stack)
206
	ret
207
 
208
 
209
  .yes_fragments:
210
	shl	ax , 3
211
	DEBUGF	1,"Fragmented packet, offset:%u, id:%x\n", ax, [edx + IPv4_Packet.Identification]:4
212
 
213
	test	ax , ax 					; Is this the first packet of the fragment?
214
	jnz	.not_first_fragment
215
 
216
	DEBUGF	1,"First fragmented packet received!\n"
217
								; try to locate a free slot..
218
	mov	ecx, MAX_FRAGMENTS
219
	mov	esi, FRAGMENT_LIST
220
     .find_free_slot:
221
	cmp	word [esi + FRAGMENT_slot.ttl], 0
222
	je	.found_free_slot
223
	add	esi, FRAGMENT_slot.size
224
	loop	.find_free_slot
225
	jmp	.dump						; If no free slot was found, dump the packet
226
 
227
     .found_free_slot:						; We found a free slot, let's fill in the FRAGMENT_slot structure
228
	mov	word [esi + FRAGMENT_slot.ttl], 15		; RFC recommends 15 secs as ttl
229
	mov	ax , word [edx + IPv4_Packet.Identification]
230
	mov	word [esi + FRAGMENT_slot.id], ax
231
	mov	eax, dword [edx + IPv4_Packet.SourceAddress]
232
	mov	dword [esi + FRAGMENT_slot.SrcIP], eax
233
	mov	eax, dword [edx + IPv4_Packet.DestinationAddress]
234
	mov	dword [esi + FRAGMENT_slot.DstIP], eax
235
	pop	eax
236
	mov	dword [esi + FRAGMENT_slot.ptr], eax
237
								; Now, replace ethernet header in original buffer with a FRAGMENT_entry structure
238
	mov	[eax + FRAGMENT_entry.NextPtr], -1
239
	mov	[eax + FRAGMENT_entry.PrevPtr], -1
240
	mov	[eax + FRAGMENT_entry.Owner], ebx
241
 
242
	add	esp, 4						; balance stack and exit
243
	ret
244
 
245
 
246
 
247
  .not_first_fragment:
248
	DEBUGF	1,"Middle fragmented packet received!\n"
249
 
250
	call	.find_fragment_slot
251
	cmp	esi, -1
252
	je	.dump
253
 
254
	mov	word [esi + FRAGMENT_slot.ttl], 15		; Reset the ttl
255
	mov	esi, [esi + FRAGMENT_slot.ptr]
256
	or	edi, -1
257
     .find_last_entry:						; The following routine will try to find the last entry
258
	cmp	edi, [esi + FRAGMENT_entry.PrevPtr]
259
	jne	.destroy_slot					; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
260
	mov	edi, esi
261
	mov	esi, [esi + FRAGMENT_entry.NextPtr]
262
	cmp	esi, -1
263
	jne	.find_last_entry
264
								; We found the last entry (pointer is noww in edi)
265
								; We are going to overwrite the ethernet header in received packet with a FRAGMENT_entry structure
266
 
267
	pop	eax						; pointer to packet
268
	mov	[edi + FRAGMENT_entry.NextPtr], eax		; update pointer of previous entry to the new entry
269
	mov	[eax + FRAGMENT_entry.NextPtr], -1
270
	mov	[eax + FRAGMENT_entry.PrevPtr], edi
271
	mov	[eax + FRAGMENT_entry.Owner], ebx
272
 
273
	add	esp, 4
274
	ret
275
 
276
 
277
 
278
  .last_fragment:
279
	DEBUGF	1,"Last fragmented packet received!\n"
280
	call	.find_fragment_slot
281
	cmp	esi, -1
282
	je	.dump
283
 
284
	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
285
	push	esi
286
	xor	eax, eax					;
287
	or	edi, -1
288
     .count_bytes:
289
	cmp	[esi + FRAGMENT_entry.PrevPtr], edi
290
	jne	.destroy_slot_pop						; Damn, something screwed up, remove the whole slot (and free buffers too if possible!)
291
	mov	cx, word [esi + FRAGMENT_entry.Data + IPv4_Packet.TotalLength]	  ; Add total length
292
	xchg	cl, ch
293
	DEBUGF	1,"Packet size: %u\n", cx
294
	add	ax, cx
295
	movzx	cx, byte [esi + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]  ; Sub Header length
296
	and	cx, 0x000F
297
	shl	cx, 2
298
	DEBUGF	1,"Header size: %u\n", cx
299
	sub	ax, cx
300
	mov	edi, esi
301
	mov	esi, [esi + FRAGMENT_entry.NextPtr]
302
	cmp	esi, -1
303
	jne	.count_bytes
304
 
305
	mov	esi, [esp+4]  ;;;
306
	mov	[edi + FRAGMENT_entry.NextPtr], esi			       ; Add this packet to the chain, this simplifies the following code
307
	mov	[esi + FRAGMENT_entry.NextPtr], -1
308
	mov	[esi + FRAGMENT_entry.PrevPtr], edi
309
	mov	[esi + FRAGMENT_entry.Owner], ebx
310
 
311
	mov	cx, [edx + IPv4_Packet.TotalLength]			       ; Note: This time we dont substract Header length
312
	xchg	cl , ch
313
	DEBUGF	1,"Packet size: %u\n", cx
314
	add	ax , cx
315
	DEBUGF	1,"Total Received data size: %u\n", eax
316
 
317
	push	eax
318
	mov	ax , [edx + IPv4_Packet.FlagsAndFragmentOffset]
319
	xchg	al , ah
320
	shl	ax , 3
321
	add	cx , ax
322
	pop	eax
323
	DEBUGF	1,"Total Fragment size: %u\n", ecx
324
 
325
	cmp	ax, cx
326
	jne	.destroy_slot_pop
327
 
328
	push	eax
329
	push	eax
330
	call	kernel_alloc
331
	test	eax, eax
332
	je	.destroy_slot_pop							; If we dont have enough space to allocate the buffer, discard all packets in slot
333
	mov	edx, [esp+4]								; Get pointer to first fragment entry back in edx
334
 
335
     .rebuild_packet_loop:
336
	movzx	ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.FlagsAndFragmentOffset]	; Calculate the fragment offset
337
	xchg	cl , ch 									;   intel byte order
338
	shl	cx , 3										;   multiply by 8 and clear first 3 bits
339
	DEBUGF	1,"Fragment offset: %u\n", cx
340
 
341
	lea	edi, [eax + ecx]								; Notice that edi will be equal to eax for first fragment
342
	movzx	ebx, byte [edx + FRAGMENT_entry.Data + IPv4_Packet.VersionAndIHL]		; Find header size (in ebx) of fragment
343
	and	bx , 0x000F									;
344
	shl	bx , 2										;
345
 
346
	lea	esi, [edx + FRAGMENT_entry.Data]						; Set esi to the correct begin of fragment
347
	movzx	ecx, word [edx + FRAGMENT_entry.Data + IPv4_Packet.TotalLength] 		; Calculate total length of fragment
348
	xchg	cl, ch										;  intel byte order
349
 
350
	cmp	edi, eax									; Is this packet the first fragment ?
351
	je	.first_fragment
352
	sub	cx, bx										; If not, dont copy the header
353
	add	esi, ebx									;
354
     .first_fragment:
355
 
356
	push	cx										; First copy dword-wise, then byte-wise
357
	shr	cx, 2										;
358
	rep	movsd										;
359
	pop	cx										;
360
	and	cx, 3										;
361
	rep	movsb										;
362
 
363
	push	eax
364
	push	edx										; Push pointer to fragment onto stack
365
	mov	edx, [edx + FRAGMENT_entry.NextPtr]						; Set edx to the next pointer
366
	call	kernel_free									; free the previous fragment buffer (this uses the value from stack)
367
	pop	eax
368
	cmp	edx, -1 									; Check if it is last fragment in chain
369
	jne	.rebuild_packet_loop
370
 
371
	pop	ecx										;
372
	xchg	cl, ch
373
	mov	edx, eax
374
	mov	word [edx + IPv4_Packet.TotalLength], cx
375
	add	esp, 8
376
 
377
	xchg	cl, ch		   ;  This prints the IP packet to the debug board (usefull when using serial output debug..)
378
	push	ecx  ;;;;
379
	push	eax	;;;;
380
;        mov     esi, edx           ;
381
;                                   ;
382
;       @@:                         ;
383
;        lodsb                      ;
384
;        DEBUGF  1,"%x ", eax:2     ;
385
;        loop    @r                 ;
386
 
387
	movzx	eax, byte [edx + IPv4_Packet.VersionAndIHL]	; Calculate Header length by using IHL field
388
	and	ax, 0x000F					;
389
	shl	ax, 2						;
390
	sub	ecx, eax					;
391
	add	eax, edx
392
	push	eax
393
	mov	al , [edx + IPv4_Packet.Protocol]
394
	pop	edx						; Offset to data (tcp/udp/icmp/.. Packet)
395
 
1196 hidnplayr 396
	cmp	al , IP_PROTO_TCP
397
;        je      TCP_handler
1159 hidnplayr 398
 
1171 hidnplayr 399
	cmp	al , IP_PROTO_UDP
1196 hidnplayr 400
	je	UDP_handler
1159 hidnplayr 401
 
402
	cmp	al , IP_PROTO_ICMP
1196 hidnplayr 403
	je	ICMP_handler_fragments
1159 hidnplayr 404
 
405
	DEBUGF	1,"IP_Handler - unknown protocol:%u\n",al
406
 
1166 hidnplayr 407
	call	kernel_free
408
	add	esp, 8						; pop (balance stack)
409
 
1165 hidnplayr 410
	ret
1159 hidnplayr 411
 
412
 
413
  .destroy_slot_pop:
414
	add	esp, 4
415
  .destroy_slot:
1166 hidnplayr 416
	DEBUGF	1,"Destroy fragment slot!\n"
1159 hidnplayr 417
	; TODO!
418
	jmp	.dump
419
 
420
 
421
 
422
;-----------------------------------------------------------------
423
;
424
; find fragment slot
425
;
426
; IN: pointer to fragmented packet in edx         ; TODO: the RFC says we should check protocol too
427
; OUT: pointer to slot in edi, -1 on error
428
;
429
;-----------------------------------------------------------------
430
 
431
  .find_fragment_slot:
432
 
433
	push	eax ebx ecx edx
434
	mov	ax , word [edx + IPv4_Packet.Identification]
435
	mov	ecx, MAX_FRAGMENTS
436
	mov	esi, FRAGMENT_LIST
437
	mov	ebx, dword [edx + IPv4_Packet.SourceAddress]
438
	mov	edx, dword [edx + IPv4_Packet.DestinationAddress]
439
  .find_slot:
440
	cmp	word [esi + FRAGMENT_slot.id], ax
441
	jne	.try_next
442
	cmp	dword [esi + FRAGMENT_slot.SrcIP], ebx
443
	jne	.try_next
444
	cmp	dword [esi + FRAGMENT_slot.DstIP], edx
445
	je	.found_slot
446
  .try_next:
447
	add	esi, FRAGMENT_slot.size
448
	loop	.find_slot
449
 ;       pop     edx ebx
450
	or	esi, -1
451
;        ret
452
 
453
  .found_slot:
454
	pop	edx ecx ebx eax
455
	ret
456
 
457
 
458
;-----------------------------------------------------------------
459
;
460
; Decrease TimeToLive of all fragment slots
461
;
462
; IN: /
463
; OUT: /
464
;
465
;-----------------------------------------------------------------
466
 
467
align 4
468
IPv4_decrease_fragment_ttls:
469
 
470
	mov	esi, FRAGMENT_LIST
471
	mov	ecx, MAX_FRAGMENTS
472
  .loop:
473
	cmp	[esi + FRAGMENT_slot.ttl], 0
474
	je	.try_next
475
	dec	[esi + FRAGMENT_slot.ttl]
476
	jnz	.try_next
477
	DEBUGF 1,"Fragment slot timed-out!\n"
478
	; TODO: clear all entry's of timed-out slot
479
  .try_next:
480
	add	esi, 4
481
	loop	.loop
482
	ret
483
 
484
 
485
 
486
 
487
 
488
;-----------------------------------------------------------------
489
;
490
; Create_IPv4_Packet
491
;
492
; IN: eax = dest ip
493
;     ebx = source ip
494
;     ecx = data length
495
;     dx  = fragment id
496
;     di  = protocol
497
;
498
; OUT: eax points to buffer start
499
;      ebx is size of complete buffer
500
;      edi = pointer to start of data (-1 on error)
501
;      ecx = unchanged (packet size of embedded data)
502
;      edx = pointer to device struct (needed for sending procedure)
503
;      esi = pointer to sending procedure
504
;
505
;-----------------------------------------------------------------
506
 
507
;;; TODO: create fragmented packets
508
 
509
align 4
1196 hidnplayr 510
IPv4_create_packet:
1159 hidnplayr 511
 
512
	DEBUGF 1,"Create IPv4 Packet\n"
513
 
514
	cmp	ecx, 1514
515
	jg	.exit_
516
 
517
	cmp	eax, -1
518
	je	.broadcast		  ; If it is broadcast, just send
519
 
1196 hidnplayr 520
	call	ARP_IP_to_MAC
1159 hidnplayr 521
 
1196 hidnplayr 522
	cmp	eax, -1
523
	jne	.found
524
 
1159 hidnplayr 525
	DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n"
526
 
527
	; TODO: QUEUE!
528
	or	edi, -1
529
 
530
	ret
531
 
1196 hidnplayr 532
  .found:
533
	push	ax
534
	push	ebx
535
 
536
	jmp	.send
537
 
1159 hidnplayr 538
  .broadcast:
1196 hidnplayr 539
	push	word -1
540
	push	dword -1
1159 hidnplayr 541
 
542
 
543
  .send:
544
	push	ecx eax ebx dx di
545
	call	IPv4_dest_to_dev
1171 hidnplayr 546
	inc	[IP_PACKETS_TX+4*edi]
1159 hidnplayr 547
	mov	edi, [ETH_DRV_LIST + 4*edi]
548
	lea	eax, [edi + ETH_DEVICE.mac]
1196 hidnplayr 549
	lea	ebx, [esp+16]
1159 hidnplayr 550
	mov	ecx, [esp+12]
551
	add	ecx, IPv4_Packet.DataOrOptional
1196 hidnplayr 552
	mov	edx, edi ;;;
1159 hidnplayr 553
	mov	di , ETHER_IPv4
554
	call	ETH_create_Packet		   ; TODO: figure out a way to make this work with other protocols too
555
	cmp	edi, -1
556
	je	.exit
557
 
558
	mov	[edi + IPv4_Packet.VersionAndIHL], 0x45   ; IPv4, normal length (no Optional header)
559
	mov	[edi + IPv4_Packet.TypeOfService], 0
560
	xchg	ch, cl
561
	mov	[edi + IPv4_Packet.TotalLength], cx
562
	mov	[edi + IPv4_Packet.FlagsAndFragmentOffset], 0x0000
563
	mov	[edi + IPv4_Packet.TimeToLive], 128
564
	mov	[edi + IPv4_Packet.HeaderChecksum], 0
565
	pop	cx
566
	mov	[edi + IPv4_Packet.Protocol], cl
567
	pop	cx
568
	mov	[edi + IPv4_Packet.Identification], cx
569
	pop	ecx
570
	mov	[edi + IPv4_Packet.SourceAddress], ecx
571
	pop	ecx
572
	mov	[edi + IPv4_Packet.DestinationAddress], ecx
573
 
574
	push	eax
575
	stdcall checksum_jb, edi, IPv4_Packet.DataOrOptional ; buf_ptr, buf_size
576
	xchg	al, ah
577
	mov	[edi + IPv4_Packet.HeaderChecksum], ax
578
	pop	eax ecx
579
	add	edi, IPv4_Packet.DataOrOptional
580
 
581
	DEBUGF 1,"IPv4 Packet for device %x created successfully\n", edx
582
 
1196 hidnplayr 583
	add	esp, 6
584
 
1159 hidnplayr 585
	ret
586
 
587
  .exit:
1196 hidnplayr 588
	add	esp, 16+6
1159 hidnplayr 589
  .exit_:
1165 hidnplayr 590
	DEBUGF 1,"Create IPv4 Packet - failed\n"
1159 hidnplayr 591
	or	edi, -1
592
	ret
593
 
594
 
595
 
596
;---------------------------------------------------------------------------
597
;
598
; IPv4_dest_to_dev
599
;
600
; IN: Destination IP in eax
601
; OUT: device id in edi
602
;
603
;---------------------------------------------------------------------------
604
 
605
align 4
606
IPv4_dest_to_dev:
607
 
608
	DEBUGF 1,"IPv4 destination to device: "
609
 
610
	xor	edi, edi
611
	mov	ecx, MAX_IP
612
 
613
  .loop:
614
	mov	ebx, [IP_LIST+edi]		; we dont need to worry about non exisiting ip interfaces
615
	and	ebx, [SUBNET_LIST+edi]		; they have IP and SUBNET set to all one's, so they will have no match except 255.255.255.255
616
						; (only a moron would insert that ip into this function..)
617
	mov	edx, eax
618
	and	edx, [SUBNET_LIST+edi]
619
 
620
	cmp	ebx, edx
621
	je	.found_it
622
 
623
	add	edi, 4
624
	loop	.loop
625
 
626
	xor	edi, edi	; if none found, use device 0 as default device
627
 
628
  .found_it:
629
	shr	edi, 2
630
 
631
	DEBUGF 1,"%u\n",edi
632
 
633
	ret
634
 
635
 
636
 
637
;---------------------------------------------------------------------------
638
;
639
; IPv4_get_frgmnt_num
640
;
641
; IN: /
642
; OUT: fragment number in ax
643
;
644
;---------------------------------------------------------------------------
645
 
646
align 4
647
IPv4_get_frgmnt_num:
648
	xor	ax, ax	;;; TODO: replace this with real code
649
 
650
	ret
651
 
652
 
653
;---------------------------------------------------------------------------
654
;
655
; IPv4_API
656
;
657
; This function is called by system function 75
658
;
659
; IN:  subfunction number in bl
660
;      device number in bh
661
;      ecx, edx, .. depends on subfunction
662
;
663
; OUT:
664
;
665
;---------------------------------------------------------------------------
666
 
667
align 4
668
IPv4_API:
669
 
670
	movzx	eax, bh
671
	shl	eax, 2
672
 
673
	test	bl, bl
674
	jz	.packets_tx	; 0
675
	dec	bl
676
	jz	.packets_rx	; 1
677
	dec	bl
678
	jz	.read_ip	; 2
679
	dec	bl
680
	jz	.write_ip	; 3
681
	dec	bl
682
	jz	.read_dns	; 4
683
	dec	bl
684
	jz	.write_dns	; 5
685
	dec	bl
686
	jz	.read_subnet	; 6
687
	dec	bl
688
	jz	.write_subnet	; 7
689
	dec	bl
690
	jz	.read_gateway	; 8
691
	dec	bl
692
	jz	.write_gateway	; 9
693
 
694
.error:
695
	mov	eax, -1
696
	ret
697
 
698
.packets_tx:
699
	add	eax, IP_PACKETS_TX
700
	mov	eax, [eax]
701
	ret
702
 
703
.packets_rx:
704
	add	eax, IP_PACKETS_RX
705
	mov	eax, [eax]
706
	ret
707
 
708
.read_ip:
709
	add	eax, IP_LIST
710
	mov	eax, [eax]
711
	ret
712
 
713
.write_ip:
714
	add	eax, IP_LIST
715
	mov	[eax], ecx
716
	xor	eax, eax
717
	ret
718
 
719
.read_dns:
720
	add	eax, DNS_LIST
721
	mov	eax, [eax]
722
	ret
723
 
724
.write_dns:
725
	add	eax, DNS_LIST
726
	mov	[eax], ecx
727
	xor	eax, eax
728
	ret
729
 
730
.read_subnet:
731
	add	eax, SUBNET_LIST
732
	mov	eax, [eax]
733
	ret
734
 
735
.write_subnet:
736
	add	eax, SUBNET_LIST
737
	mov	[eax], ecx
738
	xor	eax, eax
739
	ret
740
 
741
.read_gateway:
742
	add	eax, GATEWAY_LIST
743
	mov	eax, [eax]
744
	ret
745
 
746
.write_gateway:
747
	add	eax, GATEWAY_LIST
748
	mov	[eax], ecx
749
	xor	eax, eax
750
	ret
751