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

Reply via email to