Re: Attaching interface filter NKE blocks Airport from coming up
Re: Attaching interface filter NKE blocks Airport from coming up
- Subject: Re: Attaching interface filter NKE blocks Airport from coming up
- From: Vincent Lubet <email@hidden>
- Date: Wed, 17 Mar 2010 13:42:36 -0700
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 (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden