Subversion Repositories Kolibri OS

Rev

Rev 1514 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
1514 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
1159 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  ICMP.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
 
1206 hidnplayr 20
$Revision: 1519 $
1159 hidnplayr 21
 
22
; ICMP types & codes
23
 
1514 hidnplayr 24
ICMP_ECHOREPLY			equ 0		    ; echo reply message
1159 hidnplayr 25
 
1514 hidnplayr 26
ICMP_UNREACH			equ 3
27
ICMP_UNREACH_NET		equ  0		     ; bad net
28
ICMP_UNREACH_HOST		equ  1		     ; bad host
29
ICMP_UNREACH_PROTOCOL		equ  2		     ; bad protocol
30
ICMP_UNREACH_PORT		equ  3		     ; bad port
31
ICMP_UNREACH_NEEDFRAG		equ  4		     ; IP_DF caused drop
32
ICMP_UNREACH_SRCFAIL		equ  5		     ; src route failed
33
ICMP_UNREACH_NET_UNKNOWN	equ  6		     ; unknown net
34
ICMP_UNREACH_HOST_UNKNOWN	equ  7		     ; unknown host
35
ICMP_UNREACH_ISOLATED		equ  8		     ; src host isolated
36
ICMP_UNREACH_NET_PROHIB 	equ  9		     ; prohibited access
37
ICMP_UNREACH_HOST_PROHIB	equ 10		    ; ditto
38
ICMP_UNREACH_TOSNET		equ 11		    ; bad tos for net
39
ICMP_UNREACH_TOSHOST		equ 12		    ; bad tos for host
40
ICMP_UNREACH_FILTER_PROHIB	equ 13		    ; admin prohib
41
ICMP_UNREACH_HOST_PRECEDENCE	equ 14		   ; host prec vio.
42
ICMP_UNREACH_PRECEDENCE_CUTOFF	equ 15		 ; prec cutoff
1159 hidnplayr 43
 
1514 hidnplayr 44
ICMP_SOURCEQUENCH		equ 4		    ; Packet lost, slow down
1159 hidnplayr 45
 
1514 hidnplayr 46
ICMP_REDIRECT			equ 5		    ; shorter route, codes:
47
ICMP_REDIRECT_NET		equ  0		     ; for network
48
ICMP_REDIRECT_HOST		equ  1		     ; for host
49
ICMP_REDIRECT_TOSNET		equ  2		     ; for tos and net
50
ICMP_REDIRECT_TOSHOST		equ  3		     ; for tos and host
1159 hidnplayr 51
 
1514 hidnplayr 52
ICMP_ALTHOSTADDR		equ 6		    ; alternate host address
53
ICMP_ECHO			equ  8		     ; echo service
54
ICMP_ROUTERADVERT		equ  9		     ; router advertisement
55
ICMP_ROUTERADVERT_NORMAL	equ  0			; normal advertisement
56
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 	; selective routing
1159 hidnplayr 57
 
1514 hidnplayr 58
ICMP_ROUTERSOLICIT		equ 10		    ; router solicitation
59
ICMP_TIMXCEED			equ 11		    ; time exceeded, code:
60
ICMP_TIMXCEED_INTRANS		equ 0		    ; ttl==0 in transit
61
ICMP_TIMXCEED_REASS		equ 1		    ; ttl==0 in reass
1159 hidnplayr 62
 
1514 hidnplayr 63
ICMP_PARAMPROB			equ 12		     ; ip header bad
64
ICMP_PARAMPROB_ERRATPTR 	equ 0		 ; error at param ptr
65
ICMP_PARAMPROB_OPTABSENT	equ 1		 ; req. opt. absent
66
ICMP_PARAMPROB_LENGTH		equ 2		 ; bad length
1159 hidnplayr 67
 
