Re: Attaching interface filter NKE blocks Airport from coming up
site_archiver@lists.apple.com Delivered-To: macnetworkprog@lists.apple.com Brendan, You ioctl filter function should return EOPNOTSUPP instead of 0, this is documented in <net/kpi_interfacefilter.h>:
@typedef iff_ioctl_func
@discussion iff_ioctl_func is used to filter ioctls sent to an interface. The interface is only valid for the duration of the filter call. If you need to keep a reference to the interface, be sure to call ifnet_reference and ifnet_release.
All undefined ioctls are reserved for future use by Apple. If you need to communicate with your kext using an ioctl, please use SIOCSIFKPI and SIOCGIFKPI. @param cookie The cookie specified when this filter was attached. @param interface The interface the packet is being transmitted on. @param ioctl_cmd The ioctl command. @param ioctl_arg A pointer to the ioctl argument. @result Return: 0 - This filter function handled the ioctl. EOPNOTSUPP - This filter function does not understand/did not handle this ioctl. EJUSTRETURN - This filter function handled the ioctl, processing should stop. Anything Else - Processing will stop, the error will be returned.
Vincent On Mar 17, 2010, at 12:21 PM, Brendan Creane wrote:
Hi All, My interface filter NKE tries to attach to "en1" while the link is down, but still advertised by ifnet_find_by_name() or ifnet_list_get(). While my nke is attached, Airport will not transition to IFF_RUNNING, even after "turning airport on." As soon as I detatch my nke from en1, Airport begins functioning again.
If I wait for en1 to transition to IFF_RUNNING before attaching, everything is fine. So it seems like attaching to en1 before it's up and running breaks Airport's ability to finish initializing.
My question is whether it's necessary to wait till en1 is both UP and RUNNING before attaching an interface filter NKE, or if I'm doing something wrong with how I attach to en1.
Sample code is below. Thank you for your time. regards, Brendan
////////////////////////////////////////////////////////////////////////////// static interface_filter_t filter_ref = NULL; static struct iff_filter enet_filter; static char if_name[DEV_NAME_LEN];
bool init_filter() { enet_filter.iff_cookie = NULL; enet_filter.iff_name = MY_BUNDLE_ID; enet_filter.iff_protocol = 0; // intercept packets with any protocol value enet_filter.iff_input = b_enet_input_func; enet_filter.iff_output = b_enet_output_func; enet_filter.iff_event = b_enet_event_func; enet_filter.iff_ioctl = b_enet_ioctl_func; enet_filter.iff_detached = b_enet_detached_func; bzero(if_name, sizeof(if_name)); strncpy(if_name, "en1", sizeof(if_name));
ifnet_t netif = NULL; errno_t rv;
rv = ifnet_find_by_name(if_name, &netif);
if (rv != KERN_SUCCESS) { printf("%s - ifnet_find_by_name(%s), err=%d\n", __FUNCTION__, if_name, rv); return false; }
rv = iflt_attach(netif, &enet_filter, &filter_ref);
// release the reference on the interface if (netif) { ifnet_release(netif); netif = NULL; }
if (rv != KERN_SUCCESS) { printf("%s - Failed to attach to %s (err=%d)\n", __FUNCTION__, if_name, rv); filter_ref = NULL; return false; } else { printf("%s - Successfully attached to %s\n", __FUNCTION__, if_name); }
return true; }
void detatch() { if (filter_ref) { printf("%s - detatching from %s\n", __FUNCTION__, if_name); iflt_detach(filter_ref); filter_ref = NULL; } }
extern "C" { static errno_t b_enet_input_func(void* cookie, ifnet_t interface, protocol_family_t protocol, mbuf_t *m, char **frame_ptr) { return KERN_SUCCESS; // pass through packet }
static errno_t b_enet_output_func(void* cookie, ifnet_t interface, protocol_family_t protocol, mbuf_t *m) { return KERN_SUCCESS; // pass through packet }
static void b_enet_detached_func(void* cookie, ifnet_t interface) { detatch(); }
static void b_enet_event_func(void* cookie, ifnet_t interface, protocol_family_t protocol, const struct kev_msg *event_msg) { // Data-link event if (event_msg->vendor_code == KEV_VENDOR_APPLE && event_msg->kev_class == KEV_NETWORK_CLASS && event_msg->kev_subclass == KEV_DL_SUBCLASS) { if (event_msg->event_code == KEV_DL_LINK_OFF) { detatch(); } }
printf("filter (%s) event: vendor %u, class %u, subclass %u, code %u\n", if_name, event_msg->vendor_code, event_msg->kev_class, event_msg->kev_subclass, event_msg->event_code); }
static errno_t b_enet_ioctl_func(void* cookie, ifnet_t interface, protocol_family_t protocol, u_long ioctl_cmd, void* ioctl_arg) { const uint8_t basecmd = (uint8_t) (IOCBASECMD(ioctl_cmd) & 0xff);
printf("enet_ioctl() - if=%p, proto=%u, " "base_cmd=%u, grp='%c', len=%u\n", interface, protocol, basecmd, (char)IOCGROUP(ioctl_cmd), (uint32_t)IOCPARM_LEN(ioctl_cmd));
return KERN_SUCCESS; } }; _______________________________________________ Do not post admin requests to the list. They will be ignored. Macnetworkprog mailing list (Macnetworkprog@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/macnetworkprog/vlubet%40apple.com
This email sent to vlubet@apple.com
_______________________________________________ Do not post admin requests to the list. They will be ignored. Macnetworkprog mailing list (Macnetworkprog@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/macnetworkprog/site_archiver%40lists.... This email sent to site_archiver@lists.apple.com
participants (1)
-
Vincent Lubet