Subversion Repositories Kolibri OS

Rev

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