1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-21 06:59:01 +00:00

Add metric to struct route_entry.

Actually getting a nonzero value for the metric is supported only on
Linux and Windows.
This commit is contained in:
david
2013-02-01 05:01:56 +00:00
parent 913fbac6d1
commit f55171a088
6 changed files with 192 additions and 3 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;