This patch adds the IOCTL requests IOC_RT_HOST_ROUTE_GET and IOC_RT_HOST_ROUTE_GET_DEV. On sucess, the requests return the HW address and the device name for the specified IPv4 host address. This also means, that the address has been resolved. The rtroute utility supports these requests and serves as example:
# rtroute get <addr> [dev <dev>] Signed-off-by: Wolfang Grandegger <[EMAIL PROTECTED]> Index: rtnet/stack/include/ipv4/route.h =================================================================== --- rtnet.orig/stack/include/ipv4/route.h +++ rtnet/stack/include/ipv4/route.h @@ -53,6 +53,8 @@ int rt_ip_route_forward(struct rtskb *rt #ifdef CONFIG_RTNET_RTIPV4_ROUTE_SRC int __rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev); +int __rt_ip_route_get_host(u32 addr, char* if_name, unsigned char *dev_addr, + struct rtnet_device *rtdev); int __rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr); static inline int rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev) @@ -60,6 +62,13 @@ static inline int rt_ip_route_del_host(u return __rt_ip_route_del_host(addr, rtdev); } +static inline int rt_ip_route_get_host(u32 addr, char* if_name, + unsigned char *dev_addr, + struct rtnet_device *rtdev) +{ + return __rt_ip_route_get_host(addr, if_name, dev_addr, rtdev); +} + static inline int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr) { @@ -67,6 +76,7 @@ static inline int rt_ip_route_output(str } #else /* !CONFIG_RTNET_RTIPV4_ROUTE_SRC */ int __rt_ip_route_del_host(u32 addr); +int __rt_ip_route_get_host(u32 addr, char* if_name, unsigned char *dev_addr); int __rt_ip_route_output(struct dest_route *rt_buf, u32 daddr); static inline int rt_ip_route_del_host(u32 addr, struct rtnet_device *rtdev) @@ -74,6 +84,13 @@ static inline int rt_ip_route_del_host(u return __rt_ip_route_del_host(addr); } +static inline int rt_ip_route_get_host(u32 addr, char* if_name, + unsigned char *dev_addr, + struct rtnet_device *rtdev) +{ + return __rt_ip_route_get_host(addr, if_name, dev_addr); +} + static inline int rt_ip_route_output(struct dest_route *rt_buf, u32 daddr, u32 saddr) { Index: rtnet/stack/include/ipv4_chrdev.h =================================================================== --- rtnet.orig/stack/include/ipv4_chrdev.h +++ rtnet/stack/include/ipv4_chrdev.h @@ -40,6 +40,11 @@ struct ipv4_cmd { struct { __u32 ip_addr; unsigned char dev_addr[DEV_ADDR_LEN]; + } gethost; + + struct { + __u32 ip_addr; + unsigned char dev_addr[DEV_ADDR_LEN]; } addhost; struct { @@ -86,7 +91,12 @@ struct ipv4_cmd { #define IOC_RT_PING _IOWR(RTNET_IOC_TYPE_IPV4, 5 | \ RTNET_IOC_NODEV_PARAM, \ struct ipv4_cmd) -#define IOC_RT_HOST_ROUTE_DELETE_DEV _IOW(RTNET_IOC_TYPE_IPV4, 6, \ +#define IOC_RT_HOST_ROUTE_DELETE_DEV _IOW(RTNET_IOC_TYPE_IPV4, 6, \ struct ipv4_cmd) +#define IOC_RT_HOST_ROUTE_GET _IOWR(RTNET_IOC_TYPE_IPV4, 7 | \ + RTNET_IOC_NODEV_PARAM, \ + struct ipv4_cmd) +#define IOC_RT_HOST_ROUTE_GET_DEV _IOWR(RTNET_IOC_TYPE_IPV4, 8, \ + struct ipv4_cmd) #endif /* __IPV4_H_ */ Index: rtnet/stack/ipv4/af_inet.c =================================================================== --- rtnet.orig/stack/ipv4/af_inet.c +++ rtnet/stack/ipv4/af_inet.c @@ -162,6 +162,17 @@ static int ipv4_ioctl(struct rtnet_devic ret = rt_ip_route_del_host(cmd.args.delhost.ip_addr, rtdev); break; + case IOC_RT_HOST_ROUTE_GET: + case IOC_RT_HOST_ROUTE_GET_DEV: + ret = rt_ip_route_get_host(cmd.args.gethost.ip_addr, + cmd.head.if_name, + cmd.args.gethost.dev_addr, rtdev); + if (ret >= 0) { + if (copy_to_user((void *)arg, &cmd, sizeof(cmd)) != 0) + ret = -EFAULT; + } + break; + #ifdef CONFIG_RTNET_RTIPV4_NETROUTING case IOC_RT_NET_ROUTE_ADD: ret = rt_ip_route_add_net(cmd.args.addnet.net_addr, Index: rtnet/stack/ipv4/route.c =================================================================== --- rtnet.orig/stack/ipv4/route.c +++ rtnet/stack/ipv4/route.c @@ -509,6 +509,51 @@ void rt_ip_route_del_all(struct rtnet_de } +/*** + * rt_ip_route_get_host - check if specified host route is resolved + */ +int __rt_ip_route_get_host(u32 addr, char *if_name, unsigned char *dev_addr +#ifdef CONFIG_RTNET_RTIPV4_ROUTE_SRC + , struct rtnet_device *rtdev +#endif /* CONFIG_RTNET_RTIPV4_ROUTE_SRC */ + ) +{ + rtdm_lockctx_t context; + struct host_route *rt; + struct host_route **last_ptr; + unsigned int key; + + + key = ntohl(addr) & HOST_HASH_KEY_MASK; + last_ptr = &host_hash_tbl[key]; + + rtdm_lock_get_irqsave(&host_table_lock, context); + + rt = host_hash_tbl[key]; + while (rt != NULL) { + if ((rt->dest_host.ip == addr) +#ifdef CONFIG_RTNET_RTIPV4_ROUTE_SRC + && (!rtdev_src || + (rt->dest_host.rtdev->local_ip == rtdev_src->local_ip)) +#endif + ) { + memcpy(dev_addr, rt->dest_host.dev_addr, + rt->dest_host.rtdev->addr_len); + strncpy(if_name, rt->dest_host.rtdev->name, IFNAMSIZ); + + rtdm_lock_put_irqrestore(&host_table_lock, context); + return 0; + } + + last_ptr = &rt->next; + rt = rt->next; + } + + rtdm_lock_put_irqrestore(&host_table_lock, context); + + return -ENOENT; +} + #ifdef CONFIG_RTNET_RTIPV4_NETROUTING /*** Index: rtnet/tools/rtroute.c =================================================================== --- rtnet.orig/tools/rtroute.c +++ rtnet/tools/rtroute.c @@ -54,6 +54,7 @@ void help(void) "\trtroute add <addr> netmask <mask> gw <gw-addr>\n" "\trtroute del <addr> [dev <dev>]\n" "\trtroute del <addr> netmask <mask>\n" + "\trtroute get <addr> [dev <dev>]\n" "\trtroute -f <host-routes-file>\n" ); @@ -307,6 +308,49 @@ void route_delete(int argc, char *argv[] +void route_get(int argc, char *argv[]) +{ + int ret; + + + if (argc == 3) { + /*** delete host route ***/ + cmd.args.gethost.ip_addr = addr.s_addr; + + ret = ioctl(f, IOC_RT_HOST_ROUTE_GET, &cmd); + } else if (argc == 5) { + /*** delete device specific route ***/ + if (strcmp(argv[3], "dev") == 0) { + cmd.args.delhost.ip_addr = addr.s_addr; + strncpy(cmd.head.if_name, argv[4], IFNAMSIZ); + ret = ioctl(f, IOC_RT_HOST_ROUTE_GET_DEV, &cmd); + } + else + help(); + } else + help(); + + if (ret >= 0) { + char *p = cmd.args.gethost.dev_addr; + printf("Destination\tHW Address\t\tDevice\n" + "%s\t%02x:%02x:%02x:%02x:%02x:%02x\t%s\n", argv[2], + p[0], p[1], p[2] , p[3], p[4], p[5], cmd.head.if_name); + } else { + if (errno == ENOENT) { + fprintf(stderr, "No route for host %s", argv[2]); + if (argc == 5) + fprintf(stderr, "on device %s", argv[4]); + fprintf(stderr, " found\n"); + } else + perror("ioctl"); + exit(1); + } + + exit(0); +} + + + int main(int argc, char *argv[]) { const char rtnet_dev[] = "/dev/rtnet"; @@ -338,6 +382,8 @@ int main(int argc, char *argv[]) route_add(argc, argv); if (strcmp(argv[1], "del") == 0) route_delete(argc, argv); + if (strcmp(argv[1], "get") == 0) + route_get(argc, argv); help(); -- ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ RTnet-users mailing list RTnet-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rtnet-users