Re: Detecting network disconnected
Re: Detecting network disconnected
- Subject: Re: Detecting network disconnected
- From: "Peter Sichel" <email@hidden>
- Date: Thu, 29 May 2003 16:15:51 -0400
>
On Thursday, May 29, 2003, at 10:04 AM, Larry Gerndt wrote:
>
>
> When using BSD sockets, what's the right way of detecting that the
>
> user has
>
> disconnected his Mac from the network (i.e. pulled the plug)?
If you mean detecting that a specific Ethernet interface such as en0
is no longer connected, I think you could listen for the kernel event
KEV_DL_IF_DETACHED or KEV_DL_PROTO_DETACHED.
I use this to detect when a new interface appears or disappears
something like this:
// Encapsulate a PF_SYSTEM socket for receiving SYSPROTO_EVENT messages
#import "KEVSocket.h"
#import <sys/uio.h> // iovec
@implementation KEVSocket
//--Setup--
- (id)init {
int socket;
//socket = Socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
socket = OpenRawSocket([NSArray arrayWithObject:@"-kev"]);
self = [super initWithSocket:socket];
return self;
}
@end
You need root privileges for the socket call to succeed, so
I use "OpenRawSocket" to invoke an SUID root helper application
to open a raw socket of the requested type and pass back the
socket fd using BSD descriptor passing.
Then you need to configure the socket for the events you wish to receive:
// get a PF_SYSTEM socket
if (!mKEVSocket) {
mKEVSocket = [[KEVSocket alloc] init];
// Configure the socket to receive the events we're interested in
kev_request.vendor_code = KEV_VENDOR_APPLE;
kev_request.kev_class = KEV_NETWORK_CLASS;
kev_request.kev_subclass = KEV_DL_SUBCLASS;
retval = ioctl([mKEVSocket socket], SIOCSKEVFILT, (void
*)&kev_request);
if (retval != 0) {
NSLog(@"KEVSocket failed to set event filter (%s)",
strerror(retval));
}
}
Then you listen for and decode incoming messages on this socket:
if ([key isEqualTo:UDPMessageNotification]) {
IPNetMessage* message;
struct kern_event_msg *event;
struct net_event_data *eventData;
NSString* bsdName;
// extract event code and bsdName from kernel event message
message = [dictionary objectForKey:key];
event = (struct kern_event_msg *)[[message data] bytes];
if (event->kev_class == KEV_NETWORK_CLASS) {
//NSLog(@"received kernel event with code %d", event->event_code);
eventData = (struct net_event_data *)event->event_data;
bsdName = [NSString stringWithFormat:@"%s%d",eventData->if_name,
eventData->if_unit];
if (event->event_code == KEV_DL_PROTO_ATTACHED) {
// protocol was attached, insert NKE for corresponding link
// detach first to clear any stale attachment
[self sendURL:[NSString stringW
ithFormat:@"%@%@",kSentryDetach,bsdName]];
[self sendURL:[NSString stringW
ithFormat:@"%@%@",kSentryAttach,bsdName]];
// log it
logText = [NSString stringWithFormat:@"KEV_DL_PROTO_ATTACHED %@",
bsdName];
logText = [logger formatLogMessage:logText];
[logger appendMessage:logText];
}
else if (event->event_code == KEV_DL_IF_DETACHED) {
// interface was detached, remove NKE for corresponding link
[self sendURL:[NSString stringW
ithFormat:@"%@%@",kSentryDetach,bsdName]];
// log it
logText = [NSString stringWithFormat:@"KEV_DL_IF_DETACHED %@", bsdName];
logText = [logger formatLogMessage:logText];
[logger appendMessage:logText];
}
}
} // if ([key isEqualTo:UDPMessageNotification])
I hope this helps.
- Peter Sichel
Sustainable Softworks
_______________________________________________
macnetworkprog mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/macnetworkprog
Do not post admin requests to the list. They will be ignored.