1514 hidnplayr 68
ICMP_TSTAMP			equ 13		    ; timestamp request
69
ICMP_TSTAMPREPLY		equ 14		    ; timestamp reply
70
ICMP_IREQ			equ 15		    ; information request
71
ICMP_IREQREPLY			equ 16		    ; information reply
72
ICMP_MASKREQ			equ 17		    ; address mask request
73
ICMP_MASKREPLY			equ 18		    ; address mask reply
74
ICMP_TRACEROUTE 		equ 30		    ; traceroute
75
ICMP_DATACONVERR		equ 31		    ; data conversion error
76
ICMP_MOBILE_REDIRECT		equ 32		    ; mobile host redirect
77
ICMP_IPV6_WHEREAREYOU		equ 33		    ; IPv6 where-are-you
78
ICMP_IPV6_IAMHERE		equ 34		    ; IPv6 i-am-here
79
ICMP_MOBILE_REGREQUEST		equ 35		    ; mobile registration req
80
ICMP_MOBILE_REGREPLY		equ 36		    ; mobile registreation reply
81
ICMP_SKIP			equ 39		    ; SKIP
1159 hidnplayr 82
 
1514 hidnplayr 83
ICMP_PHOTURIS			equ 40		    ; Photuris
84
ICMP_PHOTURIS_UNKNOWN_INDEX	equ 1		     ; unknown sec index
85
ICMP_PHOTURIS_AUTH_FAILED	equ 2		     ; auth failed
86
ICMP_PHOTURIS_DECRYPT_FAILED	equ 3		     ; decrypt failed
1159 hidnplayr 87
 
88
 
89
 
90
struct	ICMP_Packet
91
	.Type		db   ?
92
	.Code		db   ?
93
	.Checksum	dw   ?
94
	.Identifier	dw   ?
95
	.SequenceNumber dw   ?
96
	.Data:
97
ends
98
 
99
 
100
align 4
101
uglobal
102
	ICMP_PACKETS_TX 	rd  MAX_IP
103
	ICMP_PACKETS_RX 	rd  MAX_IP
104
endg
105
 
1185 hidnplayr 106
 
107
 
1159 hidnplayr 108
;-----------------------------------------------------------------
109
;
110
; ICMP_init
111
;
112
;  This function resets all ICMP variables
113
;
114
;  IN:  /
115
;  OUT: /
116
;
117
;-----------------------------------------------------------------
118
align 4
119
ICMP_init:
120
 
121
	xor	eax, eax
122
	mov	edi, ICMP_PACKETS_TX
123
	mov	ecx, 2*MAX_IP
124
	rep	stosd
125
 
126
	ret
1171 hidnplayr 127
 
128
 
129
 
130
 
1257 hidnplayr 131
;-----------------------------------------------------------------
1159 hidnplayr 132
;
1514 hidnplayr 133
; ICMP_input:
1159 hidnplayr 134
;
1514 hidnplayr 135
;  This procedure will send reply's to ICMP echo's
136
;   and insert packets into sockets when needed
1159 hidnplayr 137
;
138
;  IN:  Pointer to buffer in [esp]
139
;       size of buffer in [esp+4]
140
;       pointer to device struct in ebx
141
;       ICMP Packet size in ecx
142
;       pointer to ICMP Packet data in edx
143
;  OUT: /
144
;
1257 hidnplayr 145
;-----------------------------------------------------------------
1159 hidnplayr 146
align 4
1514 hidnplayr 147
ICMP_input:
1159 hidnplayr 148
 
1514 hidnplayr 149
;;; TODO: works only on pure ethernet right now !
150
 
151
	DEBUGF	1,"ICMP_Handler - start\n"
1185 hidnplayr 152
	cmp	byte [edx + ICMP_Packet.Type], ICMP_ECHO		    ; Is this an echo request?
1159 hidnplayr 153
	jne	.check_sockets
154
 
1473 hidnplayr 155
;;; TODO: check checksum!
156
 
1514 hidnplayr 157
	DEBUGF	1,"ICMP_Handler - echo request\n"
1473 hidnplayr 158
 
1159 hidnplayr 159
	mov	byte [edx + ICMP_Packet.Type], ICMP_ECHOREPLY		    ; Change Packet type to reply
160
	mov	word [edx + ICMP_Packet.Checksum], 0			    ; Set checksum to 0, needed to calculate new checksum
161
 
1514 hidnplayr 162
	call	NET_ptr_to_num
1171 hidnplayr 163
	cmp	edi,-1
164
	je	.dump
165
	inc	[ICMP_PACKETS_RX+4*edi]
1185 hidnplayr 166
	inc	[ICMP_PACKETS_TX+4*edi]
1171 hidnplayr 167
 
1159 hidnplayr 168
; exchange dest and source address in IP header
169
; exchange dest and source MAC in ETH header
170
	mov	esi, [esp]
171
 
