Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here is some code I wrote to find the routes for the machine. I copied the system calls from the code for <code>netstat</code>. Note that I was strongly recommended against doing this, as these system calls are not a supported API and may change at any time. They recommended I just parse the output of <code>netstat</code>.</p> <p>CustomRoute.c:</p> <pre><code>#import "CustomRoute.h" @implementation CustomRoute + (NSMutableArray*) getRoutes { NSMutableArray* routeArray = [NSMutableArray array]; CustomRoute* route = nil; size_t needed; int mib[6]; char *buf, *next, *lim; register struct rt_msghdr2 *rtm; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP2; mib[5] = 0; if (sysctl(mib, 6, NULL, &amp;needed, NULL, 0) &lt; 0) { err(1, "sysctl: net.route.0.0.dump estimate"); } if ((buf = malloc(needed)) == 0) { err(2, "malloc(%lu)", (unsigned long)needed); } if (sysctl(mib, 6, buf, &amp;needed, NULL, 0) &lt; 0) { err(1, "sysctl: net.route.0.0.dump"); } lim = buf + needed; for (next = buf; next &lt; lim; next += rtm-&gt;rtm_msglen) { rtm = (struct rt_msghdr2 *)next; route = [self getRoute:rtm]; if(route != nil) { [routeArray addObject:route]; } } free(buf); printf("Total routes: %u\n", [routeArray count]); return routeArray; } + (CustomRoute*) getRoute:(struct rt_msghdr2 *)rtm { //sockaddrs are after the message header struct sockaddr* dst_sa = (struct sockaddr *)(rtm + 1); CustomRoute* route = nil; if(rtm-&gt;rtm_addrs &amp; RTA_DST) { switch(dst_sa-&gt;sa_family) { case AF_INET: if(dst_sa-&gt;sa_family == AF_INET &amp;&amp; !((rtm-&gt;rtm_flags &amp; RTF_WASCLONED) &amp;&amp; (rtm-&gt;rtm_parentflags &amp; RTF_PRCLONING))) { route = [[CustomRoute alloc] initWithRtm:rtm]; } break; } } return route; } -(void) setAddr:(struct sockaddr*)sa index:(int)rtax_index { if(rtax_index &gt;= 0 &amp;&amp; rtax_index &lt; RTAX_MAX) { memcpy(&amp;(m_addrs[rtax_index]), sa, sizeof(struct sockaddr)); } } -(NSString*) getDestination { return [self getAddrStringByIndex:RTAX_DST]; } -(NSString*) getNetmask { return [self getAddrStringByIndex:RTAX_NETMASK]; } -(NSString*) getGateway { return [self getAddrStringByIndex:RTAX_GATEWAY]; } -(NSString*) getDetails { NSMutableString* result = [[NSMutableString alloc] init]; [result appendFormat: [NSString stringWithFormat: @"message type: 0x%06x\n", m_rtm.rtm_type]]; [result appendFormat: [NSString stringWithFormat: @"flags: 0x%06x\n", m_rtm.rtm_flags]]; [result appendFormat: [NSString stringWithFormat: @"addrs: 0x%06x\n", m_rtm.rtm_addrs]]; return result; } -initWithRtm: (struct rt_msghdr2*) rtm { int i; struct sockaddr* sa = (struct sockaddr*)(rtm + 1); //copy over the route message memcpy(&amp;(m_rtm), rtm, sizeof(struct rt_msghdr2)); for(i = 0; i &lt; RTAX_MAX; i++) { [self setAddr:&amp;(sa[i]) index:i]; } return self; } - init { memset(m_addrs, 0, sizeof(m_addrs)); return self; } @end @implementation CustomRoute (Private) -(NSString*) getAddrStringByIndex: (int)rtax_index { NSString * routeString = nil; struct sockaddr* sa = &amp;(m_addrs[rtax_index]); int flagVal = 1 &lt;&lt; rtax_index; if(!(m_rtm.rtm_addrs &amp; flagVal)) { return @"none"; } if(rtax_index &gt;= 0 &amp;&amp; rtax_index &lt; RTAX_MAX) { switch(sa-&gt;sa_family) { case AF_INET: { struct sockaddr_in* si = (struct sockaddr_in *)sa; if(si-&gt;sin_addr.s_addr == INADDR_ANY) routeString = @"default"; else routeString = [NSString stringWithCString:(char *)inet_ntoa(si-&gt;sin_addr) encoding:NSASCIIStringEncoding]; } break; case AF_LINK: { struct sockaddr_dl* sdl = (struct sockaddr_dl*)sa; if(sdl-&gt;sdl_nlen + sdl-&gt;sdl_alen + sdl-&gt;sdl_slen == 0) { routeString = [NSString stringWithFormat: @"link #%d", sdl-&gt;sdl_index]; } else routeString = [NSString stringWithCString:link_ntoa(sdl) encoding:NSASCIIStringEncoding]; } break; default: { char a[3 * sa-&gt;sa_len]; char *cp; char *sep = ""; int i; if(sa-&gt;sa_len == 0) { routeString = @"empty"; } else { a[0] = (char)NULL; for(i = 0, cp = a; i &lt; sa-&gt;sa_len; i++) { cp += sprintf(cp, "%s%02x", sep, (unsigned char)sa-&gt;sa_data[i]); sep = ":"; } routeString = [NSString stringWithCString:a encoding:NSASCIIStringEncoding]; } } } } return routeString; } @end </code></pre> <p>CustomRoute.h:</p> <pre><code>#import &lt;Cocoa/Cocoa.h&gt; #import &lt;net/route.h&gt; #import &lt;sys/socket.h&gt; #import &lt;netinet/in.h&gt; #import &lt;net/if_dl.h&gt; #import &lt;sys/sysctl.h&gt; @interface CustomRoute : NSObject { struct sockaddr m_addrs[RTAX_MAX]; struct rt_msghdr2 m_rtm; int m_len; /* length of the sockaddr array */ } + (NSMutableArray*) getRoutes; + (CustomRoute*) getRoute:(struct rt_msghdr2 *)rtm; - (void) setAddr:(struct sockaddr*)sa index:(int)rtax_index; - (NSString*) getDestination; - (NSString*) getNetmask; - (NSString*) getGateway; - initWithRtm: (struct rt_msghdr2*) rtm; @end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload