home *** CD-ROM | disk | FTP | other *** search
/ sustworks.com / 2014.06.sustworks.com.tar / sustworks.com / open_source_IPNetSentry_NKE.dmg / IPNetSentry_NKE.h < prev    next >
C/C++ Source or Header  |  2005-08-10  |  12KB  |  299 lines

  1. //
  2. //  IPNetSentry_NKE.h
  3. //  Mac OS X Interface Filter NKE
  4. //
  5. //  Created by psichel [PAS] on Teus Nov 12 2002.
  6. //  Copyright (c) 2002 Sustainable Softworks Inc. All rights reserved.
  7. //
  8. //    Per Apple Computer's Open Source license, IPNetSentry_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 "ipkTypes.h"
  121.  
  122. // use IPNetSentry app signature 'NScp'
  123. #define IPNetSentry_NKE_Handle    0x4E536370
  124. //
  125. // UDP SOL_SOCKET level options for controlling our NKE
  126. // Usage: setsockopt(s, SOL_SOCKET, optionCode, &so_nke, sizeof(struct so_nke));
  127. // s should be a UDP (or PF_NKE) socket with our NKE previously inserted using the SO_NKE option
  128.  
  129. #define SO_ATTACH_LINK    0x10A0
  130. #define SO_DETACH_LINK    0x10A1
  131. #define SO_MONITOR_ON    0x10A2
  132. #define SO_MONITOR_OFF    0x10A3
  133. #define SO_FILTER_DOWNLOAD    0x10A4
  134. #define SO_FILTER_UPLOAD    0x10A5
  135. #define SO_KFT_RESET    0X10A6
  136. #define SO_FILTER_COUNT    0X10A7
  137. #define SO_SET_TIME        0x10A8
  138. #define SO_DROP_RESPONSE 0x10A9
  139. #define SO_TRIGGER_DURATION 0X10AA
  140. #define SO_TRIGGER_ADDRESS 0X10AB
  141. #define SO_TRIGGER_UPLOAD 0X10AC
  142. #define SO_INTERFACE_UPLOAD 0X10AD
  143. #define SO_PORTMAP_UPLOAD 0x10AE
  144. #define SO_IPK_MESSAGE 0X10AF
  145. #define SO_NAT_UPLOAD 0x10B0
  146. #define SO_TRIGGER_COUNT 0X10B1
  147. #define SO_INTERFACE_COUNT 0X10B2
  148. #define SO_PORTMAP_COUNT 0X10B3
  149.  
  150. #define SO_SET_FLAGS 0x10B4
  151. #define SO_GET_FLAGS 0x10B5
  152.  
  153. typedef struct    sopt_attachParam {
  154.     char    bsdName[16];    // bsdName of desired interface
  155.     short    protocolFilter;    // 0=interface filter, 1=protocol filter
  156. } sopt_attachParam_t;
  157.  
  158. typedef struct    sopt_timeParam {
  159.     u_long timeStamp;        // seconds from gettimeofday()
  160.     int secondOfDay;
  161.     int day;
  162. } sopt_timeParam_t;
  163.  
  164. typedef struct sopt_flagsParam {
  165.     u_int32_t flags;    // desired values
  166.     u_int32_t mask;        // which bits to modify
  167. } sopt_flagsParam_t;
  168. #define kFlag_sourceAwareRouting 0x01
  169.  
  170. typedef KFT_interfaceEntry_t sopt_kftParameters_t;
  171.  
  172. // buffer size for ipk messages (must fit within a 2048 byte cluster)
  173. #define kUpdateBufferSize 2000
  174. // ---------------------------------------------------------------------------------
  175. // generic upstream message
  176. // ---------------------------------------------------------------------------------
  177. typedef struct    ipk_message {
  178.     int32_t    length;    // length of message
  179.     int32_t    type;    // identify message type/version
  180. } ipk_message_t;
  181.  
  182. // ---------------------------------------------------------------------------------
  183. // upstream message for monitorStats
  184. // ---------------------------------------------------------------------------------
  185. typedef struct    ipk_monitorStats {
  186.     int32_t    length;    // length of message
  187.     int32_t    type;    // identify message type/version
  188.     int32_t    sendCount;
  189.     int32_t    receiveCount;
  190. } ipk_monitorStats_t;
  191.  
  192. // ---------------------------------------------------------------------------------
  193. // upstream message for filter logging
  194. // ---------------------------------------------------------------------------------
  195. typedef struct    ipk_filterLog {
  196.     int32_t    length;    // length of message
  197.     int32_t    type;    // identify message type/version
  198.     unsigned char text[500];    // text of log message
  199. } ipk_filterLog_t;
  200.  
  201. // ---------------------------------------------------------------------------------
  202. // upstream message for filter update
  203. // ---------------------------------------------------------------------------------
  204. typedef struct ipk_countUpdate {
  205.     int32_t index;
  206.     int64_t lastTime;
  207.     KFT_stat64_t match;
  208.     KFT_stat64_t byte;
  209. } ipk_countUpdate_t;
  210.  
  211. typedef struct    ipk_filterUpdate {
  212.     int32_t    length;    // length of message
  213.     int32_t    type;    // identify message type/version
  214.     ipk_countUpdate_t countUpdate[1];    // some number of count updates
  215. } ipk_filterUpdate_t;
  216.  
  217. // ---------------------------------------------------------------------------------
  218. // upstream message for trigger update
  219. // ---------------------------------------------------------------------------------
  220. typedef struct    ipk_triggerUpdate {
  221.     int32_t    length;    // length of message
  222.     int32_t    type;    // identify message type/version
  223.     KFT_triggerEntry_t triggerUpdate[1];    // some number of trigger updates
  224. } ipk_triggerUpdate_t;
  225.  
  226. // ---------------------------------------------------------------------------------
  227. // upstream message for interface update
  228. // ---------------------------------------------------------------------------------
  229. typedef struct    ipk_interfaceUpdate {
  230.     int32_t    length;    // length of message
  231.     int32_t    type;    // identify message type/version
  232.     KFT_interfaceEntry_t interfaceUpdate[1];    // some number of interface updates
  233. } ipk_interfaceUpdate_t;
  234.  
  235. // ---------------------------------------------------------------------------------
  236. // upstream message for connection update
  237. // ---------------------------------------------------------------------------------
  238. typedef struct    ipk_connectionUpdate {
  239.     int32_t    length;    // length of message
  240.     int32_t    type;    // identify message type/version
  241.     KFT_connectionEntry_t connectionUpdate[1];    // some number of connection updates
  242. } ipk_connectionUpdate_t;
  243.  
  244. // ---------------------------------------------------------------------------------
  245. // upstream message for nat update
  246. // ---------------------------------------------------------------------------------
  247. typedef struct    ipk_natUpdate {
  248.     int32_t    length;    // length of message
  249.     int32_t    type;    // identify message type/version
  250.     KFT_natEntry_t natUpdate[1];    // some number of nat updates
  251. } ipk_natUpdate_t;
  252.  
  253. // ---------------------------------------------------------------------------------
  254. // upstream message for bridge update
  255. // ---------------------------------------------------------------------------------
  256. typedef struct    ipk_bridgeUpdate {
  257.     int32_t    length;    // length of message
  258.     int32_t    type;    // identify message type/version
  259.     KFT_bridgeEntry_t bridgeUpdate[1];    // some number of connection updates
  260. } ipk_bridgeUpdate_t;
  261.  
  262. // ---------------------------------------------------------------------------------
  263. // upstream message for failover update
  264. // ---------------------------------------------------------------------------------
  265. typedef struct    ipk_failoverUpdate {
  266.     int32_t    length;    // length of message
  267.     int32_t    type;    // identify message type/version
  268.     int32_t request;        // failover dest, remove dest, failover default route
  269.     u_int32_t dstAddress;    // dest ip of datagram to be re-routed
  270.     char bsdName[kBSDNameLength];
  271. } ipk_failoverUpdate_t;
  272. #define kFailoverDestination    1
  273. #define kFailoverRemove            2
  274. #define kFailoverDefault1        3
  275. #define kFailoverDefault2        4
  276.  
  277.  
  278. // Message types
  279. #define KFT_filterEntry_size 400
  280. #define kMonitorStats    1
  281. #define kFilterLog        2
  282. #define kFilterUpdate    3
  283. #define kFilterAlert    4
  284. #define kFilterEmail    5
  285. #define kFilterURL        6
  286. #define kFilterAppleScript    7
  287. #define kTriggerUpdate    8
  288. #define kConnectionUpdate 9
  289. #define kNatUpdate 10
  290. #define kInterfaceUpdate 11
  291. #define kPortMapUpdate 12
  292. #define kBridgeUpdate 13
  293. #define kFailoverUpdate 14
  294.  
  295.  
  296. void PROJECT_sendMessageToAll(ipk_message_t *message);
  297. int PROJECT_modifyReadyPacket(KFT_packetData_t* packet);
  298.  
  299.