home *** CD-ROM | disk | FTP | other *** search
/ sustworks.com / 2014.06.sustworks.com.tar / sustworks.com / open_source_IPNetSentry_TNKE.dmg / IPNetSentry_TNKE.h < prev    next >
Text File  |  2005-08-10  |  12KB  |  310 lines

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