Subversion Repositories Kolibri OS

Rev

Rev 1473 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.    ;;
  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.  
  20. $Revision: 1514 $
  21.  
  22. ; ICMP types & codes
  23.  
  24. ICMP_ECHOREPLY                  equ 0               ; echo reply message
  25.  
  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
  43.  
  44. ICMP_SOURCEQUENCH               equ 4               ; Packet lost, slow down
  45.  
  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
  51.  
  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
  57.  
  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
  62.  
  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
  67.  
  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
  82.  
  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
  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.  
  106.  
  107.  
  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
  127.                                                                                                    
  128.                                                                                                              
  129.  
  130.  
  131. ;-----------------------------------------------------------------
  132. ;
  133. ; ICMP_input:
  134. ;
  135. ;  This procedure will send reply's to ICMP echo's
  136. ;   and insert packets into sockets when needed
  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. ;
  145. ;-----------------------------------------------------------------
  146. align 4
  147. ICMP_input:
  148.  
  149. ;;; TODO: works only on pure ethernet right now !
  150.  
  151.         DEBUGF  1,"ICMP_Handler - start\n"
  152.         cmp     byte [edx + ICMP_Packet.Type], ICMP_ECHO                    ; Is this an echo request?
  153.         jne     .check_sockets
  154.  
  155. ;;; TODO: check checksum!
  156.  
  157.         DEBUGF  1,"ICMP_Handler - echo request\n"
  158.  
  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.  
  162.         call    NET_ptr_to_num
  163.         cmp     edi,-1
  164.         je      .dump
  165.         inc     [ICMP_PACKETS_RX+4*edi]
  166.         inc     [ICMP_PACKETS_TX+4*edi]
  167.  
  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
  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
  198.  
  199. ; Recalculate ICMP CheckSum
  200.         movzx   eax, word[esi + IPv4_Packet.TotalLength]                    ; Find length of IP Packet
  201.         xchg    ah , al                                                     ;
  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
  210.         mov     word [edx + ICMP_Packet.Checksum], ax
  211.  
  212.         jmp     NET_send                                                  ; Send the reply
  213.                                                                             ; and return to caller of this proc
  214.  
  215.  
  216.  
  217.  
  218.        .check_sockets:
  219.         ; TODO: validate the header & checksum.
  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:
  227.         mov     esi, [esi + SOCKET.NextPtr]
  228.         or      esi, esi
  229.         jz      .dump
  230.         cmp     [esi + SOCKET.Type], IP_PROTO_ICMP
  231.         jne     .next_socket
  232.         cmp     [esi + ICMP_SOCKET.Identifier], ax
  233.         jne     .next_socket
  234.  
  235.         call    IPv4_dest_to_dev
  236.         cmp     edi,-1
  237.         je      .dump
  238.         inc     [ICMP_PACKETS_RX+4*edi]
  239.  
  240.         DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi
  241.  
  242.         lea     ebx, [esi + SOCKET.lock]
  243.         call    wait_mutex
  244.  
  245.         ; Now, assign data to socket. We have socket address in esi.
  246.         ; We have ICMP Packet in edx
  247.         ; number of bytes in ecx
  248.  
  249.         mov     eax, esi
  250.         pop     esi
  251.         add     esp, 4
  252.         sub     edx, esi
  253.         mov     edi, edx
  254. ;;;        jmp     SOCKET_input
  255.  
  256.        .dump:
  257.         DEBUGF  1,"ICMP_Handler - dumping\n"
  258.  
  259.         call    kernel_free
  260.         add     esp, 4 ; pop (balance stack)
  261.  
  262.         ret
  263.  
  264.  
  265. ;-----------------------------------------------------------------
  266. ;
  267. ; Note: ICMP only works on top of IP protocol :)
  268. ;
  269. ; inputs:
  270. ;
  271. ; eax = dest ip
  272. ; ebx = source ip
  273. ; ecx = data length
  274. ; dh = type
  275. ; dl = code
  276. ; high 16 bits of edx = fragment id (for IP header)
  277. ; esi = data offset
  278. ; edi = identifier shl 16 + sequence number
  279. ;
  280. ;-----------------------------------------------------------------
  281. align 4
  282. ICMP_output:
  283.  
  284.         DEBUGF 1,"Create ICMP Packet\n"
  285.  
  286.         push    esi edi edx
  287.  
  288.         add     ecx, ICMP_Packet.Data
  289.         mov     di , IP_PROTO_ICMP
  290.         shr     edx, 16
  291.  
  292.         call    IPv4_create_packet
  293.         jz      .exit
  294.  
  295.         DEBUGF 1,"full icmp packet size: %u\n", edx
  296.  
  297.         pop     eax
  298.         mov     word [edi + ICMP_Packet.Type], ax       ; Write both type and code bytes at once
  299.         pop     eax
  300.         mov     [edi + ICMP_Packet.SequenceNumber], ax
  301.         shr     eax, 16
  302.         mov     [edi + ICMP_Packet.Identifier], ax
  303.         mov     [edi + ICMP_Packet.Checksum], 0
  304.  
  305.         push    eax ebx ecx edx
  306.         mov     esi, edi
  307.         xor     edx, edx
  308.         call    checksum_1
  309.         call    checksum_2
  310.         mov     [edi + ICMP_Packet.Checksum], dx
  311.         pop     edx ecx ebx eax esi
  312.  
  313.         sub     ecx, ICMP_Packet.Data
  314.         add     edi, ICMP_Packet.Data
  315.         push    cx
  316.         shr     cx , 2
  317.         rep     movsd
  318.         pop     cx
  319.         and     cx , 3
  320.         rep     movsb
  321.  
  322.         sub     edi, edx                                ;;; TODO: find a better way to remember start of packet
  323.         mov     ecx, [ebx + ETH_DEVICE.transmit]
  324.         push    edx edi ecx
  325.         DEBUGF 1,"Sending ICMP Packet\n"
  326.         ret                                             ; Send the packet (create_packet routine outputs pointer to routine to send packet in eax)
  327.  
  328.   .exit:
  329.         DEBUGF 1,"Creating ICMP Packet failed\n"
  330.         add     esp, 3*4
  331.         ret
  332.  
  333.  
  334.  
  335.  
  336. ;-----------------------------------------------------------------
  337. ;
  338. ; ICMP_API
  339. ;
  340. ; This function is called by system function 75
  341. ;
  342. ; IN:  subfunction number in bl
  343. ;      device number in bh
  344. ;      ecx, edx, .. depends on subfunction
  345. ;
  346. ; OUT:
  347. ;
  348. ;-----------------------------------------------------------------
  349. align 4
  350. ICMP_API:
  351.  
  352.         movzx   eax, bh
  353.         shl     eax, 2
  354.  
  355.         test    bl, bl
  356.         jz      .packets_tx     ; 0
  357.         dec     bl
  358.         jz      .packets_rx     ; 1
  359.  
  360. .error:
  361.         mov     eax, -1
  362.         ret
  363.  
  364. .packets_tx:
  365.         add     eax, ICMP_PACKETS_TX
  366.         mov     eax, [eax]
  367.         ret
  368.  
  369. .packets_rx:
  370.         add     eax, ICMP_PACKETS_RX
  371.         mov     eax, [eax]
  372.         ret
  373.