2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (if_lookup_by_name_len, if_get_by_name_len) New functions.
* if.c: (if_lookup_by_name_len, if_get_by_name_len) New functions.
(if_get_by_name) Tighten up code.
(interface) Use new function if_get_by_name_len.
* zclient.c: (zebra_interface_add_read) Use new if_get_by_name_len
function.
(zebra_interface_state_read) Use new if_lookup_by_name_len function.
* kernel_socket.c: (ifm_read) Use new if_lookup_by_name_len function
to save a memcpy.
* if_ioctl_solaris.c: (interface_list_ioctl) Fix subtle bug with new
if_get_by_name_len function.
* ospf_interface.c: (ospf_vl_new) Use strnlen to fix call to if_create.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index c372e66..35910a6 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,5 +1,15 @@
2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+ * if.h: (if_lookup_by_name_len, if_get_by_name_len) New functions.
+ * if.c: (if_lookup_by_name_len, if_get_by_name_len) New functions.
+ (if_get_by_name) Tighten up code.
+ (interface) Use new function if_get_by_name_len.
+ * zclient.c: (zebra_interface_add_read) Use new if_get_by_name_len
+ function.
+ (zebra_interface_state_read) Use new if_lookup_by_name_len function.
+
+2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
* str.c: Replace strlcpy and strlcat with actual working versions
copied from rsync-2.6.2/lib/compat.c.
diff --git a/lib/if.c b/lib/if.c
index e35e3ed..212b236 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -219,12 +219,33 @@
for (node = listhead (iflist); node; nextnode (node))
{
ifp = getdata (node);
+ /* Change this to strcmp once improper uses of this function
+ have been replaced with calls to if_lookup_by_name_len. */
if (strncmp (name, ifp->name, sizeof ifp->name) == 0)
return ifp;
}
return NULL;
}
+struct interface *
+if_lookup_by_name_len(const char *name, size_t namelen)
+{
+ struct listnode *node;
+
+ if (namelen > INTERFACE_NAMSIZ)
+ return NULL;
+
+ for (node = listhead (iflist); node; nextnode (node))
+ {
+ struct interface *ifp;
+
+ ifp = getdata (node);
+ if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
+ return ifp;
+ }
+ return NULL;
+}
+
/* Lookup interface by IPv4 address. */
struct interface *
if_lookup_exact_address (struct in_addr src)
@@ -314,10 +335,19 @@
{
struct interface *ifp;
- ifp = if_lookup_by_name (name);
- if (ifp == NULL)
- ifp = if_create (name, INTERFACE_NAMSIZ);
- return ifp;
+ /* Replace 2nd arg to if_create with strlen(name) once improper uses of
+ this function have been replaced with calls to if_get_by_name_len. */
+ return ((ifp = if_lookup_by_name(name)) != NULL) ? ifp :
+ if_create(name, INTERFACE_NAMSIZ);
+}
+
+struct interface *
+if_get_by_name_len(const char *name, size_t namelen)
+{
+ struct interface *ifp;
+
+ return ((ifp = if_lookup_by_name_len(name, namelen)) != NULL) ? ifp :
+ if_create(name, namelen);
}
/* Does interface up ? */
@@ -504,10 +534,8 @@
return CMD_WARNING;
}
- ifp = if_lookup_by_name (argv[0]);
+ ifp = if_get_by_name_len(argv[0], sl);
- if (ifp == NULL)
- ifp = if_create (argv[0], sl);
vty->index = ifp;
vty->node = INTERFACE_NODE;
diff --git a/lib/if.h b/lib/if.h
index df9ff60..4cfc9e7 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -214,11 +214,25 @@
int if_cmp_func (struct interface *, struct interface *);
struct interface *if_create (const char *name, int namelen);
struct interface *if_lookup_by_index (unsigned int);
-struct interface *if_lookup_by_name (const char *);
struct interface *if_lookup_exact_address (struct in_addr);
struct interface *if_lookup_address (struct in_addr);
+
+/* Currently, the code assumes that the interface name arguments to these
+ functions have length <= INTERFACE_NAMSIZ, and they must be NUL-terminated
+ if they are shorter than INTERFACE_NAMSIZ. After code cleanup, the
+ implementation will be changed to require the arguments to these functions
+ to terminate with a NUL character (no length limitation). */
+struct interface *if_lookup_by_name (const char *);
struct interface *if_get_by_name (const char *);
+/* For these 2 functions, the 2nd argument should be the precise length
+ of the interface name (not counting a trailing NUL which may or may
+ not be present). */
+extern struct interface *if_lookup_by_name_len(const char *name,
+ size_t namelen);
+extern struct interface *if_get_by_name_len(const char *name, size_t namelen);
+
+
/* Delete the interface, but do not free the structure, and leave it in the
interface list. It is often advisable to leave the pseudo interface
structure because there may be configuration information attached. */
diff --git a/lib/zclient.c b/lib/zclient.c
index 453e6cd..efcad57 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -534,12 +534,8 @@
/* Read interface name. */
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
- /* Lookup this by interface name. */
- ifp = if_lookup_by_name (ifname_tmp);
-
- /* If such interface does not exist, make new one. */
- if (! ifp)
- ifp = if_create (ifname_tmp, INTERFACE_NAMSIZ);
+ /* Lookup/create interface by name. */
+ ifp = if_get_by_name_len (ifname_tmp, strnlen(ifname_tmp, INTERFACE_NAMSIZ));
/* Read interface's index. */
ifp->ifindex = stream_getl (s);
@@ -579,7 +575,8 @@
stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
/* Lookup this by interface index. */
- ifp = if_lookup_by_name (ifname_tmp);
+ ifp = if_lookup_by_name_len (ifname_tmp,
+ strnlen(ifname_tmp, INTERFACE_NAMSIZ));
/* If such interface does not exist, indicate an error */
if (! ifp)
diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog
index b1d6bbe..e8eae90 100644
--- a/ospfd/ChangeLog
+++ b/ospfd/ChangeLog
@@ -1,5 +1,9 @@
2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+ * ospf_interface.c: (ospf_vl_new) Use strnlen to fix call to if_create.
+
+2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
* ospf_vty.c: (show_ip_ospf_interface_sub) Show ifindex and interface
flags to help with debugging.
* ospf_zebra.c: (ospf_interface_delete) After deleting, set ifp->ifindex
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index b76abe5..027dfb9 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -880,8 +880,8 @@
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");
- snprintf (ifname, INTERFACE_NAMSIZ + 1, "VLINK%d", vlink_count);
- vi = if_create (ifname, INTERFACE_NAMSIZ);
+ snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
+ vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
co = connected_new ();
co->ifp = vi;
listnode_add (vi->connected, co);
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index 572d268..924f0f0 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -1,5 +1,12 @@
2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+ * kernel_socket.c: (ifm_read) Use new if_lookup_by_name_len function
+ to save a memcpy.
+ * if_ioctl_solaris.c: (interface_list_ioctl) Fix subtle bug with new
+ if_get_by_name_len function.
+
+2005-04-02 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
* interface.c: (if_new_intern_ifindex) Remove obsolete function.
(if_delete_update) After distributing the interface deletion message,
set ifp->ifindex to IFINDEX_INTERNAL.
diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c
index 38ac5a7..aa01b07 100644
--- a/zebra/if_ioctl_solaris.c
+++ b/zebra/if_ioctl_solaris.c
@@ -138,7 +138,9 @@
for (n = 0; n < lifconf.lifc_len; n += sizeof (struct lifreq))
{
- ifp = if_get_by_name (lifreq->lifr_name);
+ ifp = if_get_by_name_len(lifreq->lifr_name,
+ strnlen(lifreq->lifr_name,
+ sizeof(lifreq->lifr_name)));
if (lifreq->lifr_addr.ss_family == AF_INET)
ifp->flags |= IFF_IPV4;
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index cdc6822..1212563 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -235,7 +235,6 @@
struct sockaddr_dl *sdl = NULL;
void *cp;
unsigned int i;
- char ifname[IFNAMSIZ];
/* paranoia: sanity check structure */
if (ifm->ifm_msglen < sizeof(struct if_msghdr))
@@ -309,6 +308,9 @@
/*
* paranoia: sanity check name length. nlen does not include
* trailing zero, but IFNAMSIZ max length does.
+ *
+ * XXX Is this test correct? Should it be '>=' or '>'? And is it even
+ * necessary now that we are using if_lookup_by_name_len?
*/
if (sdl->sdl_nlen >= IFNAMSIZ)
{
@@ -316,9 +318,7 @@
return -1;
}
- memcpy (ifname, sdl->sdl_data, sdl->sdl_nlen);
- ifname[sdl->sdl_nlen] = '\0';
- ifp = if_lookup_by_name (ifname);
+ ifp = if_lookup_by_name_len (sdl->sdl_data, sdl->sdl_nlen);
}
/*