Subversion Repositories Kolibri OS

Rev

Rev 1165 | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. 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: 593 $
  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. ; ICMP_init
  109. ;
  110. ;  This function resets all ICMP variables
  111. ;
  112. ;  IN:  /
  113. ;  OUT: /
  114. ;
  115. ;-----------------------------------------------------------------
  116.  
  117. align 4
  118. ICMP_init:
  119.  
  120.         xor     eax, eax
  121.         mov     edi, ICMP_PACKETS_TX
  122.         mov     ecx, 2*MAX_IP
  123.         rep     stosd
  124.  
  125.         ret
  126.  
  127.  
  128.  
  129.  
  130.  
  131.                                                          
  132.                                                                                                    
  133.                                                                                                              
  134.  
  135.  
  136. ;--------------------------------
  137. ;
  138. ; ICMP_Handler:
  139. ;
  140. ;  Called by IP_handler,
  141. ;  this procedure will send reply's to ICMP echo's etc               ;;; TODO: update this to work with fragmented packets too!
  142. ;
  143. ;  IN:  Pointer to buffer in [esp]
  144. ;       size of buffer in [esp+4]
  145. ;       pointer to device struct in ebx
  146. ;       ICMP Packet size in ecx
  147. ;       pointer to ICMP Packet data in edx
  148. ;  OUT: /
  149. ;
  150. ;--------------------------------
  151.  
  152. align 4
  153. ICMP_Handler:   ;TODO: works only on pure ethernet right now !
  154.  
  155.         DEBUGF  1,"ICMP_Handler - start\n"
  156.         cmp     byte [edx + ICMP_Packet.Type], ICMP_ECHO                    ; Is this an echo request? discard if not
  157.         jne     .check_sockets
  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    ETH_struc2dev
  163.         cmp     edi,-1
  164.         je      .dump
  165.         inc     [ICMP_PACKETS_RX+4*edi]
  166.  
  167. ; exchange dest and source address in IP header
  168. ; exchange dest and source MAC in ETH header
  169.         mov     esi, [esp]
  170.  
  171.         mov     eax, dword [esi + ETH_FRAME.DstMAC]
  172.         mov     ecx, dword [esi + ETH_FRAME.SrcMAC]
  173.         mov     dword [esi + ETH_FRAME.SrcMAC], eax
  174.         mov     dword [esi + ETH_FRAME.DstMAC], ecx
  175.  
  176.         mov     ax, word [esi + ETH_FRAME.DstMAC + 4]
  177.         mov     cx, word [esi + ETH_FRAME.SrcMAC + 4]
  178.         mov     word [esi + ETH_FRAME.SrcMAC + 4], ax
  179.         mov     word [esi + ETH_FRAME.DstMAC + 4], cx
  180.  
  181.         mov     eax, dword [esi + ETH_FRAME.Data + IPv4_Packet.SourceAddress]
  182.         mov     ecx, dword [esi + ETH_FRAME.Data + IPv4_Packet.DestinationAddress]
  183.         mov     dword [esi + ETH_FRAME.Data + IPv4_Packet.DestinationAddress], eax
  184.         mov     dword [esi + ETH_FRAME.Data + IPv4_Packet.SourceAddress], ecx
  185.  
  186. ; Recalculate ip header checksum
  187. ;        mov     esi, [esp]
  188.         add     esi, ETH_FRAME.Data                                         ; Point esi to start of IP Packet
  189.         movzx   eax, byte [esi + IPv4_Packet.VersionAndIHL]                   ; Calculate IP Header length by using IHL field
  190.         and     eax, 0x0000000F                                             ;
  191.         shl     eax, 2                                                      ;
  192.         push    ebx edx esi
  193.         stdcall checksum_jb, esi, eax                                       ; calculate the checksum
  194.         pop     esi edx ebx
  195.         xchg    al, ah                                                      ; convert to intel byte order
  196. ;        mov     esi, [esp]
  197.         mov     word [esi + IPv4_Packet.HeaderChecksum], ax  ; Store it in the IP Packet header
  198.  
  199. ; Recalculate ICMP CheckSum
  200. ;        mov     esi, [esp]                                                 ; Find length of IP Packet
  201.         movzx   eax, word[esi + IPv4_Packet.TotalLength]     ;
  202.         xchg    ah , al                                                     ;
  203.         movzx   edi, byte [esi + IPv4_Packet.VersionAndIHL]  ; Calculate IP Header length by using IHL field
  204.         and     edi, 0x0000000F                                             ;
  205.         shl     edi, 2                                                      ;
  206.         sub     ax , di                                                     ; Now we know the length of ICMP data in eax
  207.         push    ebx edx
  208.         stdcall checksum_jb,edx,eax                                         ; Calculate the checksum of icmp data
  209.         pop     edx ebx
  210.         xchg    al, ah                                                      ; Convert to intel byte order
  211.         mov     word [edx + ICMP_Packet.Checksum], ax
  212.  
  213.         jmp     ETH_Sender                                                  ; Send the reply
  214.  
  215.  
  216.  
  217.  
  218.  
  219.        .check_sockets:
  220.         ; TODO: validate the header & checksum. Discard buffer if error
  221.  
  222.         ; Look for an open ICMP socket
  223.  
  224.         mov     esi, net_sockets
  225.   .try_more:
  226.         mov     ax , [edx + ICMP_Packet.Identifier]
  227.   .next_socket:
  228.         mov     esi, [esi + SOCKET.NextPtr]
  229.         or      esi, esi
  230.         jz      .dump
  231.         cmp     [esi + SOCKET.Type], IP_PROTO_ICMP
  232.         jne     .next_socket
  233.         cmp     [esi + SOCKET.LocalPort], ax
  234.         jne     .next_socket
  235.  
  236.         cmp     [esi + SOCKET.rxDataCount],0          ; get # of bytes already in buffer
  237.         jnz     .dump                                 ; only one packet at a time may be in the buffer!
  238.  
  239.         cmp     ecx, SOCKETBUFFSIZE - SOCKETHEADERSIZE; TODO: fix this problem !
  240.         jg      .dump
  241.  
  242.         call    IPv4_dest_to_dev
  243.         cmp     edi,-1
  244.         je      .dump
  245.         inc     [ICMP_PACKETS_RX+4*edi]
  246.  
  247.         DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi
  248.  
  249.         lea     ebx, [esi + SOCKET.lock]
  250.         call    wait_mutex
  251.  
  252.         ; Now, copy data to socket. We have socket address in esi.
  253.         ; We have ICMP Packet in edx
  254.         ; number of bytes in ecx
  255.  
  256.         ; note: we do not strip the header!
  257.  
  258.         DEBUGF 1,"bytes: %u\n", ecx
  259.  
  260.         mov     [esi + SOCKET.rxDataCount], ecx
  261.  
  262.         lea     edi, [esi + SOCKETHEADERSIZE]
  263.         push    esi
  264.         push    ecx
  265.         mov     esi, edx
  266.         shr     ecx, 2
  267.         rep     movsd          ; copy the data across
  268.         pop     ecx
  269.         and     ecx, 3
  270.         rep     movsb
  271.         pop     esi
  272.  
  273.         DEBUGF 1,"ICMP socket updated\n"
  274.  
  275.         mov     [esi + SOCKET.lock], 0
  276.  
  277.         ; flag an event to the application
  278.         mov     eax, [esi + SOCKET.PID]                 ; get socket owner PID
  279.         mov     ecx, 1
  280.         mov     esi, TASK_DATA + TASKDATA.pid
  281.  
  282.        .next_pid:
  283.         cmp     [esi], eax
  284.         je      .found_pid
  285.         inc     ecx
  286.         add     esi, 0x20
  287.         cmp     ecx, [TASK_COUNT]
  288.         jbe     .next_pid
  289.  
  290.         jmp     .dump
  291.  
  292.        .found_pid:
  293.         shl     ecx, 8
  294.         or      [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
  295.  
  296.         mov     [check_idle_semaphore], 200
  297.  
  298.        .dump:
  299.         DEBUGF  1,"ICMP_Handler - dumping\n"
  300.  
  301.         call    kernel_free
  302.         add     esp, 8 ; pop (balance stack)
  303.  
  304.         ret
  305.  
  306.  
  307. ;--------------------------------
  308. ;
  309. ; ICMP_Handler_fragments:
  310. ;
  311. ;  Called by IP_handler,
  312. ;  this procedure will send reply's to ICMP echo's etc
  313. ;
  314. ;  IN:  Pointer to buffer in [esp]
  315. ;       size of buffer in [esp+4]
  316. ;       pointer to device struct in ebx
  317. ;       ICMP Packet size in ecx
  318. ;       pointer to ICMP Packet data in edx
  319. ;  OUT: /
  320. ;
  321. ;--------------------------------
  322.  
  323. align 4
  324. ICMP_Handler_fragments:   ; works only on pure ethernet right now !
  325.  
  326.         DEBUGF  1,"ICMP_Handler_fragments - start\n"
  327.  
  328.         cmp     ecx, 65500
  329.         jg      .dump
  330.  
  331.         cmp     byte [edx + ICMP_Packet.Type], ICMP_ECHO                    ; Is this an echo request? discard if not
  332.         jne     .dump
  333.  
  334.         mov     esi, [esp]
  335.  
  336.         sub     ecx, ICMP_Packet.Data
  337.         mov     eax, [esi + IPv4_Packet.SourceAddress]
  338.         mov     ebx, [esi + IPv4_Packet.DestinationAddress]
  339.         push    word [esi + IPv4_Packet.Identification]
  340.  
  341.         mov     di , [edx + ICMP_Packet.Identifier]
  342.         shl     edi, 16
  343.         mov     di , [edx + ICMP_Packet.SequenceNumber]
  344.  
  345.         mov     esi, edx
  346.         add     esi, ICMP_Packet.Data
  347.         pop     dx
  348.         shl     edx, 16
  349.         mov     dx , ICMP_ECHOREPLY shl 8 + 0                               ; Type + Code
  350.  
  351.         call    ICMP_create_Packet
  352.  
  353.        .dump:
  354.         DEBUGF  1,"ICMP_Handler_fragments - end\n"
  355.  
  356.         call    kernel_free
  357.         add     esp, 8 ; pop (balance stack)
  358.         ret
  359.  
  360. ;-----------------------------------------------------------------
  361. ;
  362. ; Note: ICMP only works on top of IP protocol :)
  363. ;
  364. ; inputs:
  365. ;
  366. ; eax = dest ip
  367. ; ebx = source ip
  368. ; ecx = data length
  369. ; dh = type
  370. ; dl = code
  371. ; high 16 bits of edx = fragment id (for IP header)
  372. ; esi = data offset
  373. ; edi = identifier shl 16 + sequence number
  374. ;
  375. ;-----------------------------------------------------------------
  376.  
  377. align 4
  378. ICMP_create_Packet:
  379.  
  380.         DEBUGF 1,"Create ICMP Packet\n"
  381.  
  382.         push    esi edi edx
  383.  
  384.         add     ecx, ICMP_Packet.Data
  385.         mov     di , IP_PROTO_ICMP
  386.         shr     edx, 16
  387.  
  388.         call    IPv4_create_Packet
  389.  
  390.         cmp     edi, -1
  391.         je      .exit
  392.  
  393.         DEBUGF 1,"full icmp packet size: %u\n", ebx
  394.  
  395.         pop     eax
  396.         mov     word [edi + ICMP_Packet.Type], ax       ; Write both type and code bytes at once
  397.         pop     eax
  398.         mov     [edi + ICMP_Packet.SequenceNumber], ax
  399.         shr     eax, 16
  400.         mov     [edi + ICMP_Packet.Identifier], ax
  401.         mov     [edi + ICMP_Packet.Checksum], 0
  402.  
  403.         stdcall checksum_jb, edi , ecx
  404.         xchg    al, ah
  405.         mov     [edi + ICMP_Packet.Checksum], ax
  406.  
  407.         pop     esi
  408.         sub     ecx, ICMP_Packet.Data
  409.         add     edi, ICMP_Packet.Data
  410.         push    cx
  411.         shr     cx , 2
  412.         rep     movsd
  413.         pop     cx
  414.         and     cx , 3
  415.         rep     movsb
  416.  
  417.         sub     edi, ebx  ;; TODO: find a better way to remember start of packet
  418.         xchg    ebx, edx
  419.         mov     ecx, [ebx + ETH_DEVICE.transmit]
  420.         push    edx edi ecx
  421.         DEBUGF 1,"Sending ICMP Packet\n"
  422.         ret                                             ; Send the packet (create_packet routine outputs pointer to routine to send packet in eax)
  423.  
  424.   .exit:
  425.         DEBUGF 1,"Creating ICMP Packet failed\n"
  426.         add     esp, 3*4
  427.         ret
  428.  
  429.  
  430.  
  431.  
  432. ;---------------------------------------------------------------------------
  433. ;
  434. ; ICMP_API
  435. ;
  436. ; This function is called by system function 75
  437. ;
  438. ; IN:  subfunction number in bl
  439. ;      device number in bh
  440. ;      ecx, edx, .. depends on subfunction
  441. ;
  442. ; OUT:
  443. ;
  444. ;---------------------------------------------------------------------------
  445.  
  446. align 4
  447. ICMP_API:
  448.  
  449.         movzx   eax, bh
  450.         shl     eax, 2
  451.  
  452.         test    bl, bl
  453.         jz      .packets_tx     ; 0
  454.         dec     bl
  455.         jz      .packets_rx     ; 1
  456.  
  457. .error:
  458.         mov     eax, -1
  459.         ret
  460.  
  461. .packets_tx:
  462.         add     eax, ICMP_PACKETS_TX
  463.         mov     eax, [eax]
  464.         ret
  465.  
  466. .packets_rx:
  467.         add     eax, ICMP_PACKETS_RX
  468.         mov     eax, [eax]
  469.         ret
  470.