home *** CD-ROM | disk | FTP | other *** search
/ ftp.sustworks.com 2015 / ftp.sustworks.com.zip / ftp.sustworks.com / open_source_IPNetRouter_TNKE.dmg / IPNetRouter_TNKE.h < prev    next >
C/C++ Source or Header  |  2005-08-27  |  12KB  |  311 lines

  1. //
  2. //  IPNetRouter_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, IPNetRouter_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. //  [Some of this information will change for Tiger versus Panther, but concepts remain the same.]
  16. //
  17. //  As an Interface (or Protocol) Filter NKE, we have two basic tasks:
  18. //
  19. //    (1) Insert our NKE as a non-global socket filter so it can
  20. //        intercept socket operations to serve as a control channel
  21. //        to any companion applications.
  22. //
  23. //  (2) Insert our NKE between the IP protocol layer and the DLIL
  24. //      so it can examine and modify IP traffic on each data link.
  25. //
  26. //  I have chosen to use standard UDP for the control channel interface
  27. //  since most control operations are either periodic reports (traffic
  28. //  counts, filter log entries) or transaction oriented (configure some
  29. //    internal state).  For just logging traffic, I might have used TCP.
  30. //    For driver control operations, I might have used a PF_NDRV raw
  31. //    socket (requires privileges).
  32. //
  33. //  Alternatively we can use PF_NKE as defined by Apple for our control
  34. //    interface, but Im not sure what value PF_NKE provides [PAS].
  35. //
  36. //    Since our NKE is non-global, a controller establishes communication by:
  37. //  (1) Making sure the NKE is loaded (kextload corresponding file)
  38. //    (2) Opening a UDP socket
  39. //    (3) Performing a setsockopt specifying our NKE by handle (signature)
  40. //
  41. //    setsockopt(s, SOL_SOCKET, SO_NKE, &so_nke, sizeof(struct so_nke));
  42. //
  43. //    See "Inside Mac OS X: Network Kernel Extensions" (file NKE.pdf)
  44. //    page 20-21.
  45. //
  46. //    Notice this NKE is designed to monitor more than one data link
  47. //    at a time (DLIL attachment instance), and allow multiple controllers.
  48. //  We define per DLIL attachment storage, and global storage allowing
  49. //    our controllers to interract with a single data link, or the entire
  50. //    set of data links.
  51. //
  52. //    For inserting our NKE below IP as a protocol filter, we use dlil_find_dltag
  53. //    to get the dl_tag for the protocol attachment to a given interface.
  54. //    If dlil_find_dltag returns an error, the protocol has not been attached
  55. //    to that data link so is not available.
  56. //
  57. //    For insertering our NKE below IP as an interface filter, we use the ifnet
  58. //    global variable which points to the list of ifnet structures and scan the
  59. //    list to find the desired ifnet structure with matching interface name.
  60. //
  61. //    The dlil_pr_flt_str (dlil_if_flt_str) used to register filters has a cookie
  62. //    field that will be passed to our data link functions.  We set the cookie to
  63. //    point to the instance storage we created for this dlil attachment allowing
  64. //    us to quickly identify which data link instance was called and collect
  65. //  per data link statistics.
  66. //  
  67. //  Once a controller has connected to our NKE, it can specify which dlil
  68. //    attachment is of interest for data link operations.  This will cause
  69. //    the NKE to attach to the corresponding data link if needed, or add
  70. //    a reference if we're already attached.
  71. //
  72. //    When the number of references for a dlil attachment reaches zero,
  73. //  the NKE is detached from that protocol interface pair or interface.
  74. //    We must also detach all references when the kext is unloaded
  75. //    and notify any clients their socket is going away.
  76. //    [Not sure how to do this yet except marking the socket invalid so
  77. //    the next request will fail - PAS]
  78. //    Notice the kernel will close any open sockets when a process terminates,
  79. //    so we intercept the soclose to tear down any dlil attach instances
  80. //    associated with that controlling socket.
  81. //
  82. //    Since our NKE can have multiple controllers from different applications,
  83. //    normally it should remain loaded, unless the user explicitly wishes
  84. //    to unload for some reason (debugging, or to load a newer version).
  85. //    We provide a menu item in the companion application to do this.
  86. //    Since there is no way to predict when another controller might try to
  87. //    insert the NKE after verifying it is loaded, it is the users responsibility
  88. //    to stop any applications that rely on this NKE before trying to unload it.
  89. //    Controllers should be designed to fail gracefully if the NKE goes away.
  90. //    One possibility is to ask the NKE if there are any outstanding connections
  91. //    before unloading it and/or tell the NKE to tear down any such connections.
  92. //
  93. //
  94. //    Control Channel Access
  95. //    ----------------------
  96. //
  97. //    Once a control socket has inserted our NKE, the following socket
  98. //     operations access NKE functions as follows:
  99. //
  100. //    connect -> ipk_connect
  101. //  disconnect -> ipk_disconnect
  102. //        ! close is intercepted to call our ipk_disconnect
  103. //    soclose -> ipk_disconnect
  104. //    soconnect -> ipk_connect
  105. //    setsockopt -> ik_control
  106. //  recvfrom -> any data inserted in socket buffer
  107. //  sendto -> appends data to socket buffer
  108. //
  109. //    Most controller initiated operations should use setsockopt since it
  110. //    allows passing an arbitrary structure and returning a result.
  111. //    These structures and option codes are defined below.
  112. //
  113. //    Both solicited and unsolicited NKE data or reports can be read
  114. //    using recvfrom (standard UDP).  The report datagrams need to be self
  115. //    identifying and optionally tied to the corresponding request.
  116. //
  117. //    We use the dl_tag as a convenient
  118. //  shorthand to uniquely identify each dlil attach instance.
  119. //
  120.  
  121. #include <sys/types.h>
  122. #include "ipkTypes.h"
  123.  
  124. // use IPNetRouter app signature 'IPnl'
  125. #define IPNetRouter_TNKE_Handle    0x49506E6C
  126. //
  127. // UDP SOL_SOCKET level options for controlling our NKE
  128. // Usage: setsockopt(s, SOL_SOCKET, optionCode, &so_nke, sizeof(struct so_nke));
  129. // s should be a UDP (or PF_NKE) socket with our NKE previously inserted using the SO_NKE option
  130.  
  131. #define SO_ATTACH_LINK    0x10A0
  132. #define SO_DETACH_LINK    0x10A1
  133. #define SO_MONITOR_ON    0x10A2
  134. #define SO_MONITOR_OFF    0x10A3
  135. #define SO_FILTER_DOWNLOAD    0x10A4
  136. #define SO_FILTER_UPLOAD    0x10A5
  137. #define SO_KFT_RESET    0X10A6
  138. #define SO_FILTER_COUNT    0X10A7
  139. #define SO_SET_TIME        0x10A8
  140. #define SO_DROP_RESPONSE 0x10A9
  141. #define SO_TRIGGER_DURATION 0X10AA
  142. #define SO_TRIGGER_ADDRESS 0X10AB
  143. #define SO_TRIGGER_UPLOAD 0X10AC
  144. #define SO_INTERFACE_UPLOAD 0X10AD
  145. #define SO_PORTMAP_UPLOAD 0x10AE
  146. #define SO_IPK_MESSAGE 0X10AF
  147. #define SO_NAT_UPLOAD 0x10B0
  148. #define SO_TRIGGER_COUNT 0X10B1
  149. #define SO_INTERFACE_COUNT 0X10B2
  150. #define SO_PORTMAP_COUNT 0X10B3
  151.  
  152. #define SO_SET_FLAGS 0x10B4
  153. #define SO_GET_FLAGS 0x10B5
  154.  
  155. typedef struct    sopt_attachParam {
  156.     char    bsdName[16];    // bsdName of desired interface
  157.     short    protocolFilter;    // 0=interface filter, 1=protocol filter
  158. } sopt_attachParam_t;
  159.  
  160. typedef struct    sopt_timeParam {
  161.     u_long timeStamp;        // seconds from gettimeofday()
  162.     int secondOfDay;
  163.     int day;
  164. } sopt_timeParam_t;
  165.  
  166. typedef struct sopt_flagsParam {
  167.     u_int32_t flags;    // desired values
  168.     u_int32_t mask;        // which bits to modify
  169. } sopt_flagsParam_t;
  170. #define kFlag_sourceAwareRouting 0x01
  171.  
  172. typedef KFT_interfaceEntry_t sopt_kftParameters_t;
  173.  
  174.  
  175. // buffer size for ipk messages (must fit within a 2048 byte cluster)
  176. #define kUpdateBufferSize 2000
  177. // ---------------------------------------------------------------------------------
  178. // generic upstream message
  179. // ---------------------------------------------------------------------------------
  180. typedef struct    ipk_message {
  181.     int32_t    length;    // length of message
  182.     int32_t    type;    // identify message type/version
  183. } ipk_message_t;
  184.  
  185. // ---------------------------------------------------------------------------------
  186. // upstream message for monitorStats
  187. // ---------------------------------------------------------------------------------
  188. typedef struct    ipk_monitorStats {
  189.     int32_t    length;    // length of message
  190.     int32_t    type;    // identify message type/version
  191.     int32_t    sendCount;
  192.     int32_t    receiveCount;
  193. } ipk_monitorStats_t;
  194.  
  195. // ---------------------------------------------------------------------------------
  196. // upstream message for filter logging
  197. // ---------------------------------------------------------------------------------
  198. typedef struct    ipk_filterLog {
  199.     int32_t    length;    // length of message
  200.     int32_t    type;    // identify message type/version
  201.     unsigned char text[500];    // text of log message
  202. } ipk_filterLog_t;
  203.  
  204. // ---------------------------------------------------------------------------------
  205. // upstream message for filter update
  206. // ---------------------------------------------------------------------------------
  207. typedef struct ipk_countUpdate {
  208.     int32_t index;
  209.     int64_t lastTime;
  210.     KFT_stat64_t match;
  211.     KFT_stat64_t byte;
  212. } ipk_countUpdate_t;
  213.  
  214. typedef struct    ipk_filterUpdate {
  215.     int32_t    length;    // length of message
  216.     int32_t    type;    // identify message type/version
  217.     ipk_countUpdate_t countUpdate[1];    // some number of count updates
  218. } ipk_filterUpdate_t;
  219.  
  220. // ---------------------------------------------------------------------------------
  221. // upstream message for trigger update
  222. // ---------------------------------------------------------------------------------
  223. typedef struct    ipk_triggerUpdate {
  224.     int32_t    length;    // length of message
  225.     int32_t    type;    // identify message type/version
  226.     KFT_triggerEntry_t triggerUpdate[1];    // some number of trigger updates
  227. } ipk_triggerUpdate_t;
  228.  
  229. // ---------------------------------------------------------------------------------
  230. // upstream message for interface update
  231. // ---------------------------------------------------------------------------------
  232. typedef struct    ipk_interfaceUpdate {
  233.     int32_t    length;    // length of message
  234.     int32_t    type;    // identify message type/version
  235.     KFT_interfaceEntry_t interfaceUpdate[1];    // some number of interface updates
  236. } ipk_interfaceUpdate_t;
  237.  
  238. // ---------------------------------------------------------------------------------
  239. // upstream message for connection update
  240. // ---------------------------------------------------------------------------------
  241. typedef struct    ipk_connectionUpdate {
  242.     int32_t    length;    // length of message
  243.     int32_t    type;    // identify message type/version
  244.     KFT_connectionEntry_t connectionUpdate[1];    // some number of connection updates
  245. } ipk_connectionUpdate_t;
  246.  
  247. // ---------------------------------------------------------------------------------
  248. // upstream message for nat update
  249. // ---------------------------------------------------------------------------------
  250. typedef struct    ipk_natUpdate {
  251.     int32_t    length;    // length of message
  252.     int32_t    type;    // identify message type/version
  253.     KFT_natEntry_t natUpdate[1];    // some number of nat updates
  254. } ipk_natUpdate_t;
  255.  
  256. // ---------------------------------------------------------------------------------
  257. // upstream message for bridge update
  258. // ---------------------------------------------------------------------------------
  259. typedef struct    ipk_bridgeUpdate {
  260.     int32_t    length;    // length of message
  261.     int32_t    type;    // identify message type/version
  262.     KFT_bridgeEntry_t bridgeUpdate[1];    // some number of connection updates
  263. } ipk_bridgeUpdate_t;
  264.  
  265. // ---------------------------------------------------------------------------------
  266. // upstream message for failover update
  267. // ---------------------------------------------------------------------------------
  268. typedef struct    ipk_failoverUpdate {
  269.     int32_t    length;    // length of message
  270.     int32_t    type;    // identify message type/version
  271.     int32_t request;        // failover dest, remove dest, failover default route
  272.     u_int32_t dstAddress;    // dest ip of datagram to be re-routed
  273.     char bsdName[kBSDNameLength];
  274. } ipk_failoverUpdate_t;
  275. #define kFailoverDestination    1
  276. #define kFailoverRemove            2
  277. #define kFailoverDefault1        3
  278. #define kFailoverDefault2        4
  279.  
  280.  
  281. // Message types
  282. #define KFT_filterEntry_size 400
  283. #define kMonitorStats    1
  284. #define kFilterLog        2
  285. #define kFilterUpdate    3
  286. #define kFilterAlert    4
  287. #define kFilterEmail    5
  288. #define kFilterURL        6
  289. #define kFilterAppleScript    7
  290. #define kTriggerUpdate    8
  291. #define kConnectionUpdate 9
  292. #define kNatUpdate 10
  293. #define kInterfaceUpdate 11
  294. #define kPortMapUpdate 12
  295. #define kBridgeUpdate 13
  296. #define kFailoverUpdate 14
  297.  
  298.  
  299. void PROJECT_sendMessageToAll(ipk_message_t *message);
  300. int PROJECT_modifyReadyPacket(KFT_packetData_t* packet);
  301.  
  302. void PROJECT_lock();
  303. void PROJECT_unlock();
  304.  
  305. // tag values
  306. #define TAG_IN 1
  307. #define TAG_OUT 2
  308. errno_t PROJECT_mtag(mbuf_t mbuf_ref, int tag_value);
  309. int PROJECT_is_mtag(mbuf_t mbuf_ref, int tag_value);
  310.  
  311.