From f55171a088100c2205799459a96be0deb260d8e8 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 1 Feb 2013 05:01:56 +0000 Subject: [PATCH] Add metric to struct route_entry. Actually getting a nonzero value for the metric is supported only on Linux and Windows. --- libdnet-stripped/NMAP_MODIFICATIONS | 162 ++++++++++++++++++++++++++ libdnet-stripped/include/dnet/route.h | 1 + libdnet-stripped/src/route-bsd.c | 6 + libdnet-stripped/src/route-hpux.c | 2 + libdnet-stripped/src/route-linux.c | 8 +- libdnet-stripped/src/route-win32.c | 16 +++ 6 files changed, 192 insertions(+), 3 deletions(-) diff --git a/libdnet-stripped/NMAP_MODIFICATIONS b/libdnet-stripped/NMAP_MODIFICATIONS index 6d74d26c0..b6196be12 100644 --- a/libdnet-stripped/NMAP_MODIFICATIONS +++ b/libdnet-stripped/NMAP_MODIFICATIONS @@ -1658,3 +1658,165 @@ index ff86851..b4536b3 100644 ret = GetIpForwardTable(r->ipftable, &len, FALSE); if (ret == NO_ERROR) break; + +o Add metric to struct route_entry. + +diff --git a/libdnet-stripped/include/dnet/route.h b/libdnet-stripped/include/dnet/route.h +index 7969772..b4bd4cc 100644 +--- a/libdnet-stripped/include/dnet/route.h ++++ b/libdnet-stripped/include/dnet/route.h +@@ -18,6 +18,7 @@ struct route_entry { + char intf_name[INTF_NAME_LEN]; /* interface name */ + struct addr route_dst; /* destination address */ + struct addr route_gw; /* gateway address */ ++ int metric; /* per-route metric */ + }; + + typedef struct route_handle route_t; +diff --git a/libdnet-stripped/src/route-bsd.c b/libdnet-stripped/src/route-bsd.c +index 33f2985..44e7dd2 100644 +--- a/libdnet-stripped/src/route-bsd.c ++++ b/libdnet-stripped/src/route-bsd.c +@@ -224,6 +224,7 @@ route_get(route_t *r, struct route_entry *entry) + if (route_msg(r, RTM_GET, entry->intf_name, &entry->route_dst, &entry->route_gw) < 0) + return (-1); + entry->intf_name[0] = '\0'; ++ entry->metric = 0; + + return (0); + } +@@ -359,6 +360,8 @@ route_loop(route_t *r, route_handler callback, void *arg) + continue; + } + ++ entry.metric = 0; ++ + if ((ret = callback(&entry, arg)) != 0) + break; + } +@@ -473,6 +476,8 @@ route_loop(route_t *r, route_handler callback, void *arg) + sin.sin_addr.s_addr = rt->ipRouteMask; + addr_stob((struct sockaddr *)&sin, + &entry.route_dst.addr_bits); ++ ++ entry.metric = 0; + + if ((ret = callback(&entry, arg)) != 0) + return (ret); +@@ -608,6 +613,7 @@ _radix_walk(int fd, struct radix_node *rn, route_handler callback, void *arg) + } + _kread(fd, rt.rt_gateway, &sin, sizeof(sin)); + addr_ston((struct sockaddr *)&sin, &entry.route_gw); ++ entry.metric = 0; + if ((ret = callback(&entry, arg)) != 0) + return (ret); + } +diff --git a/libdnet-stripped/src/route-hpux.c b/libdnet-stripped/src/route-hpux.c +index a542347..07e7f8c 100644 +--- a/libdnet-stripped/src/route-hpux.c ++++ b/libdnet-stripped/src/route-hpux.c +@@ -120,6 +120,7 @@ route_get(route_t *r, struct route_entry *entry) + entry->route_gw.addr_type = ADDR_TYPE_IP; + entry->route_gw.addr_bits = IP_ADDR_BITS; + memcpy(&entry->route_gw.addr_ip, &rtr.rtr_gwayaddr, IP_ADDR_LEN); ++ entry->metric = 0; + + return (0); + } +@@ -163,6 +164,7 @@ route_loop(route_t *r, route_handler callback, void *arg) + addr_mtob(&rtentries[i].Mask, IP_ADDR_LEN, + &entry.route_dst.addr_bits); + entry.route_gw.addr_ip = rtentries[i].NextHop; ++ entry.metric = 0; + + if ((ret = callback(&entry, arg)) != 0) + break; +diff --git a/libdnet-stripped/src/route-linux.c b/libdnet-stripped/src/route-linux.c +index a80b71b..b14c527 100644 +--- a/libdnet-stripped/src/route-linux.c ++++ b/libdnet-stripped/src/route-linux.c +@@ -252,6 +252,7 @@ route_loop(route_t *r, route_handler callback, void *arg) + continue; + + entry.route_gw.addr_bits = IP_ADDR_BITS; ++ entry.metric = metric; + + if ((ret = callback(&entry, arg)) != 0) + break; +@@ -260,17 +261,17 @@ route_loop(route_t *r, route_handler callback, void *arg) + } + if (ret == 0 && (fp = fopen(PROC_IPV6_ROUTE_FILE, "r")) != NULL) { + char s[33], d[8][5], n[8][5]; +- int i, iflags; ++ int i, iflags, metric; + u_int slen, dlen; + + while (fgets(buf, sizeof(buf), fp) != NULL) { + i = sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %02x " + "%32s %02x %04s%04s%04s%04s%04s%04s%04s%04s " +- "%*x %*x %*x %x %15s", ++ "%x %*x %*x %x %15s", + d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], + &dlen, s, &slen, + n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], +- &iflags, ifbuf); ++ &metric, &iflags, ifbuf); + + if (i < 21 || !(iflags & RTF_UP)) + continue; +@@ -285,6 +286,7 @@ route_loop(route_t *r, route_handler callback, void *arg) + n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], + IP6_ADDR_BITS); + addr_aton(buf, &entry.route_gw); ++ entry.metric = metric; + + if ((ret = callback(&entry, arg)) != 0) + break; +diff --git a/libdnet-stripped/src/route-win32.c b/libdnet-stripped/src/route-win32.c +index b4536b3..c69b29b 100644 +--- a/libdnet-stripped/src/route-win32.c ++++ b/libdnet-stripped/src/route-win32.c +@@ -122,6 +122,7 @@ route_get(route_t *route, struct route_entry *entry) + entry->route_gw.addr_type = ADDR_TYPE_IP; + entry->route_gw.addr_bits = IP_ADDR_BITS; + entry->route_gw.addr_ip = ipfrow.dwForwardNextHop; ++ entry->metric = ipfrow.dwForwardMetric1; + + entry->intf_name[0] = '\0'; + intf = intf_open(); +@@ -172,6 +173,7 @@ route_loop_getipforwardtable(route_t *r, route_handler callback, void *arg) + &entry.route_dst.addr_bits); + entry.route_gw.addr_ip = + r->ipftable->table[i].dwForwardNextHop; ++ entry.metric = r->ipftable->table[i].dwForwardMetric1; + + /* Look up the interface name. */ + entry.intf_name[0] = '\0'; +@@ -209,6 +211,8 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2, + for (i = 0; i < r->ipftable2->NumEntries; i++) { + struct intf_entry intf_entry; + MIB_IPFORWARD_ROW2 *row; ++ MIB_IPINTERFACE_ROW ifrow; ++ ULONG metric; + + row = &r->ipftable2->Table[i]; + addr_ston((struct sockaddr *) &row->DestinationPrefix.Prefix, &entry.route_dst); +@@ -223,6 +227,18 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2, + row->InterfaceIndex) == 0) { + strlcpy(entry.intf_name, intf_entry.intf_name, sizeof(entry.intf_name)); + } ++ ++ ifrow.Family = row->DestinationPrefix.Prefix.si_family; ++ ifrow.InterfaceLuid = row->InterfaceLuid; ++ ifrow.InterfaceIndex = row->InterfaceIndex; ++ if (GetIpInterfaceEntry(&ifrow) != NO_ERROR) { ++ return (-1); ++ } ++ metric = ifrow.Metric + row->Metric; ++ if (metric < INT_MAX) ++ entry.metric = metric; ++ else ++ entry.metric = INT_MAX; + + if ((ret = (*callback)(&entry, arg)) != 0) + break; diff --git a/libdnet-stripped/include/dnet/route.h b/libdnet-stripped/include/dnet/route.h index 796977242..b4bd4ccc0 100644 --- a/libdnet-stripped/include/dnet/route.h +++ b/libdnet-stripped/include/dnet/route.h @@ -18,6 +18,7 @@ struct route_entry { char intf_name[INTF_NAME_LEN]; /* interface name */ struct addr route_dst; /* destination address */ struct addr route_gw; /* gateway address */ + int metric; /* per-route metric */ }; typedef struct route_handle route_t; diff --git a/libdnet-stripped/src/route-bsd.c b/libdnet-stripped/src/route-bsd.c index 33f2985f3..44e7dd2f2 100644 --- a/libdnet-stripped/src/route-bsd.c +++ b/libdnet-stripped/src/route-bsd.c @@ -224,6 +224,7 @@ route_get(route_t *r, struct route_entry *entry) if (route_msg(r, RTM_GET, entry->intf_name, &entry->route_dst, &entry->route_gw) < 0) return (-1); entry->intf_name[0] = '\0'; + entry->metric = 0; return (0); } @@ -359,6 +360,8 @@ route_loop(route_t *r, route_handler callback, void *arg) continue; } + entry.metric = 0; + if ((ret = callback(&entry, arg)) != 0) break; } @@ -473,6 +476,8 @@ route_loop(route_t *r, route_handler callback, void *arg) sin.sin_addr.s_addr = rt->ipRouteMask; addr_stob((struct sockaddr *)&sin, &entry.route_dst.addr_bits); + + entry.metric = 0; if ((ret = callback(&entry, arg)) != 0) return (ret); @@ -608,6 +613,7 @@ _radix_walk(int fd, struct radix_node *rn, route_handler callback, void *arg) } _kread(fd, rt.rt_gateway, &sin, sizeof(sin)); addr_ston((struct sockaddr *)&sin, &entry.route_gw); + entry.metric = 0; if ((ret = callback(&entry, arg)) != 0) return (ret); } diff --git a/libdnet-stripped/src/route-hpux.c b/libdnet-stripped/src/route-hpux.c index a54234744..07e7f8ce7 100644 --- a/libdnet-stripped/src/route-hpux.c +++ b/libdnet-stripped/src/route-hpux.c @@ -120,6 +120,7 @@ route_get(route_t *r, struct route_entry *entry) entry->route_gw.addr_type = ADDR_TYPE_IP; entry->route_gw.addr_bits = IP_ADDR_BITS; memcpy(&entry->route_gw.addr_ip, &rtr.rtr_gwayaddr, IP_ADDR_LEN); + entry->metric = 0; return (0); } @@ -163,6 +164,7 @@ route_loop(route_t *r, route_handler callback, void *arg) addr_mtob(&rtentries[i].Mask, IP_ADDR_LEN, &entry.route_dst.addr_bits); entry.route_gw.addr_ip = rtentries[i].NextHop; + entry.metric = 0; if ((ret = callback(&entry, arg)) != 0) break; diff --git a/libdnet-stripped/src/route-linux.c b/libdnet-stripped/src/route-linux.c index a80b71b11..b14c52795 100644 --- a/libdnet-stripped/src/route-linux.c +++ b/libdnet-stripped/src/route-linux.c @@ -252,6 +252,7 @@ route_loop(route_t *r, route_handler callback, void *arg) continue; entry.route_gw.addr_bits = IP_ADDR_BITS; + entry.metric = metric; if ((ret = callback(&entry, arg)) != 0) break; @@ -260,17 +261,17 @@ route_loop(route_t *r, route_handler callback, void *arg) } if (ret == 0 && (fp = fopen(PROC_IPV6_ROUTE_FILE, "r")) != NULL) { char s[33], d[8][5], n[8][5]; - int i, iflags; + int i, iflags, metric; u_int slen, dlen; while (fgets(buf, sizeof(buf), fp) != NULL) { i = sscanf(buf, "%04s%04s%04s%04s%04s%04s%04s%04s %02x " "%32s %02x %04s%04s%04s%04s%04s%04s%04s%04s " - "%*x %*x %*x %x %15s", + "%x %*x %*x %x %15s", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], &dlen, s, &slen, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], - &iflags, ifbuf); + &metric, &iflags, ifbuf); if (i < 21 || !(iflags & RTF_UP)) continue; @@ -285,6 +286,7 @@ route_loop(route_t *r, route_handler callback, void *arg) n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], IP6_ADDR_BITS); addr_aton(buf, &entry.route_gw); + entry.metric = metric; if ((ret = callback(&entry, arg)) != 0) break; diff --git a/libdnet-stripped/src/route-win32.c b/libdnet-stripped/src/route-win32.c index b4536b33d..c69b29bfb 100644 --- a/libdnet-stripped/src/route-win32.c +++ b/libdnet-stripped/src/route-win32.c @@ -122,6 +122,7 @@ route_get(route_t *route, struct route_entry *entry) entry->route_gw.addr_type = ADDR_TYPE_IP; entry->route_gw.addr_bits = IP_ADDR_BITS; entry->route_gw.addr_ip = ipfrow.dwForwardNextHop; + entry->metric = ipfrow.dwForwardMetric1; entry->intf_name[0] = '\0'; intf = intf_open(); @@ -172,6 +173,7 @@ route_loop_getipforwardtable(route_t *r, route_handler callback, void *arg) &entry.route_dst.addr_bits); entry.route_gw.addr_ip = r->ipftable->table[i].dwForwardNextHop; + entry.metric = r->ipftable->table[i].dwForwardMetric1; /* Look up the interface name. */ entry.intf_name[0] = '\0'; @@ -209,6 +211,8 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2, for (i = 0; i < r->ipftable2->NumEntries; i++) { struct intf_entry intf_entry; MIB_IPFORWARD_ROW2 *row; + MIB_IPINTERFACE_ROW ifrow; + ULONG metric; row = &r->ipftable2->Table[i]; addr_ston((struct sockaddr *) &row->DestinationPrefix.Prefix, &entry.route_dst); @@ -223,6 +227,18 @@ route_loop_getipforwardtable2(GETIPFORWARDTABLE2 GetIpForwardTable2, row->InterfaceIndex) == 0) { strlcpy(entry.intf_name, intf_entry.intf_name, sizeof(entry.intf_name)); } + + ifrow.Family = row->DestinationPrefix.Prefix.si_family; + ifrow.InterfaceLuid = row->InterfaceLuid; + ifrow.InterfaceIndex = row->InterfaceIndex; + if (GetIpInterfaceEntry(&ifrow) != NO_ERROR) { + return (-1); + } + metric = ifrow.Metric + row->Metric; + if (metric < INT_MAX) + entry.metric = metric; + else + entry.metric = INT_MAX; if ((ret = (*callback)(&entry, arg)) != 0) break;