Last active
October 24, 2024 16:28
-
-
Save etodd/d8184b91c02306b889c13eb03f81fb6d to your computer and use it in GitHub Desktop.
dump route table on macos
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// stolen from https://stackoverflow.com/a/11265543 | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <err.h> | |
#include <sys/param.h> | |
#include <sys/sysctl.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <net/route.h> | |
/* Darwin doesn't define this for some very odd reason */ | |
#ifndef SA_SIZE | |
# define SA_SIZE(sa) \ | |
( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \ | |
sizeof(long) : \ | |
1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) ) | |
#endif | |
static void | |
ntreestuff(void) | |
{ | |
size_t needed; | |
int mib[6]; | |
char *buf, *next, *lim; | |
struct rt_msghdr *rtm; | |
struct sockaddr *sa; | |
struct sockaddr_in *sockin; | |
char line[MAXHOSTNAMELEN]; | |
mib[0] = CTL_NET; | |
mib[1] = PF_ROUTE; | |
mib[2] = 0; | |
mib[3] = 0; | |
mib[4] = NET_RT_DUMP; | |
mib[5] = 0; | |
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { | |
err(1, "sysctl: net.route.0.0.dump estimate"); | |
} | |
if ((buf = (char *)malloc(needed)) == NULL) { | |
errx(2, "malloc(%lu)", (unsigned long)needed); | |
} | |
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { | |
err(1, "sysctl: net.route.0.0.dump"); | |
} | |
lim = buf + needed; | |
for (next = buf; next < lim; next += rtm->rtm_msglen) { | |
rtm = (struct rt_msghdr *)next; | |
sa = (struct sockaddr *)(rtm + 1); | |
sa = (struct sockaddr *)(SA_SIZE(sa) + (char *)sa); | |
sockin = (struct sockaddr_in *)sa; | |
inet_ntop(AF_INET, &sockin->sin_addr.s_addr, line, sizeof(line) - 1); | |
printf("defaultrouter=%s\n", line); | |
} | |
free(buf); | |
} | |
int | |
main(int argc __unused, char *argv[] __unused) | |
{ | |
ntreestuff(); | |
return (0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// stolen from https://stackoverflow.com/a/8095530 | |
#include <stdio.h> | |
#include <netinet/in.h> | |
#include <stdlib.h> | |
#include <sys/sysctl.h> | |
#include "getgateway.h" | |
#include "route.h" | |
#include <net/if.h> | |
#include <string.h> | |
#define CTL_NET 4 /* network, see socket.h */ | |
#if defined(BSD) || defined(__APPLE__) | |
#define ROUNDUP(a) \ | |
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) | |
int getdefaultgateway(in_addr_t * addr) | |
{ | |
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, | |
NET_RT_FLAGS, RTF_GATEWAY}; | |
size_t l; | |
char * buf, * p; | |
struct rt_msghdr * rt; | |
struct sockaddr * sa; | |
struct sockaddr * sa_tab[RTAX_MAX]; | |
int i; | |
int r = -1; | |
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) { | |
return -1; | |
} | |
if(l>0) { | |
buf = malloc(l); | |
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) { | |
return -1; | |
} | |
for(p=buf; p<buf+l; p+=rt->rtm_msglen) { | |
rt = (struct rt_msghdr *)p; | |
sa = (struct sockaddr *)(rt + 1); | |
for(i=0; i<RTAX_MAX; i++) { | |
if(rt->rtm_addrs & (1 << i)) { | |
sa_tab[i] = sa; | |
sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); | |
} else { | |
sa_tab[i] = NULL; | |
} | |
} | |
if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) | |
&& sa_tab[RTAX_DST]->sa_family == AF_INET | |
&& sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) { | |
if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) { | |
char ifName[128]; | |
if_indextoname(rt->rtm_index,ifName); | |
if(strcmp("en0",ifName)==0){ | |
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr; | |
r = 0; | |
} | |
} | |
} | |
} | |
free(buf); | |
} | |
return r; | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/param.h> | |
#include <sys/sysctl.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <net/route.h> | |
/* Darwin doesn't define this for some very odd reason */ | |
#ifndef SA_SIZE | |
# define SA_SIZE(sa) \ | |
( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \ | |
sizeof(long) : \ | |
1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) ) | |
#endif | |
static int ntreestuff(void) | |
{ | |
int mib[6]; | |
mib[0] = CTL_NET; | |
mib[1] = PF_ROUTE; | |
mib[2] = 0; | |
mib[3] = 0; | |
mib[4] = NET_RT_DUMP; | |
mib[5] = 0; | |
size_t needed; | |
if ( sysctl( mib, 6, NULL, &needed, NULL, 0 ) < 0 ) | |
{ | |
return -1; | |
} | |
char * buffer; | |
if ( ( buffer = (char *)( malloc( needed ) ) ) == NULL ) | |
{ | |
return -1; | |
} | |
if ( sysctl( mib, 6, buffer, &needed, NULL, 0 ) < 0 ) | |
{ | |
return -1; | |
} | |
struct rt_msghdr * rtm; | |
int count = 0; | |
for ( char * i = buffer; i < buffer + needed; i += rtm->rtm_msglen ) | |
{ | |
rtm = (struct rt_msghdr *)( i ); | |
if ( rtm->rtm_type != RTM_GET ) | |
continue; | |
if ( !( rtm->rtm_flags & RTF_UP ) ) | |
continue; | |
if ( !( rtm->rtm_flags & RTF_GATEWAY ) ) | |
continue; | |
if ( !( rtm->rtm_addrs & ( 1 << RTAX_DST ) ) ) | |
continue; | |
if ( !( rtm->rtm_addrs & ( 1 << RTAX_NETMASK ) ) ) | |
continue; | |
printf( "flags: %x\n", rtm->rtm_flags ); | |
struct sockaddr * sa = (struct sockaddr *)( (char *)( rtm ) + sizeof( struct rt_msghdr ) ); | |
struct sockaddr_in * sockin; | |
char line[MAXHOSTNAMELEN]; | |
if ( rtm->rtm_addrs & ( 1 << RTAX_DST ) ) | |
{ | |
sockin = (struct sockaddr_in *)( sa + RTAX_DST ); | |
inet_ntop( AF_INET, &sockin->sin_addr.s_addr, line, sizeof( line ) - 1 ); | |
printf( "dest: %s\n", line ); | |
} | |
if ( rtm->rtm_addrs & ( 1 << RTAX_NETMASK ) ) | |
{ | |
sockin = (struct sockaddr_in *)( sa + RTAX_NETMASK ); | |
inet_ntop( AF_INET, &sockin->sin_addr.s_addr, line, sizeof( line ) - 1 ); | |
printf( "netmask: %s\n", line ); | |
} | |
if ( rtm->rtm_addrs & ( 1 << RTAX_GATEWAY ) ) | |
{ | |
sockin = (struct sockaddr_in *)( sa + RTAX_GATEWAY ); | |
inet_ntop( AF_INET, &sockin->sin_addr.s_addr, line, sizeof( line ) - 1 ); | |
printf( "gateway: %s\n", line ); | |
} | |
printf( "iface: %hu\n", rtm->rtm_index ); | |
count++; | |
} | |
printf( "count: %d\n", count ); | |
free( buffer ); | |
return 0; | |
} | |
int main( int argc, char ** argv ) | |
{ | |
(void) argc; | |
(void) argv; | |
ntreestuff(); | |
return 0; | |
} |
@Wangzihaooooo 0.0.0.0
is the default value to my understanding. Mac has many network devices these days and not all of them will have a gateway configured. I think it can be assumed that 0.0.0.0
is not a valid gateway address, and if that value is encountered in the sockaddr struct, then it is essentially unset.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are many such outputs on Mac -> dest:0.0.0.0 and gateway:0.0.0.0
But using "netstat -nr", there is no 0.0.0.0 in the result
How to fix it, pls help me