172
	mov	eax, dword [esi + ETH_FRAME.DstMAC]
173
	mov	ecx, dword [esi + ETH_FRAME.SrcMAC]
174
	mov	dword [esi + ETH_FRAME.SrcMAC], eax
175
	mov	dword [esi + ETH_FRAME.DstMAC], ecx
176
 
177
	mov	ax, word [esi + ETH_FRAME.DstMAC + 4]
178
	mov	cx, word [esi + ETH_FRAME.SrcMAC + 4]
179
	mov	word [esi + ETH_FRAME.SrcMAC + 4], ax
180
	mov	word [esi + ETH_FRAME.DstMAC + 4], cx
181
 
182
	mov	eax, dword [esi + ETH_FRAME.Data + IPv4_Packet.SourceAddress]
183
	mov	ecx, dword [esi + ETH_FRAME.Data + IPv4_Packet.DestinationAddress]
184
	mov	dword [esi + ETH_FRAME.Data + IPv4_Packet.DestinationAddress], eax
185
	mov	dword [esi + ETH_FRAME.Data + IPv4_Packet.SourceAddress], ecx
186
 
187
; Recalculate ip header checksum
188
	add	esi, ETH_FRAME.Data					    ; Point esi to start of IP Packet
1249 hidnplayr 189
	movzx	ecx, byte [esi + IPv4_Packet.VersionAndIHL]		    ; Calculate IP Header length by using IHL field
190
	and	ecx, 0x0000000F 					    ;
191
	shl	cx , 2
192
	push	ebx edx ecx esi
193
	xor	edx, edx
194
	call	checksum_1
195
	call	checksum_2
196
	pop	esi
197
	mov	word [esi + IPv4_Packet.HeaderChecksum], dx		    ; Store it in the IP Packet header
1159 hidnplayr 198
 
199
; Recalculate ICMP CheckSum
1249 hidnplayr 200
	movzx	eax, word[esi + IPv4_Packet.TotalLength]		    ; Find length of IP Packet
1159 hidnplayr 201
	xchg	ah , al 						    ;
1249 hidnplayr 202
	sub	eax, [esp]						     ; Now we know the length of ICMP data in eax
203
	mov	ecx, eax
204
	mov	esi, [esp + 4]
205
	xor	edx, edx
206
	call	checksum_1
207
	call	checksum_2
208
	mov	ax , dx
209
	pop	ecx edx ebx
1159 hidnplayr 210
	mov	word [edx + ICMP_Packet.Checksum], ax
211
 
1519 hidnplayr 212
	call	[ebx + NET_DEVICE.transmit]
213
	ret
1159 hidnplayr 214
 
1171 hidnplayr 215
 
216
 
217
 
1159 hidnplayr 218
       .check_sockets:
1206 hidnplayr 219
	; TODO: validate the header & checksum.
1159 hidnplayr 220
 
221
	; Look for an open ICMP socket
222
 
223
	mov	esi, net_sockets
224
  .try_more:
225
	mov	ax , [edx + ICMP_Packet.Identifier]
226
  .next_socket:
1514 hidnplayr 227
	mov	esi, [esi + SOCKET.NextPtr]
1159 hidnplayr 228
	or	esi, esi
229
	jz	.dump
1514 hidnplayr 230
	cmp	[esi + SOCKET.Type], IP_PROTO_ICMP
1159 hidnplayr 231
	jne	.next_socket
1514 hidnplayr 232
	cmp	[esi + ICMP_SOCKET.Identifier], ax
1159 hidnplayr 233
	jne	.next_socket
234
 
1171 hidnplayr 235
	call	IPv4_dest_to_dev
236
	cmp	edi,-1
237
	je	.dump
238
	inc	[ICMP_PACKETS_RX+4*edi]
239
 
1159 hidnplayr 240
	DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi
241
 
1514 hidnplayr 242
	lea	ebx, [esi + SOCKET.lock]
1159 hidnplayr 243
	call	wait_mutex
244
 
1249 hidnplayr 245
	; Now, assign data to socket. We have socket address in esi.
1159 hidnplayr 246
	; We have ICMP Packet in edx
247
	; number of bytes in ecx
248
 
1249 hidnplayr 249
	mov	eax, esi
1159 hidnplayr 250
	pop	esi
1249 hidnplayr 251
	add	esp, 4
252
	sub	edx, esi
253
	mov	edi, edx
1519 hidnplayr 254
	jmp	SOCKET_input
1159 hidnplayr 255
 
256
       .dump:
257
	DEBUGF	1,"ICMP_Handler - dumping\n"
258
 
259
	call	kernel_free
1249 hidnplayr 260
	add	esp, 4 ; pop (balance stack)
1159 hidnplayr 261
 
262
	ret
263
 
264
 
1257 hidnplayr 265
;-----------------------------------------------------------------
1159 hidnplayr 266
;
1519 hidnplayr 267
; ICMP_output
1159 hidnplayr 268
;
1519 hidnplayr 269
; IN:  eax = dest ip
270
;      ebx = source ip
271
;      ecx = data length
272
;      dh  = type
273
;      dl  = code
274
;      high 16 bits of edx = fragment id (for IP header)
275
;      esi = data offset
276
;      edi = identifier shl 16 + sequence number
1159 hidnplayr 277
;
278
;-----------------------------------------------------------------
279
align 4
1514 hidnplayr 280
ICMP_output:
1159 hidnplayr 281
 
1519 hidnplayr 282
	DEBUGF	1,"Creating ICMP Packet\n"
1159 hidnplayr 283
 
284
	push	esi edi edx
285
 
286
	add	ecx, ICMP_Packet.Data
287
	mov	di , IP_PROTO_ICMP
288
	shr	edx, 16
289
 
1196 hidnplayr 290
	call	IPv4_create_packet
1514 hidnplayr 291
	jz	.exit
1159 hidnplayr 292
 
1519 hidnplayr 293
	DEBUGF	1,"full icmp packet size: %u\n", edx
1165 hidnplayr 294
 
1159 hidnplayr 295
	pop	eax
296
	mov	word [edi + ICMP_Packet.Type], ax	; Write both type and code bytes at once
297
	pop	eax
298
	mov	[edi + ICMP_Packet.SequenceNumber], ax
299
	shr	eax, 16
300
	mov	[edi + ICMP_Packet.Identifier], ax
301
	mov	[edi + ICMP_Packet.Checksum], 0
302
 
1249 hidnplayr 303
	push	eax ebx ecx edx
304
	mov	esi, edi
305
	xor	edx, edx
306
	call	checksum_1
307
	call	checksum_2
308
	mov	[edi + ICMP_Packet.Checksum], dx
309
	pop	edx ecx ebx eax esi
1159 hidnplayr 310
 
311
	sub	ecx, ICMP_Packet.Data
312
	add	edi, ICMP_Packet.Data
313
	push	cx
314
	shr	cx , 2
315
	rep	movsd
316
	pop	cx
317
	and	cx , 3
318
	rep	movsb
319
 
1514 hidnplayr 320
	sub	edi, edx				;;; TODO: find a better way to remember start of packet
1519 hidnplayr 321
	push	edx edi
322
	DEBUGF	1,"Sending ICMP Packet\n"
323
	call	[ebx + NET_DEVICE.transmit]
324
	ret
1159 hidnplayr 325
  .exit:
1519 hidnplayr 326
	DEBUGF	1,"Creating ICMP Packet failed\n"
1165 hidnplayr 327
	add	esp, 3*4
1159 hidnplayr 328
	ret
329
 
330
 
331
 
332
 
1257 hidnplayr 333
;-----------------------------------------------------------------
1159 hidnplayr 334
;
335
; ICMP_API
336
;
337
; This function is called by system function 75
338
;
339
; IN:  subfunction number in bl
340
;      device number in bh
341
;      ecx, edx, .. depends on subfunction
342
;
343
; OUT:
344
;
1257 hidnplayr 345
;-----------------------------------------------------------------
1159 hidnplayr 346
align 4
347
ICMP_API:
348
 
349
	movzx	eax, bh
350
	shl	eax, 2
351
 
352
	test	bl, bl
353
	jz	.packets_tx	; 0
354
	dec	bl
355
	jz	.packets_rx	; 1
356
 
357
.error:
358
	mov	eax, -1
359
	ret
360
 
361
.packets_tx:
362
	add	eax, ICMP_PACKETS_TX
363
	mov	eax, [eax]
364
	ret
365
 
366
.packets_rx:
367
	add	eax, ICMP_PACKETS_RX
368
	mov	eax, [eax]
369
	ret