home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.sustworks.com 2018
/
ftp.sustworks.com.zip
/
ftp.sustworks.com
/
open_source_IPNetMonitor_NKE.dmg
/
IPNetMonitor_NKE.h
< prev
Wrap
Text File
|
2005-03-09
|
7KB
|
164 lines
//
// IPNetMonitor_NKE.h
// Mac OS X Interface Filter NKE
//
// Created by psichel [PAS] on Wed Mar 27 2002.
// Copyright (c) 2002 Sustainable Softworks Inc. All rights reserved.
//
// Per Apple Computer's Open Source license, IPNetMonitor_NKE.c is
// Open Source to be available from the sustworks website.
// Other source files used by this kernel extension to perform
// NAT or IP filtering need not be Open Source.
//
// Design Overview
// ===============
//
// As an Interface (or Protocol) Filter NKE, we have two basic tasks:
//
// (1) Insert our NKE as a non-global socket filter so it can
// intercept socket operations to serve as a control channel
// to any companion applications.
//
// (2) Insert our NKE between the IP protocol layer and the DLIL
// so it can examine and modify IP traffic on each data link.
//
// I have chosen to use standard UDP for the control channel interface
// since most control operations are either periodic reports (traffic
// counts, filter log entries) or transaction oriented (configure some
// internal state). For just logging traffic, I might have used TCP.
// For driver control operations, I might have used a PF_NDRV raw
// socket (requires privileges).
//
// Alternatively we can use PF_NKE as defined by Apple for our control
// interface, but Im not sure what value PF_NKE provides [PAS].
//
// Since our NKE is non-global, a controller establishes communication by:
// (1) Making sure the NKE is loaded (kextload corresponding file)
// (2) Opening a UDP socket
// (3) Performing a setsockopt specifying our NKE by handle (signature)
//
// setsockopt(s, SOL_SOCKET, SO_NKE, &so_nke, sizeof(struct so_nke));
//
// See "Inside Mac OS X: Network Kernel Extensions" (file NKE.pdf)
// page 20-21.
//
// Notice this NKE is designed to monitor more than one data link
// at a time (DLIL attachment instance), and allow multiple controllers.
// We define per DLIL attachment storage, and global storage allowing
// our controllers to interract with a single data link, or the entire
// set of data links.
//
// For inserting our NKE below IP as a protocol filter, we use dlil_find_dltag
// to get the dl_tag for the protocol attachment to a given interface.
// If dlil_find_dltag returns an error, the protocol has not been attached
// to that data link so is not available.
//
// For insertering our NKE below IP as an interface filter, we use the ifnet
// global variable which points to the list of ifnet structures and scan the
// list to find the desired ifnet structure with matching interface name.
//
// The dlil_pr_flt_str (dlil_if_flt_str) used to register filters has a cookie
// field that will be passed to our data link functions. We set the cookie to
// point to the instance storage we created for this dlil attachment allowing
// us to quickly identify which data link instance was called and collect
// per data link statistics.
//
// Once a controller has connected to our NKE, it can specify which dlil
// attachment is of interest for data link operations. This will cause
// the NKE to attach to the corresponding data link if needed, or add
// a reference if we're already attached.
//
// When the number of references for a dlil attachment reaches zero,
// the NKE is detached from that protocol interface pair or interface.
// We must also detach all references when the kext is unloaded
// and notify any clients their socket is going away.
// [Not sure how to do this yet except marking the socket invalid so
// the next request will fail - PAS]
// Notice the kernel will close any open sockets when a process terminates,
// so we intercept the soclose to tear down any dlil attach instances
// associated with that controlling socket.
//
// Since our NKE can have multiple controllers from different applications,
// normally it should remain loaded, unless the user explicitly wishes
// to unload for some reason (debugging, or to load a newer version).
// We provide a menu item in the companion application to do this.
// Since there is no way to predict when another controller might try to
// insert the NKE after verifying it is loaded, it is the users responsibility
// to stop any applications that rely on this NKE before trying to unload it.
// Controllers should be designed to fail gracefully if the NKE goes away.
// One possibility is to ask the NKE if there are any outstanding connections
// before unloading it and/or tell the NKE to tear down any such connections.
//
//
// Control Channel Access
// ----------------------
//
// Once a control socket has inserted our NKE, the following socket
// operations access NKE functions as follows:
//
// connect -> ipk_connect
// disconnect -> ipk_disconnect
// ! close is intercepted to call our ipk_disconnect
// soclose -> ipk_disconnect
// soconnect -> ipk_connect
// setsockopt -> ik_control
// recvfrom -> any data inserted in socket buffer
// sendto -> appends data to socket buffer
//
// Most controller initiated operations should use setsockopt since it
// allows passing an arbitrary structure and returning a result.
// These structures and option codes are defined below.
//
// Both solicited and unsolicited NKE data or reports can be read
// using recvfrom (standard UDP). The report datagrams need to be self
// identifying and optionally tied to the corresponding request.
//
// We use the dl_tag as a convenient
// shorthand to uniquely identify each dlil attach instance.
//
#include <sys/types.h>
#include "ipkTypes.h"
// name prefix for global symbol names
#define PROJECT com_sustworks_ipnm
// use IPNetMonitor app signature 'MIPR'
#define IPNetMonitor_NKE_Handle 0x4D495052
//
// UDP SOL_SOCKET level options for controlling our NKE
// Usage: setsockopt(s, SOL_SOCKET, optionCode, &so_nke, sizeof(struct so_nke));
// s should be a UDP (or PF_NKE) socket with our NKE previously inserted using the SO_NKE option
#define SO_ATTACH_LINK 0x10A0
#define SO_DETACH_LINK 0x10A1
#define SO_MONITOR_ON 0x10A2
#define SO_MONITOR_OFF 0x10A3
typedef struct sopt_attachParam {
char bsdName[16]; // bsdName of desired interface
short protocolFilter; // 0=interface filter, 1=protocol filter
} sopt_attachParam_t;
// buffer size for ipk messages (must fit within a 2048 byte cluster)
#define kUpdateBufferSize 2000
// ---------------------------------------------------------------------------------
// generic upstream message
// ---------------------------------------------------------------------------------
typedef struct ipk_message {
int32_t length; // length of message
int32_t type; // identify message type/version
} ipk_message_t;
// ---------------------------------------------------------------------------------
// upstream message for monitorStats
// ---------------------------------------------------------------------------------
typedef struct ipk_monitorStats {
int32_t length; // length of message
int32_t type; // identify message type/version
int32_t sendCount;
int32_t receiveCount;
} ipk_monitorStats_t;
#define kMonitorStats 1