📄 route.c
字号:
if (r->metric_defined) buf_printf (&buf, " -rtt %d", r->metric);#endif buf_printf (&buf, " %s -netmask %s %s", network, netmask, gateway); msg (D_ROUTE, "%s", BSTR (&buf)); status = system_check (BSTR (&buf), "ERROR: Solaris route add command failed", false);#elif defined(TARGET_FREEBSD) buf_printf (&buf, ROUTE_PATH " add");#if 0 if (r->metric_defined) buf_printf (&buf, " -rtt %d", r->metric);#endif buf_printf (&buf, " -net %s %s %s", network, gateway, netmask); msg (D_ROUTE, "%s", BSTR (&buf)); status = system_check (BSTR (&buf), "ERROR: FreeBSD route add command failed", false);#elif defined(TARGET_DARWIN) buf_printf (&buf, ROUTE_PATH " add");#if 0 if (r->metric_defined) buf_printf (&buf, " -rtt %d", r->metric);#endif buf_printf (&buf, " -net %s %s %s", network, gateway, netmask); msg (D_ROUTE, "%s", BSTR (&buf)); status = system_check (BSTR (&buf), "ERROR: FreeBSD route add command failed", false);#elif defined(TARGET_OPENBSD) buf_printf (&buf, ROUTE_PATH " add");#if 0 if (r->metric_defined) buf_printf (&buf, " -rtt %d", r->metric);#endif buf_printf (&buf, " -net %s %s -netmask %s", network, gateway, netmask); msg (D_ROUTE, "%s", BSTR (&buf)); status = system_check (BSTR (&buf), "ERROR: OpenBSD route add command failed", false);#else msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");#endif r->defined = status; gc_free (&gc);}static voiddelete_route (const struct route *r){ struct gc_arena gc; struct buffer buf; const char *network; const char *netmask; const char *gateway; if (!r->defined) return; gc_init (&gc); buf = alloc_buf_gc (256, &gc); network = print_in_addr_t (r->network, false, &gc); netmask = print_in_addr_t (r->netmask, false, &gc); gateway = print_in_addr_t (r->gateway, false, &gc);#if defined(TARGET_LINUX)#ifdef CONFIG_FEATURE_IPROUTE buf_printf (&buf, IPROUTE_PATH " route del %s/%d", network, count_netmask_bits(netmask));#else buf_printf (&buf, ROUTE_PATH " del -net %s netmask %s", network, netmask);#endif /*CONFIG_FEATURE_IPROUTE*/ msg (D_ROUTE, "%s", BSTR (&buf)); system_check (BSTR (&buf), "ERROR: Linux route delete command failed", false);#elif defined (WIN32) buf_printf (&buf, ROUTE_PATH " DELETE %s", network); netcmd_semaphore_lock (); msg (D_ROUTE, "%s", BSTR (&buf)); system_check (BSTR (&buf), "ERROR: Windows route delete command failed", false); netcmd_semaphore_release ();#elif defined (TARGET_SOLARIS) buf_printf (&buf, ROUTE_PATH " delete %s -netmask %s %s", network, netmask, gateway); msg (D_ROUTE, "%s", BSTR (&buf)); system_check (BSTR (&buf), "ERROR: Solaris route delete command failed", false);#elif defined(TARGET_FREEBSD) buf_printf (&buf, ROUTE_PATH " delete -net %s %s %s", network, gateway, netmask); msg (D_ROUTE, "%s", BSTR (&buf)); system_check (BSTR (&buf), "ERROR: FreeBSD route delete command failed", false);#elif defined(TARGET_DARWIN) buf_printf (&buf, ROUTE_PATH " delete -net %s %s %s", network, gateway, netmask); msg (D_ROUTE, "%s", BSTR (&buf)); system_check (BSTR (&buf), "ERROR: Darwin route delete command failed", false);#elif defined(TARGET_OPENBSD) buf_printf (&buf, ROUTE_PATH " delete -net %s %s -netmask %s", network, gateway, netmask); msg (D_ROUTE, "%s", BSTR (&buf)); system_check (BSTR (&buf), "ERROR: OpenBSD route delete command failed", false);#else msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");#endif gc_free (&gc);}/* * The --redirect-gateway option requires OS-specific code below * to get the current default gateway. */#if defined(WIN32)static boolget_default_gateway (in_addr_t *ret){ struct gc_arena gc = gc_new (); ULONG size = 0; DWORD status; bool ret_bool = false; if ((status = GetIpForwardTable (NULL, &size, TRUE)) == ERROR_INSUFFICIENT_BUFFER) { int i; PMIB_IPFORWARDTABLE routes = (PMIB_IPFORWARDTABLE) gc_malloc (size, false, &gc); ASSERT (routes); if ((status = GetIpForwardTable (routes, &size, TRUE)) != NO_ERROR) goto done; for (i = 0; i < routes->dwNumEntries; ++i) { const MIB_IPFORWARDROW *row = &routes->table[i]; const in_addr_t net = ntohl (row->dwForwardDest); const in_addr_t mask = ntohl (row->dwForwardMask); const in_addr_t gw = ntohl (row->dwForwardNextHop);#if 0 msg (M_INFO, "route[%d] %s %s %s", i, print_in_addr_t ((in_addr_t) net, false, &gc), print_in_addr_t ((in_addr_t) mask, false, &gc), print_in_addr_t ((in_addr_t) gw, false, &gc));#endif if (!net && !mask) { *ret = gw; ret_bool = true; break; } } } done: gc_free (&gc); return ret_bool;}#elif defined(TARGET_LINUX)static boolget_default_gateway (in_addr_t *ret){ struct gc_arena gc = gc_new (); FILE *fp = fopen ("/proc/net/route", "r"); if (fp) { char line[256]; int count = 0; while (fgets (line, sizeof (line), fp) != NULL) { if (count) { unsigned int net_x = 0; unsigned int mask_x = 0; unsigned int gw_x = 0; const int np = sscanf (line, "%*s\t%x\t%x\t%*s\t%*s\t%*s\t%*s\t%x", &net_x, &gw_x, &mask_x); if (np == 3) { const in_addr_t net = ntohl (net_x); const in_addr_t mask = ntohl (mask_x); const in_addr_t gw = ntohl (gw_x);#if 0 msg (M_INFO, "route %s %s %s", print_in_addr_t ((in_addr_t) net, false, &gc), print_in_addr_t ((in_addr_t) mask, false, &gc), print_in_addr_t ((in_addr_t) gw, false, &gc));#endif if (!net && !mask) { fclose (fp); *ret = gw; gc_free (&gc); return true; } } } ++count; } fclose (fp); } gc_free (&gc); return false;}#elif defined(TARGET_FREEBSD)#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>/* all of this is taken from <net/route.h> in FreeBSD */#define RTA_DST 0x1#define RTA_GATEWAY 0x2#define RTA_NETMASK 0x4#define RTM_GET 0x4#define RTM_VERSION 5#define RTF_UP 0x1#define RTF_GATEWAY 0x2/* * These numbers are used by reliable protocols for determining * retransmission behavior and are included in the routing structure. */struct rt_metrics { u_long rmx_locks; /* Kernel must leave these values alone */ u_long rmx_mtu; /* MTU for this path */ u_long rmx_hopcount; /* max hops expected */ u_long rmx_expire; /* lifetime for route, e.g. redirect */ u_long rmx_recvpipe; /* inbound delay-bandwidth product */ u_long rmx_sendpipe; /* outbound delay-bandwidth product */ u_long rmx_ssthresh; /* outbound gateway buffer limit */ u_long rmx_rtt; /* estimated round trip time */ u_long rmx_rttvar; /* estimated rtt variance */ u_long rmx_pksent; /* packets sent using this route */ u_long rmx_filler[4]; /* will be used for T/TCP later */};/* * Structures for routing messages. */struct rt_msghdr { u_short rtm_msglen; /* to skip over non-understood messages */ u_char rtm_version; /* future binary compatibility */ u_char rtm_type; /* message type */ u_short rtm_index; /* index for associated ifp */ int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ int rtm_addrs; /* bitmask identifying sockaddrs in msg */ pid_t rtm_pid; /* identify sender */ int rtm_seq; /* for sender to identify action */ int rtm_errno; /* why failed */ int rtm_use; /* from rtentry */ u_long rtm_inits; /* which metrics we are initializing */ struct rt_metrics rtm_rmx; /* metrics themselves */};struct { struct rt_msghdr m_rtm; char m_space[512];} m_rtmsg;#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))static boolget_default_gateway (in_addr_t *ret){ struct gc_arena gc = gc_new (); int s, seq, l, pid, rtm_addrs, i; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *sa; struct rt_msghdr *rtm_aux;#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\ }#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))#define rtm m_rtmsg.m_rtm pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK; bzero(&so_dst, sizeof(so_dst)); bzero(&so_mask, sizeof(so_mask)); bzero(&rtm, sizeof(struct rt_msghdr)); rtm.rtm_type = RTM_GET; rtm.rtm_flags = RTF_UP | RTF_GATEWAY; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = ++seq; rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; so_dst.sa_len = sizeof(struct sockaddr_in); so_mask.sa_family = AF_INET; so_mask.sa_len = sizeof(struct sockaddr_in); NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; s = socket(PF_ROUTE, SOCK_RAW, 0); if (write(s, (char *)&m_rtmsg, l) < 0) { warn("writing to routing socket"); gc_free (&gc); return false; } do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); rtm_aux = &rtm; cp = ((char *)(rtm_aux + 1)); if (rtm_aux->rtm_addrs) { for (i = 1; i; i <<= 1) if (i & rtm_aux->rtm_addrs) { sa = (struct sockaddr *)cp; if (i == RTA_GATEWAY ) gate = sa; ADVANCE(cp, sa); } } else { gc_free (&gc); return false; } if (gate != NULL ) { *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);#if 1 msg (M_INFO, "gw %s", print_in_addr_t ((in_addr_t) *ret, false, &gc));#endif gc_free (&gc); return true; } else { gc_free (&gc); return false; }}#elif defined(TARGET_DARWIN)#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>/* all of this is taken from <net/route.h> in Darwin */#define RTA_DST 0x1#define RTA_GATEWAY 0x2#define RTA_NETMASK 0x4#define RTM_GET 0x4#define RTM_VERSION 5#define RTF_UP 0x1#define RTF_GATEWAY 0x2/* * These numbers are used by reliable protocols for determining * retransmission behavior and are included in the routing structure. */struct rt_metrics { u_long rmx_locks; /* Kernel must leave these values alone */ u_long rmx_mtu; /* MTU for this path */ u_long rmx_hopcount; /* max hops expected */ u_long rmx_expire; /* lifetime for route, e.g. redirect */ u_long rmx_recvpipe; /* inbound delay-bandwidth product */ u_long rmx_sendpipe; /* outbound delay-bandwidth product */ u_long rmx_ssthresh; /* outbound gateway buffer limit */ u_long rmx_rtt; /* estimated round trip time */ u_long rmx_rttvar; /* estimated rtt variance */ u_long rmx_pksent; /* packets sent using this route */ u_long rmx_filler[4]; /* will be used for T/TCP later */};/* * Structures for routing messages. */struct rt_msghdr { u_short rtm_msglen; /* to skip over non-understood messages */ u_char rtm_version; /* future binary compatibility */ u_char rtm_type; /* message type */ u_short rtm_index; /* index for associated ifp */ int rtm_flags; /* flags, incl. kern & message, e.g. DONE */ int rtm_addrs; /* bitmask identifying sockaddrs in msg */ pid_t rtm_pid; /* identify sender */ int rtm_seq; /* for sender to identify action */ int rtm_errno; /* why failed */ int rtm_use; /* from rtentry */ u_long rtm_inits; /* which metrics we are initializing */ struct rt_metrics rtm_rmx; /* metrics themselves */};struct { struct rt_msghdr m_rtm; char m_space[512];} m_rtmsg;#define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))static boolget_default_gateway (in_addr_t *ret){ struct gc_arena gc = gc_new (); int s, seq, l, pid, rtm_addrs, i; struct sockaddr so_dst, so_mask; char *cp = m_rtmsg.m_space; struct sockaddr *gate = NULL, *sa; struct rt_msghdr *rtm_aux;#define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\ }#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))#define rtm m_rtmsg.m_rtm pid = getpid(); seq = 0; rtm_addrs = RTA_DST | RTA_NETMASK; bzero(&so_dst, sizeof(so_dst)); bzero(&so_mask, sizeof(so_mask)); bzero(&rtm, sizeof(struct rt_msghdr)); rtm.rtm_type = RTM_GET; rtm.rtm_flags = RTF_UP | RTF_GATEWAY; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = ++seq; rtm.rtm_addrs = rtm_addrs; so_dst.sa_family = AF_INET; so_dst.sa_len = sizeof(struct sockaddr_in); so_mask.sa_family = AF_INET; so_mask.sa_len = sizeof(struct sockaddr_in); NEXTADDR(RTA_DST, so_dst); NEXTADDR(RTA_NETMASK, so_mask); rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; s = socket(PF_ROUTE, SOCK_RAW, 0); if (write(s, (char *)&m_rtmsg, l) < 0) { msg (M_WARN, "ROUTE: problem writing to routing socket"); gc_free (&gc); return false; } do { l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); rtm_aux = &rtm; cp = ((char *)(rtm_aux + 1)); if (rtm_aux->rtm_addrs) { for (i = 1; i; i <<= 1) if (i & rtm_aux->rtm_addrs) { sa = (struct sockaddr *)cp; if (i == RTA_GATEWAY ) gate = sa; ADVANCE(cp, sa); } } else { gc_free (&gc); return false; } if (gate != NULL ) { *ret = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);#if 1 msg (M_INFO, "gw %s", print_in_addr_t ((in_addr_t) *ret, false, &gc));#endif gc_free (&gc); return true; } else { gc_free (&gc); return false; }}#elsestatic boolget_default_gateway (in_addr_t *ret){ return false;}#endifboolnetmask_to_netbits (in_addr_t network, in_addr_t netmask, int *netbits){ int i; const int addrlen = sizeof (in_addr_t) * 8; if ((network & netmask) == network) { for (i = 0; i <= addrlen; ++i) { in_addr_t mask = netbits_to_netmask (i); if (mask == netmask) { if (i == addrlen) *netbits = -1; else *netbits = i; return true; } } } return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -