Add and document ether_ntoa_r() and ether_aton_r() functions, which accept

passed storage buffers rather than using static storage.  Reimplement
ether_ntoa() and ether_aton() in terms of these functions.  These variants
are thread-safe.
This commit is contained in:
Robert Watson 2007-05-13 13:57:45 +00:00
parent b06619453f
commit 62ad77f006
2 changed files with 85 additions and 37 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 1995 Bill Paul <wpaul@ctr.columbia.edu>.
* Copyright (c) 2007 Robert N. M. Watson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -67,53 +68,67 @@ __FBSDID("$FreeBSD$");
int
ether_line(const char *l, struct ether_addr *e, char *hostname)
{
int i, o[6];
int i, o[6];
i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2], &o[3],
i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2], &o[3],
&o[4], &o[5], hostname);
if (i != 7)
return (i);
for (i=0; i<6; i++)
e->octet[i] = o[i];
return (0);
return (i);
for (i=0; i<6; i++)
e->octet[i] = o[i];
return (0);
}
/*
* Convert an ASCII representation of an ethernet address to binary form.
*/
struct ether_addr *
ether_aton(const char *a)
ether_aton_r(const char *a, struct ether_addr *e)
{
int i;
static struct ether_addr o;
int i;
unsigned int o0, o1, o2, o3, o4, o5;
i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
if (i != 6)
return (NULL);
o.octet[0]=o0;
o.octet[1]=o1;
o.octet[2]=o2;
o.octet[3]=o3;
o.octet[4]=o4;
o.octet[5]=o5;
return ((struct ether_addr *)&o);
i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
if (i != 6)
return (NULL);
e->octet[0]=o0;
e->octet[1]=o1;
e->octet[2]=o2;
e->octet[3]=o3;
e->octet[4]=o4;
e->octet[5]=o5;
return (e);
}
struct ether_addr *
ether_aton(const char *a)
{
static struct ether_addr e;
return (ether_aton_r(a, &e));
}
/*
* Convert a binary representation of an ethernet address to an ASCII string.
*/
char *
ether_ntoa_r(const struct ether_addr *n, char *a)
{
int i;
i = sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x", n->octet[0],
n->octet[1], n->octet[2], n->octet[3], n->octet[4], n->octet[5]);
if (i < 17)
return (NULL);
return (a);
}
char *
ether_ntoa(const struct ether_addr *n)
{
int i;
static char a[18];
i = sprintf(a, "%02x:%02x:%02x:%02x:%02x:%02x", n->octet[0],
n->octet[1], n->octet[2], n->octet[3], n->octet[4], n->octet[5]);
if (i < 17)
return (NULL);
return ((char *)&a);
return (ether_ntoa_r(n, a));
}
/*

View file

@ -1,5 +1,6 @@
.\" Copyright (c) 1995
.\" Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
.\" Copyright (c) 1995 Bill Paul <wpaul@ctr.columbia.edu>.
.\" Copyright (c) 2007 Robert N. M. Watson
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@ -30,14 +31,16 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 12, 1995
.Dd May 13, 2007
.Dt ETHERS 3
.Os
.Sh NAME
.Nm ethers ,
.Nm ether_line ,
.Nm ether_aton ,
.Nm ether_aton_r ,
.Nm ether_ntoa ,
.Nm ether_ntoa_r ,
.Nm ether_ntohost ,
.Nm ether_hostton
.Nd Ethernet address conversion and lookup routines
@ -51,8 +54,12 @@
.Fn ether_line "const char *l" "struct ether_addr *e" "char *hostname"
.Ft struct ether_addr *
.Fn ether_aton "const char *a"
.Ft struct ether_addr *
.Fn ether_aton_r "const char *a" "struct ether_addr *e"
.Ft char *
.Fn ether_ntoa "const struct ether_addr *n"
.Ft char *
.Fn ether_ntoa_r "const struct ether_addr *n" "char *buf"
.Ft int
.Fn ether_ntohost "char *hostname" "const struct ether_addr *e"
.Ft int
@ -95,18 +102,23 @@ into their component parts.
.Pp
The
.Fn ether_aton
function converts an
and
.Fn ether_aton_r
functions convert
.Tn ASCII
representation of an ethernet address into an
representation of ethernet addresses into
.Vt ether_addr
structure.
Likewise,
structures.
Likewise, the
.Fn ether_ntoa
converts an ethernet address specified as an
and
.Fn ether_ntoa_r
functions
convert ethernet addresses specified as
.Vt ether_addr
structure into an
structures into
.Tn ASCII
string.
strings.
.Pp
The
.Fn ether_ntohost
@ -138,7 +150,9 @@ and the hostname in the supplied string
.Pp
On success,
.Fn ether_ntoa
returns a pointer to a string containing an
and
.Fn ether_ntoa_r
functions return a pointer to a string containing an
.Tn ASCII
representation of an ethernet address.
If it is unable to convert
@ -147,13 +161,25 @@ the supplied
structure, it returns a
.Dv NULL
pointer.
.Fn ether_ntoa
stores the result in a static buffer;
.Fn ether_ntoa_r
stores the result in a user-passed buffer.
.Pp
Likewise,
.Fn ether_aton
returns a pointer to an
and
.Fn ether_aton_r
return a pointer to an
.Vt ether_addr
structure on success and a
.Dv NULL
pointer on failure.
.Fn ether_aton
stores the result in a static buffer;
.Fn ether_aton_r
stores the result in a user-passed buffer.
.Pp
The
.Fn ether_ntohost
@ -192,6 +218,8 @@ This particular implementation of the
.Nm
library functions were written for and first appeared in
.Fx 2.1 .
Thread-safe function variants first appeared in
.Fx 7.0 .
.Sh BUGS
The
.Fn ether_aton
@ -199,3 +227,8 @@ and
.Fn ether_ntoa
functions returns values that are stored in static memory areas
which may be overwritten the next time they are called.
.Pp
.Fn ether_ntoa_r
accepts a character buffer pointer, but not a buffer length.
The caller must ensure adequate space is available in the buffer in order to
avoid a buffer overflow.