Loading src/output.c +9 −9 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ #include <io.h> #include <fcntl.h> #define access _access #elif defined(__linux__) #else #include <unistd.h> #endif Loading src/rawsock-getif.c +129 −2 Original line number Diff line number Diff line Loading @@ -9,11 +9,138 @@ #include "ranges.h" /*for parsing IPv4 addresses */ #if defined(__APPLE__) int rawsock_get_default_interface(char *ifname, size_t sizeof_ifname) #if defined(__APPLE__) || defined(__FreeBSD__) #include <unistd.h> #include <sys/socket.h> #include <net/route.h> #include <netinet/in.h> #include <net/if_dl.h> #include <ctype.h> #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int)) static struct sockaddr * get_rt_address(struct rt_msghdr *rtm, int desired) { int i; int bitmask = rtm->rtm_addrs; struct sockaddr *sa = (struct sockaddr *)(rtm + 1); for (i = 0; i < RTAX_MAX; i++) { if (bitmask & (1 << i)) { if ((1<<i) == desired) return sa; sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa); } else ; } return NULL; } int rawsock_get_default_interface(char *ifname, size_t sizeof_ifname) { int fd; int seq = time(0); int err; struct rt_msghdr *rtm; size_t sizeof_buffer; /* * Requests/responses from the kernel are done with an "rt_msghdr" * structure followed by an array of "sockaddr" structures. */ sizeof_buffer = sizeof(*rtm) + sizeof(struct sockaddr_in)*16; rtm = (struct rt_msghdr *)malloc(sizeof_buffer); /* * Create a socket for querying the kernel */ fd = socket(PF_ROUTE, SOCK_RAW, 0); if (fd <= 0) { perror("socket(PF_ROUTE)"); free(rtm); return errno; } /* * Format and send request to kernel */ memset(rtm, 0, sizeof_buffer); rtm->rtm_msglen = sizeof_buffer; rtm->rtm_type = RTM_GET; rtm->rtm_flags = RTF_UP | RTF_GATEWAY; rtm->rtm_version = RTM_VERSION; rtm->rtm_seq = seq; rtm->rtm_addrs = RTA_DST | RTA_NETMASK | RTA_GATEWAY | RTA_IFP; err = write(fd, (char *)rtm, sizeof_buffer); if (err < 0 || err != sizeof_buffer) { perror("write(RTM_GET)"); printf("----%u %u\n", err, sizeof_buffer); close(fd); free(rtm); return -1; } /* * Read responses until we find one that belongs to us */ for (;;) { err = read(fd, (char *)rtm, sizeof_buffer); if (err <= 0) break; if (rtm->rtm_seq != seq) { printf("seq: %u %u\n", rtm->rtm_seq, seq); continue; } if (rtm->rtm_pid != getpid()) { printf("pid: %u %u\n", rtm->rtm_pid, getpid()); continue; } break; } close(fd); //hexdump(rtm+1, err-sizeof(*rtm)); //dump_rt_addresses(rtm); /* * Parse our data */ { //struct sockaddr_in *sin; struct sockaddr_dl *sdl; sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP); if (sdl) { size_t len = sdl->sdl_nlen; if (len > sizeof_ifname-1) len = sizeof_ifname-1; memcpy(ifname, sdl->sdl_data, len); ifname[len] = 0; return 0; } /*sin = (struct sockaddr_in *)get_rt_address(rtm, RTA_GATEWAY); if (sin) { *ipv4 = ntohl(sin->sin_addr.s_addr); free(rtm); return 0; }*/ } free(rtm); return -1; } #elif defined(__linux__) #include <netinet/in.h> #include <net/if.h> Loading src/rawsock-getip.c +72 −14 Original line number Diff line number Diff line Loading @@ -2,19 +2,22 @@ retrieve IPv4 address of the named network interface/adapter like "eth0" This works on both Linux and Windows. This works on: - Windows - Linux - Apple - FreeBSD I think it'll work the same on any BSD system. */ #include "rawsock.h" #include "string_s.h" #include "ranges.h" /*for parsing IPv4 addresses */ #if defined(__APPLE__) unsigned rawsock_get_adapter_ip(const char *ifname) { return 0; } #elif defined(__linux__) /***************************************************************************** *****************************************************************************/ #if defined(__linux__) #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> Loading Loading @@ -49,17 +52,16 @@ rawsock_get_adapter_ip(const char *ifname) sin = (struct sockaddr_in *)sa; return ntohl(sin->sin_addr.s_addr); } #endif #if defined(WIN32) /***************************************************************************** *****************************************************************************/ #elif defined(WIN32) #include <winsock2.h> #include <iphlpapi.h> #ifdef _MSC_VER #pragma comment(lib, "IPHLPAPI.lib") #endif unsigned rawsock_get_adapter_ip(const char *ifname) { Loading @@ -75,7 +77,7 @@ rawsock_get_adapter_ip(const char *ifname) */ pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof (IP_ADAPTER_INFO)); if (pAdapterInfo == NULL) { fprintf(stderr, "Error allocating memory needed to call GetAdaptersinfo\n"); fprintf(stderr, "error:malloc(): for GetAdaptersinfo\n"); return 0; } Loading @@ -89,7 +91,7 @@ again: free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); if (pAdapterInfo == NULL) { fprintf(stderr, "Error allocating memory needed to call GetAdaptersinfo\n"); fprintf(stderr, "error:malloc(): for GetAdaptersinfo\n"); return 0; } goto again; Loading Loading @@ -129,5 +131,61 @@ again: return 0; } /***************************************************************************** *****************************************************************************/ #elif defined(__APPLE__) || defined(__FreeBSD__) || 1 #include <sys/types.h> #include <sys/socket.h> #include <ifaddrs.h> #include <stdio.h> #include <arpa/inet.h> #ifdef AF_LINK # include <net/if_dl.h> #endif #ifdef AF_PACKET # include <netpacket/packet.h> #endif unsigned rawsock_get_adapter_ip(const char *ifname) { int err; struct ifaddrs *ifap; struct ifaddrs *p; unsigned ip; /* Get the list of all network adapters */ err = getifaddrs(&ifap); if (err != 0) { perror("getifaddrs"); return 0; } /* Look through the list until we get our adapter */ for (p = ifap; p; p = p->ifa_next) { if (strcmp(ifname, p->ifa_name) == 0 && p->ifa_addr && p->ifa_addr->sa_family == AF_INET) break; } if (p == NULL) goto error; /* not found */ /* Return the address */ { struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; ip = ntohl(sin->sin_addr.s_addr); } freeifaddrs(ifap); return ip; error: freeifaddrs(ifap); return 0; } #endif src/rawsock-getmac.c +80 −10 Original line number Diff line number Diff line /* get MAC address of named network interface/adapter like "eth0" This works on both Windows and linux This works on: - Windows - Linux - Apple - FreeBSD I think it'll work the same on any BSD system. */ #include "rawsock.h" #include "string_s.h" #if defined(__APPLE__) int rawsock_get_adapter_mac(const char *ifname, unsigned char *mac) { return -1; } #elif defined(__linux__) /***************************************************************************** *****************************************************************************/ #if defined(__linux__) #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> Loading Loading @@ -47,9 +49,10 @@ end: close(fd); return 0; } #endif #if defined(WIN32) /***************************************************************************** *****************************************************************************/ #elif defined(WIN32) #include <winsock2.h> #include <iphlpapi.h> #ifdef _MSC_VER Loading Loading @@ -118,5 +121,72 @@ again: return 0; } /***************************************************************************** *****************************************************************************/ #elif defined(__APPLE__) || defined(__FreeBSD__) || 1 #include <sys/types.h> #include <sys/socket.h> #include <ifaddrs.h> #include <stdio.h> #include <arpa/inet.h> #ifdef AF_LINK # include <net/if_dl.h> #endif #ifdef AF_PACKET # include <netpacket/packet.h> #endif int rawsock_get_adapter_mac(const char *ifname, unsigned char *mac) { int err; struct ifaddrs *ifap; struct ifaddrs *p; /* Get the list of all network adapters */ err = getifaddrs(&ifap); if (err != 0) { perror("getifaddrs"); return 1; } /* Look through the list until we get our adapter */ for (p = ifap; p; p = p->ifa_next) { if (strcmp(ifname, p->ifa_name) == 0 && p->ifa_addr && p->ifa_addr->sa_family == AF_LINK) break; } if (p == NULL) goto error; /* not found */ /* Return the address */ { size_t len = 6; struct sockaddr_dl *link; link = (struct sockaddr_dl *)p->ifa_addr; if (len > link->sdl_alen) { memset(mac, 0, 6); len = link->sdl_alen; } memcpy( mac, link->sdl_data + link->sdl_nlen, len); } freeifaddrs(ifap); return 0; error: freeifaddrs(ifap); return -1; } #endif src/rawsock-getroute.c +110 −21 Original line number Diff line number Diff line Loading @@ -10,11 +10,87 @@ #include "ranges.h" /*for parsing IPv4 addresses */ #if defined(__APPLE__) #if defined(__APPLE__) || defined(__FreeBSD__) #include <unistd.h> #include <sys/socket.h> #include <net/route.h> #include <netinet/in.h> #include <net/if_dl.h> #include <ctype.h> #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int)) struct sockaddr * get_rt_address(struct rt_msghdr *rtm, int desired) { int i; int bitmask = rtm->rtm_addrs; struct sockaddr *sa = (struct sockaddr *)(rtm + 1); for (i = 0; i < RTAX_MAX; i++) { if (bitmask & (1 << i)) { if ((1<<i) == desired) return sa; sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa); } else ; } return NULL; } static void hexdump(const void *v, size_t len) { const unsigned char *p = (const unsigned char *)v; size_t i; for (i=0; i<len; i += 16) { size_t j; for (j=i; j<i+16 && j<len; j++) printf("%02x ", p[j]); for (;j<i+16; j++) printf(" "); printf(" "); for (j=i; j<i+16 && j<len; j++) if (isprint(p[j]) && !isspace(p[j])) printf("%c", p[j]); else printf("."); printf("\n"); } } #if 0 #define RTA_DST 0x1 /* destination sockaddr present */ #define RTA_GATEWAY 0x2 /* gateway sockaddr present */ #define RTA_NETMASK 0x4 /* netmask sockaddr present */ #define RTA_GENMASK 0x8 /* cloning mask sockaddr present */ #define RTA_IFP 0x10 /* interface name sockaddr present */ #define RTA_IFA 0x20 /* interface addr sockaddr present */ #define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */ #define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */ #endif void dump_rt_addresses(struct rt_msghdr *rtm) { int i; int bitmask = rtm->rtm_addrs; struct sockaddr *sa = (struct sockaddr *)(rtm + 1); for (i = 0; i < RTAX_MAX; i++) { if (bitmask & (1 << i)) { printf("b=%u fam=%u len=%u\n", (1<<i), sa->sa_family, sa->sa_len); hexdump(sa, sa->sa_len + sizeof(sa->sa_family)); sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa); } else ; } } int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) { Loading @@ -29,7 +105,7 @@ int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) * Requests/responses from the kernel are done with an "rt_msghdr" * structure followed by an array of "sockaddr" structures. */ sizeof_buffer = sizeof(*rtm) + sizeof(struct sockaddr_in) * sizeof(int)*8; sizeof_buffer = sizeof(*rtm) + sizeof(struct sockaddr_in)*16; rtm = (struct rt_msghdr *)malloc(sizeof_buffer); Loading @@ -53,11 +129,12 @@ int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) rtm->rtm_flags = RTF_UP | RTF_GATEWAY; rtm->rtm_version = RTM_VERSION; rtm->rtm_seq = seq; rtm->rtm_addrs = RTA_DST | RTA_NETMASK; rtm->rtm_addrs = RTA_DST | RTA_NETMASK | RTA_GATEWAY | RTA_IFP; err = write(fd, (char *)rtm, sizeof_buffer); if (err) { if (err < 0 || err != sizeof_buffer) { perror("write(RTM_GET)"); printf("----%u %u\n", err, sizeof_buffer); close(fd); free(rtm); return -1; Loading @@ -70,34 +147,46 @@ int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) err = read(fd, (char *)rtm, sizeof_buffer); if (err <= 0) break; if (rtm->rtm_seq != seq) if (rtm->rtm_seq != seq) { printf("seq: %u %u\n", rtm->rtm_seq, seq); continue; if (rtm->rtm_pid != getpid()) } if (rtm->rtm_pid != getpid()) { printf("pid: %u %u\n", rtm->rtm_pid, getpid()); continue; } break; } close(fd); //hexdump(rtm+1, err-sizeof(*rtm)); //dump_rt_addresses(rtm); /* * Parse our data */ { int i; struct sockaddr *sa; /* Addresses start right in buffer after RTM structure */ sa = (struct sockaddr *)(rtm + 1); struct sockaddr_in *sin; struct sockaddr_dl *sdl; sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP); if (sdl) { //hexdump(sdl, sdl->sdl_len); //printf("%.*s\n", sdl->sdl_nlen, sdl->sdl_data); if (memcmp(ifname, sdl->sdl_data, sdl->sdl_nlen) != 0) { fprintf(stderr, "ERROR: ROUTE DOESN'T MATCH INTERFACE\n"); fprintf(stderr, "YOU'LL HAVE TO SET --router-mac MANUALLY\n"); exit(1); } } for (i=1; i; i *= 2) { if (i == RTA_GATEWAY) { /* FOUND IT!! copy the address and return */ struct sockaddr_in *sin = (struct sockaddr_in *)sa; sin = (struct sockaddr_in *)get_rt_address(rtm, RTA_GATEWAY); if (sin) { *ipv4 = ntohl(sin->sin_addr.s_addr); free(rtm); return 0; } sa++; } } free(rtm); Loading Loading
src/output.c +9 −9 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ #include <io.h> #include <fcntl.h> #define access _access #elif defined(__linux__) #else #include <unistd.h> #endif Loading
src/rawsock-getif.c +129 −2 Original line number Diff line number Diff line Loading @@ -9,11 +9,138 @@ #include "ranges.h" /*for parsing IPv4 addresses */ #if defined(__APPLE__) int rawsock_get_default_interface(char *ifname, size_t sizeof_ifname) #if defined(__APPLE__) || defined(__FreeBSD__) #include <unistd.h> #include <sys/socket.h> #include <net/route.h> #include <netinet/in.h> #include <net/if_dl.h> #include <ctype.h> #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int)) static struct sockaddr * get_rt_address(struct rt_msghdr *rtm, int desired) { int i; int bitmask = rtm->rtm_addrs; struct sockaddr *sa = (struct sockaddr *)(rtm + 1); for (i = 0; i < RTAX_MAX; i++) { if (bitmask & (1 << i)) { if ((1<<i) == desired) return sa; sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa); } else ; } return NULL; } int rawsock_get_default_interface(char *ifname, size_t sizeof_ifname) { int fd; int seq = time(0); int err; struct rt_msghdr *rtm; size_t sizeof_buffer; /* * Requests/responses from the kernel are done with an "rt_msghdr" * structure followed by an array of "sockaddr" structures. */ sizeof_buffer = sizeof(*rtm) + sizeof(struct sockaddr_in)*16; rtm = (struct rt_msghdr *)malloc(sizeof_buffer); /* * Create a socket for querying the kernel */ fd = socket(PF_ROUTE, SOCK_RAW, 0); if (fd <= 0) { perror("socket(PF_ROUTE)"); free(rtm); return errno; } /* * Format and send request to kernel */ memset(rtm, 0, sizeof_buffer); rtm->rtm_msglen = sizeof_buffer; rtm->rtm_type = RTM_GET; rtm->rtm_flags = RTF_UP | RTF_GATEWAY; rtm->rtm_version = RTM_VERSION; rtm->rtm_seq = seq; rtm->rtm_addrs = RTA_DST | RTA_NETMASK | RTA_GATEWAY | RTA_IFP; err = write(fd, (char *)rtm, sizeof_buffer); if (err < 0 || err != sizeof_buffer) { perror("write(RTM_GET)"); printf("----%u %u\n", err, sizeof_buffer); close(fd); free(rtm); return -1; } /* * Read responses until we find one that belongs to us */ for (;;) { err = read(fd, (char *)rtm, sizeof_buffer); if (err <= 0) break; if (rtm->rtm_seq != seq) { printf("seq: %u %u\n", rtm->rtm_seq, seq); continue; } if (rtm->rtm_pid != getpid()) { printf("pid: %u %u\n", rtm->rtm_pid, getpid()); continue; } break; } close(fd); //hexdump(rtm+1, err-sizeof(*rtm)); //dump_rt_addresses(rtm); /* * Parse our data */ { //struct sockaddr_in *sin; struct sockaddr_dl *sdl; sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP); if (sdl) { size_t len = sdl->sdl_nlen; if (len > sizeof_ifname-1) len = sizeof_ifname-1; memcpy(ifname, sdl->sdl_data, len); ifname[len] = 0; return 0; } /*sin = (struct sockaddr_in *)get_rt_address(rtm, RTA_GATEWAY); if (sin) { *ipv4 = ntohl(sin->sin_addr.s_addr); free(rtm); return 0; }*/ } free(rtm); return -1; } #elif defined(__linux__) #include <netinet/in.h> #include <net/if.h> Loading
src/rawsock-getip.c +72 −14 Original line number Diff line number Diff line Loading @@ -2,19 +2,22 @@ retrieve IPv4 address of the named network interface/adapter like "eth0" This works on both Linux and Windows. This works on: - Windows - Linux - Apple - FreeBSD I think it'll work the same on any BSD system. */ #include "rawsock.h" #include "string_s.h" #include "ranges.h" /*for parsing IPv4 addresses */ #if defined(__APPLE__) unsigned rawsock_get_adapter_ip(const char *ifname) { return 0; } #elif defined(__linux__) /***************************************************************************** *****************************************************************************/ #if defined(__linux__) #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> Loading Loading @@ -49,17 +52,16 @@ rawsock_get_adapter_ip(const char *ifname) sin = (struct sockaddr_in *)sa; return ntohl(sin->sin_addr.s_addr); } #endif #if defined(WIN32) /***************************************************************************** *****************************************************************************/ #elif defined(WIN32) #include <winsock2.h> #include <iphlpapi.h> #ifdef _MSC_VER #pragma comment(lib, "IPHLPAPI.lib") #endif unsigned rawsock_get_adapter_ip(const char *ifname) { Loading @@ -75,7 +77,7 @@ rawsock_get_adapter_ip(const char *ifname) */ pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof (IP_ADAPTER_INFO)); if (pAdapterInfo == NULL) { fprintf(stderr, "Error allocating memory needed to call GetAdaptersinfo\n"); fprintf(stderr, "error:malloc(): for GetAdaptersinfo\n"); return 0; } Loading @@ -89,7 +91,7 @@ again: free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); if (pAdapterInfo == NULL) { fprintf(stderr, "Error allocating memory needed to call GetAdaptersinfo\n"); fprintf(stderr, "error:malloc(): for GetAdaptersinfo\n"); return 0; } goto again; Loading Loading @@ -129,5 +131,61 @@ again: return 0; } /***************************************************************************** *****************************************************************************/ #elif defined(__APPLE__) || defined(__FreeBSD__) || 1 #include <sys/types.h> #include <sys/socket.h> #include <ifaddrs.h> #include <stdio.h> #include <arpa/inet.h> #ifdef AF_LINK # include <net/if_dl.h> #endif #ifdef AF_PACKET # include <netpacket/packet.h> #endif unsigned rawsock_get_adapter_ip(const char *ifname) { int err; struct ifaddrs *ifap; struct ifaddrs *p; unsigned ip; /* Get the list of all network adapters */ err = getifaddrs(&ifap); if (err != 0) { perror("getifaddrs"); return 0; } /* Look through the list until we get our adapter */ for (p = ifap; p; p = p->ifa_next) { if (strcmp(ifname, p->ifa_name) == 0 && p->ifa_addr && p->ifa_addr->sa_family == AF_INET) break; } if (p == NULL) goto error; /* not found */ /* Return the address */ { struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; ip = ntohl(sin->sin_addr.s_addr); } freeifaddrs(ifap); return ip; error: freeifaddrs(ifap); return 0; } #endif
src/rawsock-getmac.c +80 −10 Original line number Diff line number Diff line /* get MAC address of named network interface/adapter like "eth0" This works on both Windows and linux This works on: - Windows - Linux - Apple - FreeBSD I think it'll work the same on any BSD system. */ #include "rawsock.h" #include "string_s.h" #if defined(__APPLE__) int rawsock_get_adapter_mac(const char *ifname, unsigned char *mac) { return -1; } #elif defined(__linux__) /***************************************************************************** *****************************************************************************/ #if defined(__linux__) #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> Loading Loading @@ -47,9 +49,10 @@ end: close(fd); return 0; } #endif #if defined(WIN32) /***************************************************************************** *****************************************************************************/ #elif defined(WIN32) #include <winsock2.h> #include <iphlpapi.h> #ifdef _MSC_VER Loading Loading @@ -118,5 +121,72 @@ again: return 0; } /***************************************************************************** *****************************************************************************/ #elif defined(__APPLE__) || defined(__FreeBSD__) || 1 #include <sys/types.h> #include <sys/socket.h> #include <ifaddrs.h> #include <stdio.h> #include <arpa/inet.h> #ifdef AF_LINK # include <net/if_dl.h> #endif #ifdef AF_PACKET # include <netpacket/packet.h> #endif int rawsock_get_adapter_mac(const char *ifname, unsigned char *mac) { int err; struct ifaddrs *ifap; struct ifaddrs *p; /* Get the list of all network adapters */ err = getifaddrs(&ifap); if (err != 0) { perror("getifaddrs"); return 1; } /* Look through the list until we get our adapter */ for (p = ifap; p; p = p->ifa_next) { if (strcmp(ifname, p->ifa_name) == 0 && p->ifa_addr && p->ifa_addr->sa_family == AF_LINK) break; } if (p == NULL) goto error; /* not found */ /* Return the address */ { size_t len = 6; struct sockaddr_dl *link; link = (struct sockaddr_dl *)p->ifa_addr; if (len > link->sdl_alen) { memset(mac, 0, 6); len = link->sdl_alen; } memcpy( mac, link->sdl_data + link->sdl_nlen, len); } freeifaddrs(ifap); return 0; error: freeifaddrs(ifap); return -1; } #endif
src/rawsock-getroute.c +110 −21 Original line number Diff line number Diff line Loading @@ -10,11 +10,87 @@ #include "ranges.h" /*for parsing IPv4 addresses */ #if defined(__APPLE__) #if defined(__APPLE__) || defined(__FreeBSD__) #include <unistd.h> #include <sys/socket.h> #include <net/route.h> #include <netinet/in.h> #include <net/if_dl.h> #include <ctype.h> #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(int) - 1))) : sizeof(int)) struct sockaddr * get_rt_address(struct rt_msghdr *rtm, int desired) { int i; int bitmask = rtm->rtm_addrs; struct sockaddr *sa = (struct sockaddr *)(rtm + 1); for (i = 0; i < RTAX_MAX; i++) { if (bitmask & (1 << i)) { if ((1<<i) == desired) return sa; sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa); } else ; } return NULL; } static void hexdump(const void *v, size_t len) { const unsigned char *p = (const unsigned char *)v; size_t i; for (i=0; i<len; i += 16) { size_t j; for (j=i; j<i+16 && j<len; j++) printf("%02x ", p[j]); for (;j<i+16; j++) printf(" "); printf(" "); for (j=i; j<i+16 && j<len; j++) if (isprint(p[j]) && !isspace(p[j])) printf("%c", p[j]); else printf("."); printf("\n"); } } #if 0 #define RTA_DST 0x1 /* destination sockaddr present */ #define RTA_GATEWAY 0x2 /* gateway sockaddr present */ #define RTA_NETMASK 0x4 /* netmask sockaddr present */ #define RTA_GENMASK 0x8 /* cloning mask sockaddr present */ #define RTA_IFP 0x10 /* interface name sockaddr present */ #define RTA_IFA 0x20 /* interface addr sockaddr present */ #define RTA_AUTHOR 0x40 /* sockaddr for author of redirect */ #define RTA_BRD 0x80 /* for NEWADDR, broadcast or p-p dest addr */ #endif void dump_rt_addresses(struct rt_msghdr *rtm) { int i; int bitmask = rtm->rtm_addrs; struct sockaddr *sa = (struct sockaddr *)(rtm + 1); for (i = 0; i < RTAX_MAX; i++) { if (bitmask & (1 << i)) { printf("b=%u fam=%u len=%u\n", (1<<i), sa->sa_family, sa->sa_len); hexdump(sa, sa->sa_len + sizeof(sa->sa_family)); sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa); } else ; } } int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) { Loading @@ -29,7 +105,7 @@ int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) * Requests/responses from the kernel are done with an "rt_msghdr" * structure followed by an array of "sockaddr" structures. */ sizeof_buffer = sizeof(*rtm) + sizeof(struct sockaddr_in) * sizeof(int)*8; sizeof_buffer = sizeof(*rtm) + sizeof(struct sockaddr_in)*16; rtm = (struct rt_msghdr *)malloc(sizeof_buffer); Loading @@ -53,11 +129,12 @@ int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) rtm->rtm_flags = RTF_UP | RTF_GATEWAY; rtm->rtm_version = RTM_VERSION; rtm->rtm_seq = seq; rtm->rtm_addrs = RTA_DST | RTA_NETMASK; rtm->rtm_addrs = RTA_DST | RTA_NETMASK | RTA_GATEWAY | RTA_IFP; err = write(fd, (char *)rtm, sizeof_buffer); if (err) { if (err < 0 || err != sizeof_buffer) { perror("write(RTM_GET)"); printf("----%u %u\n", err, sizeof_buffer); close(fd); free(rtm); return -1; Loading @@ -70,34 +147,46 @@ int rawsock_get_default_gateway(const char *ifname, unsigned *ipv4) err = read(fd, (char *)rtm, sizeof_buffer); if (err <= 0) break; if (rtm->rtm_seq != seq) if (rtm->rtm_seq != seq) { printf("seq: %u %u\n", rtm->rtm_seq, seq); continue; if (rtm->rtm_pid != getpid()) } if (rtm->rtm_pid != getpid()) { printf("pid: %u %u\n", rtm->rtm_pid, getpid()); continue; } break; } close(fd); //hexdump(rtm+1, err-sizeof(*rtm)); //dump_rt_addresses(rtm); /* * Parse our data */ { int i; struct sockaddr *sa; /* Addresses start right in buffer after RTM structure */ sa = (struct sockaddr *)(rtm + 1); struct sockaddr_in *sin; struct sockaddr_dl *sdl; sdl = (struct sockaddr_dl *)get_rt_address(rtm, RTA_IFP); if (sdl) { //hexdump(sdl, sdl->sdl_len); //printf("%.*s\n", sdl->sdl_nlen, sdl->sdl_data); if (memcmp(ifname, sdl->sdl_data, sdl->sdl_nlen) != 0) { fprintf(stderr, "ERROR: ROUTE DOESN'T MATCH INTERFACE\n"); fprintf(stderr, "YOU'LL HAVE TO SET --router-mac MANUALLY\n"); exit(1); } } for (i=1; i; i *= 2) { if (i == RTA_GATEWAY) { /* FOUND IT!! copy the address and return */ struct sockaddr_in *sin = (struct sockaddr_in *)sa; sin = (struct sockaddr_in *)get_rt_address(rtm, RTA_GATEWAY); if (sin) { *ipv4 = ntohl(sin->sin_addr.s_addr); free(rtm); return 0; } sa++; } } free(rtm); Loading