Subversion Repositories Kolibri OS

Rev

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

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