home *** CD-ROM | disk | FTP | other *** search
/ sustworks.com / 2014.06.sustworks.com.tar / sustworks.com / open_source_IPNetMonitor_NKE.dmg / IPNetMonitor_NKE.h < prev   
Text File  |  2005-03-09  |  7KB  |  164 lines

  1. //
  2. //  IPNetMonitor_NKE.h
  3. //  Mac OS X Interface Filter NKE
  4. //
  5. //  Created by psichel [PAS] on Wed Mar 27 2002.
  6. //  Copyright (c) 2002 Sustainable Softworks Inc. All rights reserved.
  7. //
  8. //    Per Apple Computer's Open Source license, IPNetMonitor_NKE.c is
  9. //    Open Source to be available from the sustworks website.
  10. //    Other source files used by this kernel extension to perform
  11. //    NAT or IP filtering need not be Open Source.
  12. //
  13. //    Design Overview
  14. //  ===============
  15. //
  16. //  As an Interface (or Protocol) Filter NKE, we have two basic tasks:
  17. //
  18. //    (1) Insert our NKE as a non-global socket filter so it can
  19. //        intercept socket operations to serve as a control channel
  20. //        to any companion applications.
  21. //
  22. //  (2) Insert our NKE between the IP protocol layer and the DLIL
  23. //      so it can examine and modify IP traffic on each data link.
  24. //
  25. //  I have chosen to use standard UDP for the control channel interface
  26. //  since most control operations are either periodic reports (traffic
  27. //  counts, filter log entries) or transaction oriented (configure some
  28. //    internal state).  For just logging traffic, I might have used TCP.
  29. //    For driver control operations, I might have used a PF_NDRV raw
  30. //    socket (requires privileges).
  31. //
  32. //  Alternatively we can use PF_NKE as defined by Apple for our control
  33. //    interface, but Im not sure what value PF_NKE provides [PAS].
  34. //
  35. //    Since our NKE is non-global, a controller establishes communication by:
  36. //  (1) Making sure the NKE is loaded (kextload corresponding file)
  37. //    (2) Opening a UDP socket
  38. //    (3) Performing a setsockopt specifying our NKE by handle (signature)
  39. //
  40. //    setsockopt(s, SOL_SOCKET, SO_NKE, &so_nke, sizeof(struct so_nke));
  41. //
  42. //    See "Inside Mac OS X: Network Kernel Extensions" (file NKE.pdf)
  43. //    page 20-21.
  44. //
  45. //    Notice this NKE is designed to monitor more than one data link
  46. //    at a time (DLIL attachment instance), and allow multiple controllers.
  47. //  We define per DLIL attachment storage, and global storage allowing
  48. //    our controllers to interract with a single data link, or the entire
  49. //    set of data links.
  50. //
  51. //    For inserting our NKE below IP as a protocol filter, we use dlil_find_dltag
  52. //    to get the dl_tag for the protocol attachment to a given interface.
  53. //    If dlil_find_dltag returns an error, the protocol has not been attached
  54. //    to that data link so is not available.
  55. //
  56. //    For insertering our NKE below IP as an interface filter, we use the ifnet
  57. //    global variable which points to the list of ifnet structures and scan the
  58. //    list to find the desired ifnet structure with matching interface name.
  59. //
  60. //    The dlil_pr_flt_str (dlil_if_flt_str) used to register filters has a cookie
  61. //    field that will be passed to our data link functions.  We set the cookie to
  62. //    point to the instance storage we created for this dlil attachment allowing
  63. //    us to quickly identify which data link instance was called and collect
  64. //  per data link statistics.
  65. //  
  66. //  Once a controller has connected to our NKE, it can specify which dlil
  67. //    attachment is of interest for data link operations.  This will cause
  68. //    the NKE to attach to the corresponding data link if needed, or add
  69. //    a reference if we're already attached.
  70. //
  71. //    When the number of references for a dlil attachment reaches zero,
  72. //  the NKE is detached from that protocol interface pair or interface.
  73. //    We must also detach all references when the kext is unloaded
  74. //    and notify any clients their socket is going away.
  75. //    [Not sure how to do this yet except marking the socket invalid so
  76. //    the next request will fail - PAS]
  77. //    Notice the kernel will close any open sockets when a process terminates,
  78. //    so we intercept the soclose to tear down any dlil attach instances
  79. //    associated with that controlling socket.
  80. //
  81. //    Since our NKE can have multiple controllers from different applications,
  82. //    normally it should remain loaded, unless the user explicitly wishes
  83. //    to unload for some reason (debugging, or to load a newer version).
  84. //    We provide a menu item in the companion application to do this.
  85. //    Since there is no way to predict when another controller might try to
  86. //    insert the NKE after verifying it is loaded, it is the users responsibility
  87. //    to stop any applications that rely on this NKE before trying to unload it.
  88. //    Controllers should be designed to fail gracefully if the NKE goes away.
  89. //    One possibility is to ask the NKE if there are any outstanding connections
  90. //    before unloading it and/or tell the NKE to tear down any such connections.
  91. //
  92. //
  93. //    Control Channel Access
  94. //    ----------------------
  95. //
  96. //    Once a control socket has inserted our NKE, the following socket
  97. //     operations access NKE functions as follows:
  98. //
  99. //    connect -> ipk_connect
  100. //  disconnect -> ipk_disconnect
  101. //        ! close is intercepted to call our ipk_disconnect
  102. //    soclose -> ipk_disconnect
  103. //    soconnect -> ipk_connect
  104. //    setsockopt -> ik_control
  105. //  recvfrom -> any data inserted in socket buffer
  106. //  sendto -> appends data to socket buffer
  107. //
  108. //    Most controller initiated operations should use setsockopt since it
  109. //    allows passing an arbitrary structure and returning a result.
  110. //    These structures and option codes are defined below.
  111. //
  112. //    Both solicited and unsolicited NKE data or reports can be read
  113. //    using recvfrom (standard UDP).  The report datagrams need to be self
  114. //    identifying and optionally tied to the corresponding request.
  115. //
  116. //    We use the dl_tag as a convenient
  117. //  shorthand to uniquely identify each dlil attach instance.
  118. //
  119.  
  120. #include <sys/types.h>
  121. #include "ipkTypes.h"
  122.  
  123. // name prefix for global symbol names
  124. #define PROJECT com_sustworks_ipnm
  125.  
  126. // use IPNetMonitor app signature 'MIPR'
  127. #define IPNetMonitor_NKE_Handle    0x4D495052
  128. //
  129. // UDP SOL_SOCKET level options for controlling our NKE
  130. // Usage: setsockopt(s, SOL_SOCKET, optionCode, &so_nke, sizeof(struct so_nke));
  131. // s should be a UDP (or PF_NKE) socket with our NKE previously inserted using the SO_NKE option
  132.  
  133. #define SO_ATTACH_LINK    0x10A0
  134. #define SO_DETACH_LINK    0x10A1
  135. #define SO_MONITOR_ON    0x10A2
  136. #define SO_MONITOR_OFF    0x10A3
  137.  
  138. typedef struct    sopt_attachParam {
  139.     char    bsdName[16];    // bsdName of desired interface
  140.     short    protocolFilter;    // 0=interface filter, 1=protocol filter
  141. } sopt_attachParam_t;
  142.  
  143. // buffer size for ipk messages (must fit within a 2048 byte cluster)
  144. #define kUpdateBufferSize 2000
  145. // ---------------------------------------------------------------------------------
  146. // generic upstream message
  147. // ---------------------------------------------------------------------------------
  148. typedef struct    ipk_message {
  149.     int32_t    length;    // length of message
  150.     int32_t    type;    // identify message type/version
  151. } ipk_message_t;
  152.  
  153. // ---------------------------------------------------------------------------------
  154. // upstream message for monitorStats
  155. // ---------------------------------------------------------------------------------
  156. typedef struct    ipk_monitorStats {
  157.     int32_t    length;    // length of message
  158.     int32_t    type;    // identify message type/version
  159.     int32_t    sendCount;
  160.     int32_t    receiveCount;
  161. } ipk_monitorStats_t;
  162.  
  163. #define kMonitorStats    1
  164.