summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-inet
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/cmd-inet')
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile4
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.c414
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.h37
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c208
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h53
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c117
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h17
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.c11
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.h2
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c5
-rw-r--r--usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c4
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/Makefile2
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/in.rarpd.c661
13 files changed, 324 insertions, 1211 deletions
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile b/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile
index c4e23f1016..24f8535619 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/Makefile
@@ -30,7 +30,7 @@ ROOTFS_PROG = $(PROG)
DEFAULTFILES = dhcpagent.dfl
LOCOBJS = adopt.o agent.o async.o bound.o class_id.o defaults.o \
- dlpi_io.o dlprims.o inform.o init_reboot.o interface.o ipc_action.o \
+ dlpi_io.o inform.o init_reboot.o interface.o ipc_action.o \
packet.o release.o renew.o request.o script_handler.o select.o \
states.o util.o
COMDIR = $(SRC)/common/net/dhcp
@@ -49,7 +49,7 @@ XGETFLAGS += -a -x dhcpagent.xcl
#
CPPFLAGS += -I$(COMDIR) -D_XOPEN_SOURCE=500 -D__EXTENSIONS__
-LDLIBS += -lxnet -lnvpair -ldhcpagent -ldhcputil -linetutil -ldevinfo
+LDLIBS += -lxnet -lnvpair -ldhcpagent -ldhcputil -linetutil -ldevinfo -ldlpi
# Disable warnings that affect all XPG applications.
LINTFLAGS += -erroff=E_INCONS_ARG_DECL2 -erroff=E_INCONS_VAL_TYPE_DECL2
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.c
index 0783ae509b..0099600ec3 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.c
@@ -29,238 +29,85 @@
#include <sys/types.h>
#include <sys/pfmod.h>
#include <sys/socket.h>
-#include <net/if.h> /* IFNAMSIZ */
#include <netinet/in.h> /* in_addr (ip.h) */
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <stropts.h>
#include <string.h> /* strpbrk */
-#include <fcntl.h>
-#include <unistd.h>
#include <sys/uio.h>
-#include <sys/dlpi.h>
-#include <unistd.h>
#include <stdlib.h>
#include <dhcpmsg.h>
-#include <libinetutil.h>
-#include "dlprims.h"
#include "dlpi_io.h"
#include "v4_sum_impl.h"
+#include "common.h"
/*
- * dhcp_dlpi_open(): opens a DLPI stream to the given interface and returns
- * information purpose about that interface.
- *
- * input: const char *: the name of the interface to open
- * dl_info_ack_t *: a place to store information about the interface
- * size_t: the size of dl_info_ack_t
- * t_uscalar_t: the sap to bind to on this interface
- * output: int: the open file descriptor on success, -1 on failure
+ * timeout to wait for acknowledgement of packet filter, in seconds.
*/
-
-int
-dhcp_dlpi_open(const char *if_name, dl_info_ack_t *dlia, size_t dlia_size,
- t_uscalar_t dl_sap)
-{
- char device_name[sizeof ("/dev/") + IFNAMSIZ];
- int fd;
- ifspec_t ifsp;
- int is_style2 = 0;
-
- if (!ifparse_ifspec(if_name, &ifsp)) {
- dhcpmsg(MSG_ERROR, "dhcp_dlpi_open: invalid interface name");
- return (-1);
- }
-
- if (ifsp.ifsp_modcnt != 0) {
- dhcpmsg(MSG_ERROR, "dhcp_dlpi_open: modules cannot be "
- "specified with an interface name");
- return (-1);
- }
-
- /* try dlpi style1 interface first; if it fails, try style 2 */
- (void) snprintf(device_name, sizeof (device_name),
- "/dev/%s%d", ifsp.ifsp_devnm, ifsp.ifsp_ppa);
- if ((fd = open(device_name, O_RDWR)) == -1) {
- dhcpmsg(MSG_DEBUG, "dhcp_dlpi_open: open on `%s'", device_name);
-
- /* try style 2 interface */
- (void) snprintf(device_name, sizeof (device_name),
- "/dev/%s", ifsp.ifsp_devnm);
- fd = open(device_name, O_RDWR);
-
- /*
- * temporary hack: if the style-2 open of the /dev link fails,
- * try the corresponding /devices/pseudo path. this allows a
- * diskless boot to succeed without necessarily pre-creating the
- * /dev links, by taking advantage of devfs's ability to create
- * /devices nodes for h/w devices on demand. this is to avoid
- * the need to fiddle with packaging scripts to boot off a new
- * NIC device. when /dev links are created on demand, this
- * work-around may be removed.
- */
-
- {
- const char prefix[] = "/devices/pseudo/clone@0:";
- char path[sizeof (prefix) + IFNAMSIZ];
- if (fd == -1 && errno == ENOENT) {
- (void) snprintf(path, sizeof (path), "%s%s",
- prefix, ifsp.ifsp_devnm);
- fd = open(path, O_RDWR);
- }
- }
-
- if (fd == -1) {
- dhcpmsg(MSG_ERR, "dhcp_dlpi_open: open on `%s'",
- device_name);
- return (-1);
- }
- is_style2 = 1;
- }
-
- /*
- * okay, so we've got an open DLPI stream now. make sure that
- * it's DL_VERSION_2, DL_STYLE2, and that it's connectionless.
- * from there, attach to the appropriate ppa, bind to dl_sap,
- * and get ready to roll.
- */
-
- if (dlinforeq(fd, dlia, dlia_size) != 0) {
- dhcpmsg(MSG_ERR, "dhcp_dlpi_open: DL_INFO_REQ on %s (1)",
- device_name);
- (void) close(fd);
- return (-1);
- }
-
- if (dlia->dl_version != DL_VERSION_2) {
- dhcpmsg(MSG_ERROR, "dhcp_dlpi_open: %s is DLPI version %ld, "
- "not 2", device_name, dlia->dl_version);
- (void) close(fd);
- return (-1);
- }
-
- if (is_style2 && dlia->dl_provider_style != DL_STYLE2) {
- dhcpmsg(MSG_ERROR,
- "dhcp_dlpi_open: %s is DL_STYLE %lx, not DL_STYLE2",
- device_name, dlia->dl_provider_style);
- (void) close(fd);
- return (-1);
- }
-
- if ((dlia->dl_service_mode & DL_CLDLS) == 0) {
- dhcpmsg(MSG_ERROR, "dhcp_dlpi_open: %s is %#lx, not DL_CLDLS, "
- "which is not supported", device_name,
- dlia->dl_service_mode);
- (void) close(fd);
- return (-1);
- }
-
- if (is_style2 && dlattachreq(fd, ifsp.ifsp_ppa) == -1) {
- dhcpmsg(MSG_ERR, "dhcp_dlpi_open: DL_ATTACH_REQ on %s",
- device_name);
- (void) close(fd);
- return (-1);
- }
-
- if (dlbindreq(fd, dl_sap, 0, DL_CLDLS, 0) == -1) {
- dhcpmsg(MSG_ERR, "dhcp_dlpi_open: DL_BIND_REQ on %s",
- device_name);
- (void) close(fd);
- return (-1);
- }
-
- /*
- * we call this again since some of the information obtained
- * previously was not valid since we had not yet attached (in
- * particular, our MAC address) (but we needed to check the
- * STYLE before we did the attach)
- */
-
- if (dlinforeq(fd, dlia, dlia_size) != 0) {
- dhcpmsg(MSG_ERR, "dhcp_dlpi_open: DL_INFO_REQ on %s (2)",
- device_name);
- (void) close(fd);
- return (-1);
- }
-
- if (ioctl(fd, I_PUSH, "pfmod") == -1) {
- dhcpmsg(MSG_ERR, "dhcp_dlpi_open: cannot push pfmod on stream");
- (void) close(fd);
- return (-1);
- }
-
- (void) ioctl(fd, I_FLUSH, FLUSHR);
- return (fd);
-}
-
-/*
- * dhcp_dlpi_close(): closes a previously opened DLPI stream
- *
- * input: int: the file descriptor of the DLPI stream
- * output: int: 0 on success, -1 on failure
- */
-
-int
-dhcp_dlpi_close(int fd)
-{
- /* don't bother dismantling. it will happen automatically */
- return (close(fd));
-}
+#define FILTER_TIMEOUT 5
/*
* dlpi_recvfrom(): receives data on a DLPI stream
*
- * input: int: the socket to receive the data on
+ * input: dlpi_handle_t: dlpi handle to receive the data on
* void *: a buffer to store the data in
* size_t: the size of the buffer
* struct sockaddr_in *: if non-NULL, sender's IP address is filled in
* struct sockaddr_in *: if non-NULL, recipient's IP address
* output: ssize_t: the number of bytes read on success, -1 on failure
*/
-
ssize_t
-dlpi_recvfrom(int fd, void *buffer, size_t buf_len, struct sockaddr_in *from,
- struct sockaddr_in *to)
+dlpi_recvfrom(dlpi_handle_t dh, void *buf, size_t buflen,
+ struct sockaddr_in *from, struct sockaddr_in *to)
{
struct ip *ip;
struct udphdr *udphdr;
- void *data_buffer;
- ssize_t data_length;
+ void *msgbuf;
+ size_t msglen;
+ dlpi_recvinfo_t dlrecv;
+ int rc;
- data_length = buf_len + sizeof (struct ip) + sizeof (struct udphdr);
- data_buffer = malloc(data_length);
+ msglen = buflen + sizeof (struct ip) + sizeof (struct udphdr);
+ msgbuf = malloc(msglen);
- if (data_buffer == NULL) {
+ if (msgbuf == NULL) {
dhcpmsg(MSG_ERR, "dlpi_recvfrom: cannot allocate packet");
return (-1);
}
- data_length = dlpi_recv_link(fd, data_buffer, data_length, 0);
- if (data_length == -1)
+ rc = dlpi_recv(dh, NULL, NULL, msgbuf, &msglen, -1, &dlrecv);
+ if (rc != DLPI_SUCCESS) {
+ dhcpmsg(MSG_ERR, "dlpi_recvfrom: dlpi_recv failed: %s",
+ dlpi_strerror(rc));
+ free(msgbuf);
return (-1);
+ }
/*
* since we're just pulling data off the wire, what we have
* may look nothing like a DHCP packet. note that this
* shouldn't happen (pfmod should have tossed it already).
*/
-
- if (data_length < sizeof (struct ip) + sizeof (struct udphdr)) {
+ if (msglen < sizeof (struct ip) + sizeof (struct udphdr)) {
dhcpmsg(MSG_WARNING, "dlpi_recvfrom: dropped short packet");
- free(data_buffer);
+ free(msgbuf);
return (-1);
}
+ if (msglen < dlrecv.dri_totmsglen) {
+ dhcpmsg(MSG_WARNING, "dlpi_recvfrom: discarding stray "
+ "data on streamhead");
+ }
+
/*
* verify checksums
*/
-
- ip = (struct ip *)data_buffer;
+ ip = msgbuf;
if (ipv4cksum((uint16_t *)ip, ip->ip_hl << 2) != 0) {
dhcpmsg(MSG_WARNING, "dlpi_recvfrom: dropped packet with bad "
"ipv4 checksum");
- free(data_buffer);
+ free(msgbuf);
return (-1);
}
@@ -269,12 +116,12 @@ dlpi_recvfrom(int fd, void *buffer, size_t buf_len, struct sockaddr_in *from,
(udp_chksum(udphdr, &ip->ip_src, &ip->ip_dst, ip->ip_p) != 0)) {
dhcpmsg(MSG_WARNING, "dlpi_recvfrom: dropped packet with bad "
"UDP checksum");
- free(data_buffer);
+ free(msgbuf);
return (-1);
}
- data_length -= (sizeof (struct ip) + sizeof (struct udphdr));
- (void) memcpy(buffer, &udphdr[1], data_length);
+ msglen -= (sizeof (struct ip) + sizeof (struct udphdr));
+ (void) memcpy(buf, &udphdr[1], msglen);
if (from != NULL) {
from->sin_family = AF_INET;
@@ -288,62 +135,14 @@ dlpi_recvfrom(int fd, void *buffer, size_t buf_len, struct sockaddr_in *from,
to->sin_port = udphdr->uh_dport;
}
- free(data_buffer);
- return (data_length);
+ free(msgbuf);
+ return (msglen);
}
/*
- * dlpi_recv_link(): receives raw data on a DLPI stream
- *
- * input: int: the DLPI stream to receive the data on
- * void *: a buffer to store the data in
- * size_t: the size of the buffer
- * uint32_t: flags (see dlpi_io.h)
- * output: ssize_t: the number of bytes received on success, -1 on failure
- */
-
-ssize_t
-dlpi_recv_link(int fd, void *data_buffer, size_t data_length, uint32_t flags)
-{
- int getmsg_flags = 0;
- struct strbuf ctrl, data;
- char ctrlbuf[1024];
-
- ctrl.maxlen = sizeof (ctrlbuf);
- ctrl.buf = ctrlbuf;
-
- data.maxlen = data_length;
- data.buf = data_buffer;
-
- switch (getmsg(fd, &ctrl, &data, &getmsg_flags)) {
-
- case MORECTL:
- case MOREDATA:
- case MOREDATA|MORECTL:
-
- (void) ioctl(fd, I_FLUSH, FLUSHR);
-
- if ((flags & DLPI_RECV_SHORT) == 0)
- dhcpmsg(MSG_WARNING, "dlpi_recv_link: discarding stray "
- "data on streamhead");
- break;
-
- case -1:
- dhcpmsg(MSG_ERR, "dlpi_recv_link: getmsg");
- return (-1);
-
- default:
- break;
- }
-
- return (data.len);
-}
-
-
-/*
* dlpi_sendto(): sends UDP packets on a DLPI stream
*
- * input: int: the socket to send the packet on
+ * input: dlpi_handle_t: dlpi handle to send the packet on
* void *: a buffer to send
* size_t: the size of the buffer
* struct sockaddr_in *: the IP address to send the data to
@@ -351,16 +150,16 @@ dlpi_recv_link(int fd, void *data_buffer, size_t data_length, uint32_t flags)
* size_t: the size of the link-layer destination address
* output: ssize_t: the number of bytes sent on success, -1 on failure
*/
-
ssize_t
-dlpi_sendto(int fd, void *buffer, size_t buf_len, struct sockaddr_in *to,
- uchar_t *dl_to, size_t dl_to_len)
+dlpi_sendto(dlpi_handle_t dh, void *buf, size_t buflen,
+ struct sockaddr_in *to, uchar_t *dl_to, size_t dl_to_len)
{
struct ip *ip;
struct udphdr *udphdr;
- void *data_buffer;
- size_t data_length;
+ void *msgbuf;
+ size_t msglen;
static uint16_t ip_id = 0;
+ int rc;
/*
* TODO: someday we might want to support `to' not being
@@ -368,7 +167,6 @@ dlpi_sendto(int fd, void *buffer, size_t buf_len, struct sockaddr_in *to,
* right now, but it's annoying to have a general interface
* that only supports a specific function.
*/
-
if (to->sin_addr.s_addr != htonl(INADDR_BROADCAST)) {
dhcpmsg(MSG_ERROR, "dlpi_sendto: send to unicast address");
return (-1);
@@ -378,18 +176,17 @@ dlpi_sendto(int fd, void *buffer, size_t buf_len, struct sockaddr_in *to,
* we allocate one extra byte here in case the UDP checksum
* routine needs it to get the packet length to be even.
*/
-
- data_length = sizeof (struct ip) + sizeof (struct udphdr) + buf_len;
- data_buffer = calloc(1, data_length + 1);
- if (data_buffer == NULL) {
+ msglen = sizeof (struct ip) + sizeof (struct udphdr) + buflen;
+ msgbuf = calloc(1, msglen + 1);
+ if (msgbuf == NULL) {
dhcpmsg(MSG_ERR, "dlpi_sendto: cannot allocate packet");
return (-1);
}
- ip = (struct ip *)data_buffer;
+ ip = (struct ip *)msgbuf;
udphdr = (struct udphdr *)&ip[1];
- (void) memcpy(&udphdr[1], buffer, buf_len);
+ (void) memcpy(&udphdr[1], buf, buflen);
/*
* build the ipv4 header. assume that our source address is 0
@@ -414,97 +211,56 @@ dlpi_sendto(int fd, void *buffer, size_t buf_len, struct sockaddr_in *to,
ip->ip_id = htons(ip_id++);
ip->ip_off = htons(IP_DF);
ip->ip_p = IPPROTO_UDP;
- ip->ip_len = htons(data_length);
+ ip->ip_len = htons(msglen);
ip->ip_dst = to->sin_addr;
ip->ip_src.s_addr = htonl(INADDR_ANY);
ip->ip_sum = ipv4cksum((uint16_t *)ip, sizeof (struct ip));
- udphdr->uh_ulen = htons(sizeof (struct udphdr) + buf_len);
+ udphdr->uh_ulen = htons(sizeof (struct udphdr) + buflen);
udphdr->uh_sport = htons(IPPORT_BOOTPC);
udphdr->uh_dport = htons(IPPORT_BOOTPS);
udphdr->uh_sum = udp_chksum(udphdr, &ip->ip_src, &ip->ip_dst, ip->ip_p);
- if (dlpi_send_link(fd, data_buffer, data_length, dl_to, dl_to_len)
- == -1) {
- free(data_buffer);
- dhcpmsg(MSG_ERR, "dlpi_sendto: dlpi_send_link");
- return (-1);
- }
-
- free(data_buffer);
- return (buf_len);
-}
-
-/*
- * dlpi_send_link(): sends raw data down a DLPI stream
- *
- * input: int: the DLPI stream to send the data on
- * void *: the raw data to send
- * size_t: the size of the raw data
- * uchar_t *: the link-layer destination address
- * size_t: the size of the link-layer destination address
- * output: ssize_t: 0 on success, -1 on failure
- */
-
-ssize_t
-dlpi_send_link(int fd, void *data_buffer, size_t data_length,
- uchar_t *dest_addr, size_t dest_addr_length)
-{
- struct strbuf ctrl, data;
- ssize_t retval;
- dl_unitdata_req_t *dl_req;
-
- /*
- * allocate the control part of the message and fill it in.
- * all we really indicate is the destination address
- */
-
- dl_req = malloc(sizeof (dl_unitdata_req_t) + data_length);
- if (dl_req == NULL) {
- dhcpmsg(MSG_ERR, "dlpi_send_link: dl_unitdata_req allocation");
+ rc = dlpi_send(dh, dl_to, dl_to_len, msgbuf, msglen, NULL);
+ if (rc != DLPI_SUCCESS) {
+ free(msgbuf);
+ dhcpmsg(MSG_ERR, "dlpi_sendto: dlpi_send: %s",
+ dlpi_strerror(rc));
return (-1);
}
- ctrl.len = sizeof (dl_unitdata_req_t) + data_length;
- ctrl.buf = (caddr_t)dl_req;
-
- data.len = data_length;
- data.buf = data_buffer;
-
- dl_req->dl_primitive = DL_UNITDATA_REQ;
- dl_req->dl_priority.dl_min = 0;
- dl_req->dl_priority.dl_max = 0;
- dl_req->dl_dest_addr_offset = sizeof (dl_unitdata_req_t);
- dl_req->dl_dest_addr_length = dest_addr_length;
- (void) memcpy(&dl_req[1], dest_addr, dest_addr_length);
-
- retval = putmsg(fd, &ctrl, &data, 0);
- free(dl_req);
- return (retval);
+ free(msgbuf);
+ return (buflen);
}
/*
* set_packet_filter(): sets the current packet filter on a DLPI stream
*
- * input: int: the DLPI stream to set the packet filter on
+ * input: dlpi_handle_t: the DLPI handle to set the packet filter on
* filter_func_t *: the filter to use
* void *: an argument to pass to the filter function
* const char *: a text description of the filter's purpose
- * output: void
+ * output: boolean_t: B_TRUE on success, B_FALSE on failure.
*/
-
-void
-set_packet_filter(int fd, filter_func_t *filter, void *arg,
+boolean_t
+set_packet_filter(dlpi_handle_t dh, filter_func_t *filter, void *arg,
const char *filter_name)
{
struct strioctl sioc;
struct packetfilt pf;
ushort_t *pfp = pf.Pf_Filter;
+ int fd = dlpi_fd(dh);
+
+ if (ioctl(fd, I_PUSH, "pfmod") == -1) {
+ dhcpmsg(MSG_ERR,
+ "open_dlpi_pif: cannot push pfmod on stream");
+ return (B_FALSE);
+ }
pf.Pf_FilterLen = filter(pfp, arg) - pf.Pf_Filter;
sioc.ic_cmd = PFIOCSETF;
- sioc.ic_timout = DLPI_TIMEOUT;
+ sioc.ic_timout = FILTER_TIMEOUT;
sioc.ic_len = sizeof (struct packetfilt);
sioc.ic_dp = (caddr_t)&pf;
@@ -525,6 +281,8 @@ set_packet_filter(int fd, filter_func_t *filter, void *arg,
*/
(void) ioctl(fd, I_FLUSH, FLUSHR);
+
+ return (B_TRUE);
}
/*
@@ -583,41 +341,3 @@ dhcp_filter(ushort_t *pfp, void *arg)
return (pfp);
}
-
-/*
- * build_broadcast_dest(): builds a DLPI destination address for the broadcast
- * address for use in DL_UNITDATA_REQs
- *
- * input: dl_info_ack_t *: information about the interface
- * uchar_t *: set to the length of the returned address
- * output: uchar_t *: the broadcast address (dynamically allocated)
- */
-
-uchar_t *
-build_broadcast_dest(dl_info_ack_t *dlia, uchar_t *length)
-{
- uchar_t sap_len = abs(dlia->dl_sap_length);
- caddr_t dl_sap;
- uchar_t *dest_addr;
-
- *length = dlia->dl_brdcst_addr_length + sap_len;
- dest_addr = malloc(*length);
- if (dest_addr == NULL)
- return (NULL);
-
- if (dlia->dl_sap_length > 0) { /* sap before */
- dl_sap = (caddr_t)dlia + dlia->dl_addr_offset;
- (void) memcpy(dest_addr, dl_sap, sap_len);
- (void) memcpy(dest_addr + sap_len, (caddr_t)dlia +
- dlia->dl_brdcst_addr_offset, dlia->dl_brdcst_addr_length);
- } else {
- dl_sap = (caddr_t)dlia + dlia->dl_addr_offset +
- (dlia->dl_addr_length - sap_len);
- (void) memcpy(dest_addr, (caddr_t)dlia +
- dlia->dl_brdcst_addr_offset, dlia->dl_brdcst_addr_length);
- (void) memcpy(dest_addr + dlia->dl_brdcst_addr_length,
- dl_sap, sap_len);
- }
-
- return (dest_addr);
-}
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.h
index 0852159bac..cb8276c204 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.h
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlpi_io.h
@@ -30,47 +30,26 @@
#include <netinet/in.h>
#include <sys/types.h>
-#include <sys/dlpi.h>
+#include <libdlpi.h>
/*
* dlpi_io.[ch] contain the interface the agent uses to interact with
- * DLPI. it makes use of dlprims.c (and should be its only consumer).
- * see dlpi_io.c for documentation on how to use the exported
- * functions.
+ * DLPI for data transfer primitives. see dlpi_io.c for documentation
+ * on how to use the exported functions.
*/
#ifdef __cplusplus
extern "C" {
#endif
-/*
- * buffer size to be used in control part of DLPI messages, in bytes
- */
-#define DLPI_BUF_MAX 256
-
-/*
- * timeout to be used on DLPI-related operations, in seconds
- */
-#define DLPI_TIMEOUT 5
-
-/*
- * flags for dlpi_recv_link()
- */
-#define DLPI_RECV_SHORT 0x01 /* short reads are expected */
-
typedef ushort_t *filter_func_t(ushort_t *, void *);
filter_func_t dhcp_filter;
-uchar_t *build_broadcast_dest(dl_info_ack_t *, uchar_t *);
-void set_packet_filter(int, filter_func_t *, void *, const char *);
-int dhcp_dlpi_open(const char *, dl_info_ack_t *, size_t,
- t_uscalar_t);
-int dhcp_dlpi_close(int);
-ssize_t dlpi_recvfrom(int, void *, size_t, struct sockaddr_in *,
- struct sockaddr_in *);
-ssize_t dlpi_recv_link(int, void *, size_t, uint32_t);
-ssize_t dlpi_send_link(int, void *, size_t, uchar_t *, size_t);
-ssize_t dlpi_sendto(int, void *, size_t, struct sockaddr_in *,
+boolean_t set_packet_filter(dlpi_handle_t, filter_func_t *, void *,
+ const char *);
+ssize_t dlpi_recvfrom(dlpi_handle_t, void *, size_t,
+ struct sockaddr_in *, struct sockaddr_in *);
+ssize_t dlpi_sendto(dlpi_handle_t, void *, size_t, struct sockaddr_in *,
uchar_t *, size_t);
#ifdef __cplusplus
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c
deleted file mode 100644
index 3d0cf75273..0000000000
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1996-1999 by Sun Microsystems, Inc.
- * All rights reserved.
- *
- * heavily cannibalized from
- *
- * #ident "@(#)dlprims.c 1.12 97/03/27 SMI"
- */
-
-#pragma ident "%W% %E% SMI"
-
-/*
- * TODO: get rid of this code as soon as possible and replace it with a
- * version from a standard library. this stuff is barf-o-riffic.
- */
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/dlpi.h>
-#include <stropts.h>
-#include <sys/poll.h>
-
-#include "dlpi_io.h"
-
-static int strgetmsg(int, struct strbuf *, struct strbuf *);
-
-/*
- * dlinforeq(): issue DL_INFO_REQ and fetch DL_INFO_ACK on stream
- *
- * input: int: the stream to do the DL_INFO_REQ on
- * dl_info_ack_t: a place to store the DL_INFO_ACK
- * size_t: the size of the dl_info_ack_t
- * output: int: 0 on success, 1 on failure (errno is set)
- */
-
-int
-dlinforeq(int fd, dl_info_ack_t *infoackp, size_t infoack_size)
-{
- struct strbuf ctl;
-
- infoackp->dl_primitive = DL_INFO_REQ;
-
- ctl.maxlen = infoack_size;
- ctl.len = DL_INFO_REQ_SIZE;
- ctl.buf = (caddr_t)infoackp;
-
- if (putmsg(fd, &ctl, NULL, 0) == -1)
- return (1);
-
- if (strgetmsg(fd, &ctl, NULL) == 1)
- return (1);
-
- if (infoackp->dl_primitive != DL_INFO_ACK ||
- ctl.len < DL_INFO_ACK_SIZE) {
- errno = EPROTO;
- return (1);
- }
-
- return (0);
-}
-
-/*
- * dlattachreq(): issue DL_ATTACH_REQ and fetch DL_OK_ACK on stream
- *
- * input: int: the stream to do the DL_ATTACH_REQ on
- * t_uscalar_t: the ppa to do the attach to
- * output: int: 0 on success, 1 on failure (errno is set)
- */
-
-int
-dlattachreq(int fd, t_uscalar_t ppa)
-{
- union DL_primitives *dlp;
- uint32_t buf[DLPI_BUF_MAX / sizeof (uint32_t)];
- struct strbuf ctl;
-
- dlp = (union DL_primitives *)buf;
- dlp->attach_req.dl_primitive = DL_ATTACH_REQ;
- dlp->attach_req.dl_ppa = ppa;
-
- ctl.maxlen = sizeof (buf);
- ctl.len = DL_ATTACH_REQ_SIZE;
- ctl.buf = (caddr_t)dlp;
-
- if (putmsg(fd, &ctl, NULL, 0) == -1)
- return (1);
-
- if (strgetmsg(fd, &ctl, NULL) == 1)
- return (1);
-
- if (dlp->dl_primitive != DL_OK_ACK) {
- errno = EPROTO;
- return (1);
- }
-
- return (0);
-}
-
-/*
- * dlbindreq(): issue DL_BIND_REQ and fetch DL_BIND_ACK on stream
- *
- * input: int: the stream to do the DL_BIND_REQ on
- * t_uscalar_t: the sap to bind to
- * t_uscalar_t: the max number of outstanding DL_CONNECT_IND messages
- * uint16_t: the service mode (connectionless/connection-oriented)
- * uint16_t: whether this is a connection management stream
- * output: int: 0 on success, 1 on failure (errno is set)
- */
-
-int
-dlbindreq(int fd, t_uscalar_t sap, t_uscalar_t max_conind,
- uint16_t service_mode, uint16_t conn_mgmt)
-{
- union DL_primitives *dlp;
- uint32_t buf[DLPI_BUF_MAX / sizeof (uint32_t)];
- struct strbuf ctl;
-
- dlp = (union DL_primitives *)buf;
- dlp->bind_req.dl_primitive = DL_BIND_REQ;
- dlp->bind_req.dl_sap = sap;
- dlp->bind_req.dl_max_conind = max_conind;
- dlp->bind_req.dl_service_mode = service_mode;
- dlp->bind_req.dl_conn_mgmt = conn_mgmt;
- dlp->bind_req.dl_xidtest_flg = 0;
-
- ctl.maxlen = sizeof (buf);
- ctl.len = DL_BIND_REQ_SIZE;
- ctl.buf = (caddr_t)dlp;
-
- if (putmsg(fd, &ctl, NULL, 0) == -1)
- return (1);
-
- if (strgetmsg(fd, &ctl, NULL) == 1)
- return (1);
-
- if (dlp->dl_primitive != DL_BIND_ACK || ctl.len < DL_BIND_ACK_SIZE) {
- errno = EPROTO;
- return (1);
- }
-
- return (0);
-}
-
-/*
- * strgetmsg(): timed getmsg(3C)
- *
- * input: int: the stream to wait for the message on
- * struct strbuf *: a buffer to hold the control part of the message
- * struct strbuf *: a buffer to hold the data part of the message
- * output: int: 0 on success, 1 on failure (errno is set)
- */
-
-static int
-strgetmsg(int fd, struct strbuf *ctlp, struct strbuf *datap)
-{
- struct pollfd fds;
- int flags = 0;
- int retval;
-
- fds.fd = fd;
- fds.events = POLLIN|POLLPRI;
-
- switch (poll(&fds, 1, DLPI_TIMEOUT * 1000)) {
-
- case 0:
- errno = ETIME;
- return (1);
-
- case -1:
- return (1);
-
- default:
-
- retval = getmsg(fd, ctlp, datap, &flags);
- if (retval == -1)
- return (1);
-
- if (retval > 0 || ctlp->len < sizeof (t_uscalar_t)) {
- errno = EPROTO;
- return (1);
- }
-
- break;
- }
-
- return (0);
-}
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h
deleted file mode 100644
index 6169983c44..0000000000
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 1999 by Sun Microsystems, Inc.
- * All rights reserved.
- */
-
-#ifndef DLPRIMS_H
-#define DLPRIMS_H
-
-#pragma ident "%W% %E% SMI"
-
-#include <sys/types.h>
-#include <sys/dlpi.h>
-
-/*
- * dlprims.[ch] provide a "simpler" interface to DLPI. in truth, it's
- * rather grotesque, but for now it's the best we can do. remove this
- * file once DLPI routines are provided in a library.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int dlinforeq(int, dl_info_ack_t *, size_t);
-int dlattachreq(int, t_uscalar_t);
-int dlbindreq(int, t_uscalar_t, t_uscalar_t, uint16_t, uint16_t);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* DLPRIMS_H */
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c
index f5ed8b4a3e..708a9bce0b 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.c
@@ -28,7 +28,6 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
-#include <sys/dlpi.h>
#include <stdlib.h>
#include <sys/sockio.h>
#include <netinet/in.h>
@@ -37,10 +36,12 @@
#include <unistd.h>
#include <search.h>
#include <libdevinfo.h>
+#include <libdlpi.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <dhcpmsg.h>
#include <dhcp_inittab.h>
+#include <stropts.h>
#include "agent.h"
#include "interface.h"
@@ -88,7 +89,7 @@ insert_pif(const char *pname, boolean_t isv6, int *error)
}
pif->pif_isv6 = isv6;
- pif->pif_dlpi_fd = -1;
+ pif->pif_dlpi_hd = NULL;
pif->pif_dlpi_id = -1;
pif->pif_hold_count = 1;
pif->pif_running = B_TRUE;
@@ -102,9 +103,9 @@ insert_pif(const char *pname, boolean_t isv6, int *error)
/* We do not use DLPI with DHCPv6 */
if (!isv6) {
- uint32_t buf[DLPI_BUF_MAX / sizeof (uint32_t)];
- dl_info_ack_t *dlia = (dl_info_ack_t *)buf;
- caddr_t dl_addr;
+ int rc;
+ dlpi_handle_t dh;
+ dlpi_info_t dlinfo;
/*
* Do the allocations necessary for IPv4 DHCP.
@@ -117,15 +118,31 @@ insert_pif(const char *pname, boolean_t isv6, int *error)
*/
/* step 1 */
- pif->pif_dlpi_fd = dhcp_dlpi_open(pname, dlia, sizeof (buf),
- ETHERTYPE_IP);
- if (pif->pif_dlpi_fd == -1) {
+ if ((rc = dlpi_open(pname, &dh, 0)) != DLPI_SUCCESS) {
+ dhcpmsg(MSG_ERROR, "insert_pif: dlpi_open: %s",
+ dlpi_strerror(rc));
+ *error = DHCP_IPC_E_INVIF;
+ goto failure;
+ }
+ pif->pif_dlpi_hd = dh;
+
+ if ((rc = dlpi_bind(dh, ETHERTYPE_IP, NULL)) != DLPI_SUCCESS) {
+ dhcpmsg(MSG_ERROR, "insert_pif: dlpi_bind: %s",
+ dlpi_strerror(rc));
*error = DHCP_IPC_E_INVIF;
goto failure;
}
/* step 2 */
- pif->pif_max = dlia->dl_max_sdu;
+ rc = dlpi_info(pif->pif_dlpi_hd, &dlinfo, 0);
+ if (rc != DLPI_SUCCESS) {
+ dhcpmsg(MSG_ERROR, "insert_pif: dlpi_info: %s",
+ dlpi_strerror(rc));
+ *error = DHCP_IPC_E_INVIF;
+ goto failure;
+ }
+
+ pif->pif_max = dlinfo.di_max_sdu;
if (pif->pif_max < DHCP_DEF_MAX_SIZE) {
dhcpmsg(MSG_ERROR, "insert_pif: %s does not have a "
"large enough maximum SDU to support DHCP "
@@ -136,9 +153,8 @@ insert_pif(const char *pname, boolean_t isv6, int *error)
}
/* step 3 */
- pif->pif_hwtype = dlpi_to_arp(dlia->dl_mac_type);
- pif->pif_hwlen = dlia->dl_addr_length -
- abs(dlia->dl_sap_length);
+ pif->pif_hwtype = dlpi_arptype(dlinfo.di_mactype);
+ pif->pif_hwlen = dlinfo.di_physaddrlen;
dhcpmsg(MSG_DEBUG, "insert_pif: %s: sdumax %u, hwtype %d, "
"hwlen %d", pname, pif->pif_max, pif->pif_hwtype,
@@ -155,30 +171,24 @@ insert_pif(const char *pname, boolean_t isv6, int *error)
}
}
+ (void) memcpy(pif->pif_hwaddr, dlinfo.di_physaddr,
+ pif->pif_hwlen);
+
/*
- * depending on the DLPI device, the sap and hardware addresses
- * can be in either order within the dlsap address; find the
- * location of the hardware address using dl_sap_length. see
- * the DLPI specification for more on this braindamage.
+ * step 5
+ * Some media types has no broadcast address.
*/
-
- dl_addr = (caddr_t)dlia + dlia->dl_addr_offset;
- if (dlia->dl_sap_length > 0) {
- pif->pif_sap_before = B_TRUE;
- dl_addr += dlia->dl_sap_length;
- }
-
- (void) memcpy(pif->pif_hwaddr, dl_addr, pif->pif_hwlen);
-
- /* step 5 */
- pif->pif_saplen = abs(dlia->dl_sap_length);
- pif->pif_daddr = build_broadcast_dest(dlia, &pif->pif_dlen);
- if (pif->pif_daddr == NULL) {
- dhcpmsg(MSG_ERR, "insert_pif: cannot allocate "
- "pif_daddr for %s", pname);
- *error = DHCP_IPC_E_MEMORY;
- goto failure;
+ if ((pif->pif_dlen = dlinfo.di_bcastaddrlen) != 0) {
+ pif->pif_daddr = malloc(pif->pif_dlen);
+ if (pif->pif_daddr == NULL) {
+ dhcpmsg(MSG_ERR, "insert_pif: cannot allocate "
+ "pif_daddr for %s", pname);
+ *error = DHCP_IPC_E_MEMORY;
+ goto failure;
+ }
}
+ (void) memcpy(pif->pif_daddr, dlinfo.di_bcastaddr,
+ pif->pif_dlen);
/* Close the DLPI stream until actually needed */
close_dlpi_pif(pif);
@@ -343,22 +353,35 @@ lookup_pif_by_name(const char *pname, boolean_t isv6)
boolean_t
open_dlpi_pif(dhcp_pif_t *pif)
{
- if (pif->pif_dlpi_fd == -1) {
- uint32_t buf[DLPI_BUF_MAX / sizeof (uint32_t)];
- dl_info_ack_t *dlia = (dl_info_ack_t *)buf;
+ int rc;
+ dlpi_handle_t dh;
- pif->pif_dlpi_fd = dhcp_dlpi_open(pif->pif_name, dlia,
- sizeof (buf), ETHERTYPE_IP);
- if (pif->pif_dlpi_fd == -1)
+ if (pif->pif_dlpi_hd == NULL) {
+ if ((rc = dlpi_open(pif->pif_name, &dh, 0)) != DLPI_SUCCESS) {
+ dhcpmsg(MSG_ERROR, "open_dlpi_pif: dlpi_open: %s",
+ dlpi_strerror(rc));
return (B_FALSE);
- set_packet_filter(pif->pif_dlpi_fd, dhcp_filter, NULL, "DHCP");
- pif->pif_dlpi_id = iu_register_event(eh, pif->pif_dlpi_fd,
- POLLIN, dhcp_collect_dlpi, pif);
+ }
+
+ if ((rc = dlpi_bind(dh, ETHERTYPE_IP, NULL)) != DLPI_SUCCESS) {
+ dhcpmsg(MSG_ERROR, "open_dlpi_pif: dlpi_bind: %s",
+ dlpi_strerror(rc));
+ dlpi_close(dh);
+ return (B_FALSE);
+ }
+
+ if (!(set_packet_filter(dh, dhcp_filter, NULL, "DHCP"))) {
+ dlpi_close(dh);
+ return (B_FALSE);
+ }
+ pif->pif_dlpi_id = iu_register_event(eh, dlpi_fd(dh), POLLIN,
+ dhcp_collect_dlpi, pif);
if (pif->pif_dlpi_id == -1) {
- (void) dhcp_dlpi_close(pif->pif_dlpi_fd);
- pif->pif_dlpi_fd = -1;
+ dlpi_close(dh);
return (B_FALSE);
}
+
+ pif->pif_dlpi_hd = dh;
}
pif->pif_dlpi_count++;
return (B_TRUE);
@@ -384,9 +407,9 @@ close_dlpi_pif(dhcp_pif_t *pif)
(void) iu_unregister_event(eh, pif->pif_dlpi_id, NULL);
pif->pif_dlpi_id = -1;
}
- if (pif->pif_dlpi_fd != -1) {
- (void) dhcp_dlpi_close(pif->pif_dlpi_fd);
- pif->pif_dlpi_fd = -1;
+ if (pif->pif_dlpi_hd != NULL) {
+ dlpi_close(pif->pif_dlpi_hd);
+ pif->pif_dlpi_hd = NULL;
}
}
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h
index cc00809c8e..585ff7d41e 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/interface.h
@@ -47,6 +47,7 @@ extern "C" {
#include <netinet/dhcp.h>
#include <dhcpagent_ipc.h>
#include <libinetutil.h>
+#include <libdlpi.h>
#include "common.h"
#include "util.h"
@@ -64,24 +65,14 @@ struct dhcp_pif_s {
uchar_t pif_hwtype; /* type of link-layer */
boolean_t pif_isv6;
boolean_t pif_running; /* interface is running */
- int pif_dlpi_fd;
+ dlpi_handle_t pif_dlpi_hd; /* dlpi handle */
int pif_dlpi_count;
iu_event_id_t pif_dlpi_id; /* event id for ack/nak/offer */
uint_t pif_hold_count; /* reference count */
- /*
- * The destination address is the broadcast address of the interface,
- * in DLPI terms (which means it includes both a link-layer broadcast
- * address and a SAP, and the order depends on the requirements of the
- * underlying driver). We store it as a token like this because it's
- * generally how we need to use it.
- */
-
- uchar_t *pif_daddr; /* our destination address */
- uchar_t pif_dlen; /* our destination address len */
+ uchar_t *pif_daddr; /* our L2 destination address */
+ uchar_t pif_dlen; /* our L2 destination address len */
- uint_t pif_saplen; /* the SAP len */
- boolean_t pif_sap_before; /* does SAP come before address? */
char pif_name[LIFNAMSIZ];
};
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.c
index f61b05db20..f07b7297b0 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.c
@@ -986,7 +986,7 @@ send_pkt_internal(dhcp_smach_t *dsmp)
n_bytes = sendmsg(v6_sock_fd, &msg, 0);
} else {
if (dsmp->dsm_using_dlpi) {
- n_bytes = dlpi_sendto(pif->pif_dlpi_fd, dpkt->pkt,
+ n_bytes = dlpi_sendto(pif->pif_dlpi_hd, dpkt->pkt,
dpkt->pkt_cur_len, &dsmp->dsm_send_dest.v4,
pif->pif_daddr, pif->pif_dlen);
/* dlpi_sendto calls putmsg */
@@ -1319,15 +1319,16 @@ sock_recvpkt(int fd, PKT_LIST *plp)
/*
* recv_pkt(): receives a single DHCP packet on a given file descriptor.
*
- * input: int: the file descriptor to receive the packet
+ * input: int: if not using dlpi, the file descriptor to receive the packet
* int: the maximum packet size to allow
* boolean_t: B_TRUE for IPv6
* boolean_t: B_TRUE if using DLPI
+ * void *: if using DLPI, structure that has DLPI handle
* output: PKT_LIST *: the received packet
*/
PKT_LIST *
-recv_pkt(int fd, int mtu, boolean_t isv6, boolean_t isdlpi)
+recv_pkt(int fd, int mtu, boolean_t isv6, boolean_t isdlpi, dhcp_pif_t *arg)
{
PKT_LIST *plp;
ssize_t retval;
@@ -1355,7 +1356,9 @@ recv_pkt(int fd, int mtu, boolean_t isv6, boolean_t isdlpi)
}
} else {
if (isdlpi) {
- retval = dlpi_recvfrom(fd, plp->pkt, mtu,
+ dhcp_pif_t *pif = arg;
+
+ retval = dlpi_recvfrom(pif->pif_dlpi_hd, plp->pkt, mtu,
(struct sockaddr_in *)&plp->pktfrom,
(struct sockaddr_in *)&plp->pktto);
} else {
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.h b/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.h
index 54e52995e7..1556dced35 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.h
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/packet.h
@@ -130,7 +130,7 @@ void *add_pkt_prl(dhcp_pkt_t *, dhcp_smach_t *);
boolean_t add_pkt_lif(dhcp_pkt_t *, dhcp_lif_t *, int, const char *);
void stop_pkt_retransmission(dhcp_smach_t *);
void retransmit_now(dhcp_smach_t *);
-PKT_LIST *recv_pkt(int, int, boolean_t, boolean_t);
+PKT_LIST *recv_pkt(int, int, boolean_t, boolean_t, dhcp_pif_t *);
boolean_t pkt_v4_match(uchar_t, dhcp_message_type_t);
void pkt_smach_enqueue(dhcp_smach_t *, PKT_LIST *);
boolean_t send_pkt(dhcp_smach_t *, dhcp_pkt_t *, in_addr_t,
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
index 685e4ac921..0784096a5c 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c
@@ -971,7 +971,8 @@ dhcp_acknak_common(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
dhcp_smach_t *dsmp;
boolean_t isv6 = (fd == v6_sock_fd);
- if ((plp = recv_pkt(fd, get_max_mtu(isv6), isv6, B_FALSE)) == NULL)
+ plp = recv_pkt(fd, get_max_mtu(isv6), isv6, B_FALSE, NULL);
+ if (plp == NULL)
return;
pif = lookup_pif_by_index(plp->ifindex, isv6);
@@ -1078,7 +1079,7 @@ dhcp_acknak_lif(iu_eh_t *ehp, int fd, short events, iu_event_id_t id,
uint_t xid;
dhcp_smach_t *dsmp;
- if ((plp = recv_pkt(fd, lif->lif_max, B_FALSE, B_FALSE)) == NULL)
+ if ((plp = recv_pkt(fd, lif->lif_max, B_FALSE, B_FALSE, NULL)) == NULL)
return;
recv_type = pkt_recv_type(plp);
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c
index 8f2771c14a..e557dfd32c 100644
--- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c
+++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/select.c
@@ -238,7 +238,7 @@ failed:
* dhcp_collect_dlpi(): collects incoming OFFERs, ACKs, and NAKs via DLPI.
*
* input: iu_eh_t *: unused
- * int: the file descriptor the mesage arrived on
+ * int: unused
* short: unused
* iu_event_id_t: the id of this event callback with the handler
* void *: the physical interface that received the message
@@ -257,7 +257,7 @@ dhcp_collect_dlpi(iu_eh_t *eh, int fd, short events, iu_event_id_t id,
dhcp_smach_t *dsmp;
uint_t xid;
- if ((plp = recv_pkt(fd, pif->pif_max, B_FALSE, B_TRUE)) == NULL)
+ if ((plp = recv_pkt(fd, pif->pif_max, B_FALSE, B_TRUE, pif)) == NULL)
return;
recv_type = pkt_recv_type(plp);
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/Makefile
index 4a609825d2..8c3d0c4793 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.sbin/Makefile
@@ -146,7 +146,7 @@ $(K5PROGS) := CPPFLAGS += -I$(SRC)/head \
LDLIBS += $(K5LIBS)
$(TSNETPROG) := LDLIBS += $(ZLAZYLOAD) -ltsnet $(ZNOLAZYLOAD)
-in.rarpd := LDLIBS += -linetutil
+in.rarpd := LDLIBS += -linetutil -ldlpi
route := CPPFLAGS += -DNDEBUG
gettable in.comsat := LDFLAGS += $(MAPFILE.NGB:%=-M%)
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.rarpd.c b/usr/src/cmd/cmd-inet/usr.sbin/in.rarpd.c
index f18bb2e0cf..6a391d4b8c 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.rarpd.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.rarpd.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -48,12 +48,10 @@
#include <stdio_ext.h>
#include <stdarg.h>
#include <string.h>
-#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h>
#include <syslog.h>
-#include <signal.h>
#include <netdb.h>
#include <errno.h>
#include <sys/socket.h>
@@ -63,13 +61,12 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stropts.h>
-#include <sys/dlpi.h>
#include <libinetutil.h>
+#include <libdlpi.h>
#include <net/if_types.h>
#include <net/if_dl.h>
#define BOOTDIR "/tftpboot" /* boot files directory */
-#define DEVDIR "/dev" /* devices directory */
#define DEVIP "/dev/ip" /* path to ip driver */
#define DEVARP "/dev/arp" /* path to arp driver */
@@ -95,12 +92,12 @@ struct ifdev {
* Physical network device
*/
struct rarpdev {
- char device[IFNAMSIZ];
- int unit;
- int fd;
- uchar_t *lladdr; /* mac address of interface */
- int ifaddrlen; /* mac address length */
- int ifsaplen; /* indicates dlsap format */
+ char device[DLPI_LINKNAME_MAX];
+ uint_t unit;
+ dlpi_handle_t dh_rarp;
+ uchar_t physaddr[DLPI_PHYSADDR_MAX];
+ /* mac address of interface */
+ uint_t physaddrlen; /* mac address length */
int ifrarplen; /* size of rarp data packet */
struct ifdev *ifdev; /* private interface info */
struct rarpdev *next; /* list of managed devices */
@@ -127,7 +124,6 @@ static struct rarpdev *rarpdev_head;
static char *cmdname; /* command name from argv[0] */
static int dflag = 0; /* enable diagnostics */
static int aflag = 0; /* start rarpd on all interfaces */
-static char *alarmmsg; /* alarm() error message */
static void getintf(void);
static struct rarpdev *find_device(ifspec_t *);
@@ -137,18 +133,16 @@ static void rarp_request(struct rarpdev *, struct arphdr *,
uchar_t *);
static void add_arp(struct rarpdev *, uchar_t *, uchar_t *);
static void arp_request(struct rarpdev *, struct arphdr *, uchar_t *);
-static int rarp_open(struct rarpdev *, ushort_t);
static void do_delay_write(void *);
static void delay_write(struct rarpdev *, struct rarpreply *);
-static int rarp_write(int, struct rarpreply *);
static int mightboot(ipaddr_t);
static void get_ifdata(char *, int, ipaddr_t *, ipaddr_t *);
static int get_ipaddr(struct rarpdev *, uchar_t *, uchar_t *, ipaddr_t *);
-static void sigalarm(int);
static int strioctl(int, int, int, int, char *);
static void usage();
-static void syserr(char *);
-static void error(char *, ...);
+static void syserr(const char *);
+/*PRINTFLIKE1*/
+static void error(const char *, ...);
static void debug(char *, ...);
extern int optind;
@@ -180,7 +174,7 @@ main(int argc, char *argv[])
}
if ((!aflag && (argc - optind) != 2) ||
- (aflag && (argc - optind) != 0)) {
+ (aflag && (argc - optind) != 0)) {
usage();
/* NOTREACHED */
}
@@ -223,7 +217,7 @@ main(int argc, char *argv[])
if (aflag) {
/*
- * Get each interface name and load rarpdev list
+ * Get each interface name and load rarpdev list.
*/
getintf();
} else {
@@ -232,10 +226,10 @@ main(int argc, char *argv[])
char buf[IFNAMSIZ + 1];
/*
- * Load specified device as only element of the list
+ * Load specified device as only element of the list.
*/
rarpdev_head = (struct rarpdev *)calloc(1,
- sizeof (struct rarpdev));
+ sizeof (struct rarpdev));
if (rarpdev_head == NULL) {
error("out of memory");
}
@@ -255,8 +249,9 @@ main(int argc, char *argv[])
sizeof (ifdev->ldevice), "%s%d:",
ifsp.ifsp_devnm, ifsp.ifsp_ppa);
ifdev->lunit = ifsp.ifsp_lun;
- } else
+ } else {
ifdev->lunit = -1; /* no logical unit */
+ }
(void) strlcpy(rarpdev_head->device, ifsp.ifsp_devnm,
sizeof (rarpdev_head->device));
rarpdev_head->unit = ifsp.ifsp_ppa;
@@ -266,7 +261,7 @@ main(int argc, char *argv[])
}
/*
- * Initialize each rarpdev
+ * Initialize each rarpdev.
*/
for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) {
init_rarpdev(rdev);
@@ -277,16 +272,16 @@ main(int argc, char *argv[])
(void) mutex_init(&debug_mutex, USYNC_THREAD, NULL);
/*
- * Start delayed processing thread
+ * Start delayed processing thread.
*/
(void) thr_create(NULL, NULL, (void *(*)(void *))do_delay_write, NULL,
THR_NEW_LWP, NULL);
/*
- * Start RARP processing for each device
+ * Start RARP processing for each device.
*/
for (rdev = rarpdev_head; rdev != NULL; rdev = rdev->next) {
- if (rdev->fd != -1) {
+ if (rdev->dh_rarp != NULL) {
(void) thr_create(NULL, NULL,
(void *(*)(void *))do_rarp, (void *)rdev,
THR_NEW_LWP, NULL);
@@ -337,7 +332,7 @@ getintf(void)
syserr("SIOCGIFCONF");
/*
- * Initialize a rarpdev for each interface
+ * Initialize a rarpdev for each interface.
*/
for (ifr = ifconf.ifc_req; ifconf.ifc_len > 0;
ifr++, ifconf.ifc_len -= sizeof (struct ifreq)) {
@@ -358,7 +353,7 @@ getintf(void)
error("ifparse_ifspec failed");
/*
- * Look for an existing device for logical interfaces
+ * Look for an existing device for logical interfaces.
*/
if ((rdev = find_device(&ifsp)) == NULL) {
rdev = calloc(1, sizeof (struct rarpdev));
@@ -406,30 +401,64 @@ find_device(ifspec_t *specp)
static void
init_rarpdev(struct rarpdev *rdev)
{
- char *dev;
- int unit;
- struct ifdev *ifdev;
-
+ char *dev;
+ int unit;
+ struct ifdev *ifdev;
+ int retval;
+ char *str = NULL;
+ uint_t physaddrlen = DLPI_PHYSADDR_MAX;
+ char linkname[DLPI_LINKNAME_MAX];
+ dlpi_handle_t dh;
+
+ (void) snprintf(linkname, DLPI_LINKNAME_MAX, "%s%d", rdev->device,
+ rdev->unit);
/*
* Open datalink provider and get our mac address.
*/
- rdev->fd = rarp_open(rdev, ETHERTYPE_REVARP);
+ if ((retval = dlpi_open(linkname, &dh, 0)) != DLPI_SUCCESS) {
+ error("cannot open link %s: %s", linkname,
+ dlpi_strerror(retval));
+ }
+
+ if ((retval = dlpi_bind(dh, ETHERTYPE_REVARP, NULL)) != DLPI_SUCCESS) {
+ dlpi_close(dh);
+ error("dlpi_bind failed: %s", dlpi_strerror(retval));
+ }
/*
- * rarp_open may fail on certain types of interfaces
+ * Save our mac address.
*/
- if (rdev->fd < 0) {
- rdev->fd = -1;
- return;
+ if ((retval = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, rdev->physaddr,
+ &physaddrlen)) != DLPI_SUCCESS) {
+ dlpi_close(dh);
+ error("dlpi_get_physaddr failed: %s", dlpi_strerror(retval));
+ }
+
+ rdev->physaddrlen = physaddrlen;
+ rdev->ifrarplen = sizeof (struct arphdr) + (2 * sizeof (ipaddr_t)) +
+ (2 * physaddrlen);
+
+ if (dflag) {
+ str = _link_ntoa(rdev->physaddr, str,
+ rdev->physaddrlen, IFT_OTHER);
+ if (str != NULL) {
+ debug("device %s physical address %s", linkname, str);
+ free(str);
+ }
}
/*
+ * Assign dlpi handle to rdev.
+ */
+ rdev->dh_rarp = dh;
+
+ /*
* Get the IP address and netmask from directory service for
* each logical interface.
*/
for (ifdev = rdev->ifdev; ifdev != NULL; ifdev = ifdev->next) {
/*
- * If lunit == -1 then this is the primary interface name
+ * If lunit == -1 then this is the primary interface name.
*/
if (ifdev->lunit == -1) {
dev = rdev->device;
@@ -451,102 +480,63 @@ init_rarpdev(struct rarpdev *rdev)
static void
do_rarp(void *buf)
{
- struct rarpdev *rdev = (struct rarpdev *)buf;
- struct strbuf ctl;
- char ctlbuf[BUFSIZE];
- struct strbuf data;
- char databuf[BUFSIZE];
+ struct rarpdev *rdev = buf;
char *cause;
struct arphdr *ans;
- uchar_t *shost;
- int flags, ret;
- union DL_primitives *dlp;
- uchar_t *laddrp;
+ uchar_t *shost;
+ uint_t saddrlen;
+ size_t anslen = rdev->ifrarplen;
char *str = NULL;
+ int retval;
- /*
- * Sanity check; if we hit this limit, ctlbuf/databuf needs
- * to be malloc'ed.
- */
- if ((sizeof (ctlbuf) < (DL_UNITDATA_IND_SIZE + rdev->ifaddrlen)) ||
- (sizeof (databuf) < rdev->ifrarplen))
- error("unsupported media");
-
- if (((shost = (uchar_t *)malloc(rdev->ifaddrlen)) == NULL) ||
- ((ans = (struct arphdr *)malloc(rdev->ifrarplen)) == NULL))
+ if (((shost = malloc(rdev->physaddrlen)) == NULL) ||
+ ((ans = malloc(rdev->ifrarplen)) == NULL))
syserr("malloc");
if (dflag) {
- str = _link_ntoa(rdev->lladdr, str, rdev->ifaddrlen, IFT_OTHER);
+ str = _link_ntoa(rdev->physaddr, str, rdev->physaddrlen,
+ IFT_OTHER);
if (str != NULL) {
- debug("starting rarp service on device %s%d address %s",
- rdev->device, rdev->unit, str);
+ debug("starting rarp service on device %s%d physical"
+ " address %s", rdev->device, rdev->unit, str);
free(str);
}
}
/*
- * read RARP packets and respond to them.
+ * Read RARP packets and respond to them.
*/
for (;;) {
- ctl.len = 0;
- ctl.maxlen = BUFSIZE;
- ctl.buf = ctlbuf;
- data.len = 0;
- data.maxlen = BUFSIZE;
- data.buf = databuf;
- flags = 0;
-
- if ((ret = getmsg(rdev->fd, &ctl, &data, &flags)) < 0)
- syserr("getmsg");
-
- /*
- * Validate DL_UNITDATA_IND.
- */
- /* LINTED pointer */
- dlp = (union DL_primitives *)ctlbuf;
-
- (void) memcpy(ans, databuf, rdev->ifrarplen);
+ saddrlen = DLPI_PHYSADDR_MAX;
+ retval = dlpi_recv(rdev->dh_rarp, shost,
+ &saddrlen, ans, &anslen, -1, NULL);
+ if (retval == DLPI_ETIMEDOUT) {
+ continue;
+ } else if (retval != DLPI_SUCCESS) {
+ error("error in dlpi_recv %s: %s", rdev->dh_rarp,
+ dlpi_strerror(retval));
+ }
cause = NULL;
- if (ctl.len == 0)
- cause = "missing control part of message";
- else if (ctl.len < 0)
- cause = "short control part of message";
- else if (dlp->dl_primitive != DL_UNITDATA_IND)
- cause = "not unitdata_ind";
- else if (ret & MORECTL)
- cause = "MORECTL flag";
- else if (ret & MOREDATA)
- cause = "MOREDATA flag";
- else if (ctl.len < DL_UNITDATA_IND_SIZE)
- cause = "short unitdata_ind";
- else if (data.len < rdev->ifrarplen)
- cause = "short arp";
+
+ if (anslen < rdev->ifrarplen)
+ cause = "short packet";
else if (ans->ar_hrd != htons(ARPHRD_ETHER))
- cause = "hrd";
+ cause = "hardware type not Ethernet";
else if (ans->ar_pro != htons(ETHERTYPE_IP))
- cause = "pro";
- else if (ans->ar_hln != rdev->ifaddrlen)
- cause = "hln";
+ cause = "protocol type not IP";
+ else if (ans->ar_hln != rdev->physaddrlen)
+ cause = "unexpected hardware address length";
else if (ans->ar_pln != sizeof (ipaddr_t))
- cause = "pln";
- if (cause) {
+ cause = "unexpected protocol address length";
+ if (cause != NULL) {
if (dflag)
- debug("receive check failed: cause: %s",
- cause);
+ debug("RARP packet received but "
+ "discarded: %s", cause);
continue;
}
/*
- * Good request.
- * Pick out the mac source address of this RARP request.
- */
- laddrp = (uchar_t *)ctlbuf +
- dlp->unitdata_ind.dl_src_addr_offset;
- (void) memcpy(shost, laddrp, ans->ar_hln);
-
- /*
* Handle the request.
*/
switch (ntohs(ans->ar_op)) {
@@ -574,7 +564,6 @@ do_rarp(void *buf)
break;
}
}
- /* NOTREACHED */
}
/*
@@ -587,6 +576,7 @@ rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
struct rarpreply *rrp;
uchar_t *shap, *thap, *spap, *tpap;
char *str = NULL;
+ int retval;
shap = (uchar_t *)rp + sizeof (struct arphdr);
spap = shap + rp->ar_hln;
@@ -594,7 +584,7 @@ rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
tpap = thap + rp->ar_hln;
if (dflag) {
- str = _link_ntoa(thap, str, rdev->ifaddrlen, IFT_OTHER);
+ str = _link_ntoa(thap, str, rdev->physaddrlen, IFT_OTHER);
if (str != NULL) {
debug("RARP_REQUEST for %s", str);
free(str);
@@ -602,22 +592,22 @@ rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
}
/*
- * third party lookups are rare and wonderful
+ * Third party lookups are rare and wonderful.
*/
- if ((memcmp(shap, thap, rdev->ifaddrlen) != 0) ||
- (memcmp(shap, shost, rdev->ifaddrlen) != 0)) {
+ if ((memcmp(shap, thap, rdev->physaddrlen) != 0) ||
+ (memcmp(shap, shost, rdev->physaddrlen) != 0)) {
if (dflag)
debug("weird (3rd party lookup)");
}
/*
- * fill in given parts of reply packet
+ * Fill in given parts of reply packet.
*/
- (void) memcpy(shap, rdev->lladdr, rdev->ifaddrlen);
+ (void) memcpy(shap, rdev->physaddr, rdev->physaddrlen);
/*
* If a good address is stored in our lookup tables, return it
- * immediately or after a delay. Store it our kernel's ARP cache.
+ * immediately or after a delay. Store it in our kernel's ARP cache.
*/
if (get_ipaddr(rdev, thap, tpap, &spa))
return;
@@ -634,12 +624,12 @@ rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
debug("good lookup, maps to %s", inet_ntoa(addr));
}
- rrp = (struct rarpreply *)calloc(1, sizeof (struct rarpreply) +
- rdev->ifaddrlen + rdev->ifrarplen);
+ rrp = calloc(1, sizeof (struct rarpreply) + rdev->physaddrlen +
+ rdev->ifrarplen);
if (rrp == NULL)
error("out of memory");
rrp->lldest = (uchar_t *)rrp + sizeof (struct rarpreply);
- rrp->arprep = rrp->lldest + rdev->ifaddrlen;
+ rrp->arprep = rrp->lldest + rdev->physaddrlen;
/*
* Create rarpreply structure.
@@ -647,7 +637,7 @@ rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
(void) gettimeofday(&rrp->tv, NULL);
rrp->tv.tv_sec += 3; /* delay */
rrp->rdev = rdev;
- (void) memcpy(rrp->lldest, shost, rdev->ifaddrlen);
+ (void) memcpy(rrp->lldest, shost, rdev->physaddrlen);
(void) memcpy(rrp->arprep, rp, rdev->ifrarplen);
/*
@@ -656,10 +646,13 @@ rarp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
*/
(void) memcpy(&tpa, tpap, sizeof (ipaddr_t));
if (mightboot(ntohl(tpa))) {
- if (rarp_write(rdev->fd, rrp) < 0)
- syslog(LOG_ERR, "Bad rarp_write: %m");
- if (dflag)
+ retval = dlpi_send(rdev->dh_rarp, rrp->lldest,
+ rdev->physaddrlen, rrp->arprep, rdev->ifrarplen, NULL);
+ if (retval != DLPI_SUCCESS) {
+ error("dlpi_send failed: %s", dlpi_strerror(retval));
+ } else if (dflag) {
debug("immediate reply sent");
+ }
(void) free(rrp);
} else {
delay_write(rdev, rrp);
@@ -677,7 +670,7 @@ add_arp(struct rarpdev *rdev, uchar_t *ip, uchar_t *laddr)
int fd;
/*
- * Common part of query or set
+ * Common part of query or set.
*/
(void) memset(&ar, 0, sizeof (ar));
ar.xarp_pa.ss_family = AF_INET;
@@ -691,10 +684,10 @@ add_arp(struct rarpdev *rdev, uchar_t *ip, uchar_t *laddr)
syserr(DEVARP);
/*
- * Set the entry
+ * Set the entry.
*/
- (void) memcpy(LLADDR(&ar.xarp_ha), laddr, rdev->ifaddrlen);
- ar.xarp_ha.sdl_alen = rdev->ifaddrlen;
+ (void) memcpy(LLADDR(&ar.xarp_ha), laddr, rdev->physaddrlen);
+ ar.xarp_ha.sdl_alen = rdev->physaddrlen;
ar.xarp_ha.sdl_family = AF_LINK;
(void) strioctl(fd, SIOCDXARP, -1, sizeof (struct xarpreq),
(char *)&ar);
@@ -716,7 +709,7 @@ arp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
struct rarpreply *rrp;
struct ifdev *ifdev;
uchar_t *shap, *thap, *spap, *tpap;
- int ret;
+ int retval;
shap = (uchar_t *)rp + sizeof (struct arphdr);
spap = shap + rp->ar_hln;
@@ -734,321 +727,31 @@ arp_request(struct rarpdev *rdev, struct arphdr *rp, uchar_t *shost)
return;
rp->ar_op = ARPOP_REPLY;
- (void) memcpy(shap, rdev->lladdr, rdev->ifaddrlen);
+ (void) memcpy(shap, rdev->physaddr, rdev->physaddrlen);
(void) memcpy(spap, &ifdev->ipaddr, sizeof (ipaddr_t));
- (void) memcpy(thap, rdev->lladdr, rdev->ifaddrlen);
+ (void) memcpy(thap, rdev->physaddr, rdev->physaddrlen);
add_arp(rdev, tpap, thap);
/*
* Create rarp reply structure.
*/
- rrp = (struct rarpreply *)calloc(1, sizeof (struct rarpreply) +
- rdev->ifaddrlen + rdev->ifrarplen);
+ rrp = calloc(1, sizeof (struct rarpreply) + rdev->physaddrlen +
+ rdev->ifrarplen);
if (rrp == NULL)
error("out of memory");
rrp->lldest = (uchar_t *)rrp + sizeof (struct rarpreply);
- rrp->arprep = rrp->lldest + rdev->ifaddrlen;
+ rrp->arprep = rrp->lldest + rdev->physaddrlen;
rrp->rdev = rdev;
- (void) memcpy(rrp->lldest, shost, rdev->ifaddrlen);
+ (void) memcpy(rrp->lldest, shost, rdev->physaddrlen);
(void) memcpy(rrp->arprep, rp, rdev->ifrarplen);
- ret = rarp_write(rdev->fd, rrp);
+ retval = dlpi_send(rdev->dh_rarp, rrp->lldest, rdev->physaddrlen,
+ rrp->arprep, rdev->ifrarplen, NULL);
free(rrp);
- if (ret < 0)
- error("rarp_write error");
-}
-
-/*
- * OPEN the datalink provider device, ATTACH to the unit,
- * and BIND to the revarp type.
- * Return the resulting descriptor.
- *
- * MT-UNSAFE
- */
-static int
-rarp_open(struct rarpdev *rarpdev, ushort_t type)
-{
- register int fd;
- char path[MAXPATHL];
- union DL_primitives *dlp;
- char buf[BUFSIZE];
- struct strbuf ctl;
- int flags;
- uchar_t *eap;
- char *device = rarpdev->device;
- int unit = rarpdev->unit;
- char *str = NULL;
-
- /*
- * Prefix the device name with "/dev/" if it doesn't
- * start with a "/" .
- */
- if (*device == '/')
- (void) snprintf(path, sizeof (path), "%s", device);
- else
- (void) snprintf(path, sizeof (path), "%s/%s", DEVDIR, device);
-
- /*
- * Open the datalink provider.
- */
- if ((fd = open(path, O_RDWR)) < 0)
- syserr(path);
-
- /*
- * Issue DL_INFO_REQ and check DL_INFO_ACK for sanity.
- */
- /* LINTED pointer */
- dlp = (union DL_primitives *)buf;
- dlp->info_req.dl_primitive = DL_INFO_REQ;
-
- ctl.buf = (char *)dlp;
- ctl.len = DL_INFO_REQ_SIZE;
-
- if (putmsg(fd, &ctl, NULL, 0) < 0)
- syserr("putmsg");
-
- (void) signal(SIGALRM, sigalarm);
-
- alarmmsg = "DL_INFO_REQ failed: timeout waiting for DL_INFO_ACK";
- (void) alarm(10);
-
- ctl.buf = (char *)dlp;
- ctl.len = 0;
- ctl.maxlen = BUFSIZE;
- flags = 0;
- if (getmsg(fd, &ctl, NULL, &flags) < 0)
- syserr("getmsg");
-
- (void) alarm(0);
- (void) signal(SIGALRM, SIG_DFL);
-
- /*
- * Validate DL_INFO_ACK reply.
- */
- if (ctl.len < sizeof (ulong_t))
- error("DL_INFO_REQ failed: short reply to DL_INFO_REQ");
-
- if (dlp->dl_primitive != DL_INFO_ACK)
- error("DL_INFO_REQ failed: dl_primitive 0x%lx received",
- dlp->dl_primitive);
-
- if (ctl.len < DL_INFO_ACK_SIZE)
- error("DL_INFO_REQ failed: short info_ack: %d bytes",
- ctl.len);
-
- if (dlp->info_ack.dl_version != DL_VERSION_2)
- error("DL_INFO_ACK: incompatible version: %lu",
- dlp->info_ack.dl_version);
-
- if (dlp->info_ack.dl_sap_length != -2) {
- if (dflag)
- debug(
-"%s%d DL_INFO_ACK: incompatible dl_sap_length: %ld",
- device, unit, dlp->info_ack.dl_sap_length);
- (void) close(fd);
- return (-1);
- }
-
- if ((dlp->info_ack.dl_service_mode & DL_CLDLS) == 0) {
- if (dflag)
- debug(
-"%s%d DL_INFO_ACK: incompatible dl_service_mode: 0x%lx",
- device, unit, dlp->info_ack.dl_service_mode);
- (void) close(fd);
- return (-1);
- }
-
- rarpdev->ifsaplen = dlp->info_ack.dl_sap_length;
- rarpdev->ifaddrlen = dlp->info_ack.dl_addr_length -
- abs(rarpdev->ifsaplen);
- rarpdev->ifrarplen = sizeof (struct arphdr) +
- (2 * sizeof (ipaddr_t)) + (2 * rarpdev->ifaddrlen);
-
- /*
- * Issue DL_ATTACH_REQ.
- */
- /* LINTED pointer */
- dlp = (union DL_primitives *)buf;
- dlp->attach_req.dl_primitive = DL_ATTACH_REQ;
- dlp->attach_req.dl_ppa = unit;
-
- ctl.buf = (char *)dlp;
- ctl.len = DL_ATTACH_REQ_SIZE;
-
- if (putmsg(fd, &ctl, NULL, 0) < 0)
- syserr("putmsg");
-
- (void) signal(SIGALRM, sigalarm);
- alarmmsg = "DL_ATTACH_REQ failed: timeout waiting for DL_OK_ACK";
-
- (void) alarm(10);
-
- ctl.buf = (char *)dlp;
- ctl.len = 0;
- ctl.maxlen = BUFSIZE;
- flags = 0;
- if (getmsg(fd, &ctl, NULL, &flags) < 0)
- syserr("getmsg");
-
- (void) alarm(0);
- (void) signal(SIGALRM, SIG_DFL);
-
- /*
- * Validate DL_OK_ACK reply.
- */
- if (ctl.len < sizeof (ulong_t))
- error("DL_ATTACH_REQ failed: short reply to attach request");
-
- if (dlp->dl_primitive == DL_ERROR_ACK)
- error("DL_ATTACH_REQ failed: dl_errno %lu unix_errno %lu",
- dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno);
-
- if (dlp->dl_primitive != DL_OK_ACK)
- error("DL_ATTACH_REQ failed: dl_primitive 0x%lx received",
- dlp->dl_primitive);
-
- if (ctl.len < DL_OK_ACK_SIZE)
- error("attach failed: short ok_ack: %d bytes",
- ctl.len);
-
- /*
- * Issue DL_BIND_REQ.
- */
- /* LINTED pointer */
- dlp = (union DL_primitives *)buf;
- dlp->bind_req.dl_primitive = DL_BIND_REQ;
- dlp->bind_req.dl_sap = type;
- dlp->bind_req.dl_max_conind = 0;
- dlp->bind_req.dl_service_mode = DL_CLDLS;
- dlp->bind_req.dl_conn_mgmt = 0;
- dlp->bind_req.dl_xidtest_flg = 0;
-
- ctl.buf = (char *)dlp;
- ctl.len = DL_BIND_REQ_SIZE;
-
- if (putmsg(fd, &ctl, NULL, 0) < 0)
- syserr("putmsg");
-
- (void) signal(SIGALRM, sigalarm);
-
- alarmmsg = "DL_BIND_REQ failed: timeout waiting for DL_BIND_ACK";
- (void) alarm(10);
-
- ctl.buf = (char *)dlp;
- ctl.len = 0;
- ctl.maxlen = BUFSIZE;
- flags = 0;
- if (getmsg(fd, &ctl, NULL, &flags) < 0)
- syserr("getmsg");
-
- (void) alarm(0);
- (void) signal(SIGALRM, SIG_DFL);
-
- /*
- * Validate DL_BIND_ACK reply.
- */
- if (ctl.len < sizeof (ulong_t))
- error("DL_BIND_REQ failed: short reply");
-
- if (dlp->dl_primitive == DL_ERROR_ACK)
- error("DL_BIND_REQ failed: dl_errno %lu unix_errno %lu",
- dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno);
-
- if (dlp->dl_primitive != DL_BIND_ACK)
- error("DL_BIND_REQ failed: dl_primitive 0x%lx received",
- dlp->dl_primitive);
-
- if (ctl.len < DL_BIND_ACK_SIZE)
- error(
-"DL_BIND_REQ failed: short bind acknowledgement received");
-
- if (dlp->bind_ack.dl_sap != type)
- error(
-"DL_BIND_REQ failed: returned dl_sap %lu != requested sap %d",
- dlp->bind_ack.dl_sap, type);
-
- /*
- * Issue DL_PHYS_ADDR_REQ to get our local mac address.
- */
- /* LINTED pointer */
- dlp = (union DL_primitives *)buf;
- dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ;
- dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR;
-
- ctl.buf = (char *)dlp;
- ctl.len = DL_PHYS_ADDR_REQ_SIZE;
-
- if (putmsg(fd, &ctl, NULL, 0) < 0)
- syserr("putmsg");
-
- (void) signal(SIGALRM, sigalarm);
-
- alarmmsg =
- "DL_PHYS_ADDR_REQ failed: timeout waiting for DL_PHYS_ADDR_ACK";
- (void) alarm(10);
-
- ctl.buf = (char *)dlp;
- ctl.len = 0;
- ctl.maxlen = BUFSIZE;
- flags = 0;
- if (getmsg(fd, &ctl, NULL, &flags) < 0)
- syserr("getmsg");
-
- (void) alarm(0);
- (void) signal(SIGALRM, SIG_DFL);
-
- /*
- * Validate DL_PHYS_ADDR_ACK reply.
- */
- if (ctl.len < sizeof (ulong_t))
- error("DL_PHYS_ADDR_REQ failed: short reply");
-
- if (dlp->dl_primitive == DL_ERROR_ACK)
- error("DL_PHYS_ADDR_REQ failed: dl_errno %lu unix_errno %lu",
- dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno);
-
- if (dlp->dl_primitive != DL_PHYS_ADDR_ACK)
- error("DL_PHYS_ADDR_REQ failed: dl_primitive 0x%lx received",
- dlp->dl_primitive);
-
- if (ctl.len < DL_PHYS_ADDR_ACK_SIZE)
- error("DL_PHYS_ADDR_REQ failed: short ack received");
-
- if (dlp->physaddr_ack.dl_addr_length != rarpdev->ifaddrlen) {
- if (dflag)
- debug(
-"%s%d DL_PHYS_ADDR_ACK failed: incompatible dl_addr_length: %lu",
- device, unit, dlp->physaddr_ack.dl_addr_length);
- (void) close(fd);
- return (-1);
- }
-
- /*
- * Save our mac address.
- */
- if ((rarpdev->lladdr = (uchar_t *)malloc(rarpdev->ifaddrlen)) == NULL) {
- if (dflag)
- debug(" %s%d malloc failed: %d bytes", device,
- unit, rarpdev->ifaddrlen);
- (void) close(fd);
- return (-1);
- }
-
- eap = (uchar_t *)dlp + dlp->physaddr_ack.dl_addr_offset;
- (void) memcpy(rarpdev->lladdr, eap, dlp->physaddr_ack.dl_addr_length);
-
- if (dflag) {
- str = _link_ntoa(rarpdev->lladdr, str, rarpdev->ifaddrlen,
- IFT_OTHER);
- if (str != NULL) {
- debug("device %s%d lladdress %s", device, unit, str);
- free(str);
- }
- }
-
- return (fd);
+ if (retval != DLPI_SUCCESS)
+ error("dlpi_send failed: %s", dlpi_strerror(retval));
}
/* ARGSUSED */
@@ -1057,6 +760,7 @@ do_delay_write(void *buf)
{
struct timeval tv;
struct rarpreply *rrp;
+ struct rarpdev *rdev;
int err;
for (;;) {
@@ -1068,6 +772,7 @@ do_delay_write(void *buf)
(void) mutex_lock(&delay_mutex);
rrp = delay_list;
+ rdev = rrp->rdev;
delay_list = delay_list->next;
(void) mutex_unlock(&delay_mutex);
@@ -1075,12 +780,13 @@ do_delay_write(void *buf)
if (tv.tv_sec < rrp->tv.tv_sec)
(void) sleep(rrp->tv.tv_sec - tv.tv_sec);
- if (rarp_write(rrp->rdev->fd, rrp) < 0)
- error("rarp_write error");
+ err = dlpi_send(rdev->dh_rarp, rrp->lldest, rdev->physaddrlen,
+ rrp->arprep, rdev->ifrarplen, NULL);
+ if (err != DLPI_SUCCESS)
+ error("dlpi_send failed: %s", dlpi_strerror(err));
(void) free(rrp);
}
- /* NOTREACHED */
}
/* ARGSUSED */
@@ -1103,43 +809,6 @@ delay_write(struct rarpdev *rdev, struct rarpreply *rrp)
(void) sema_post(&delay_sema);
}
-static int
-rarp_write(int fd, struct rarpreply *rrp)
-{
- struct strbuf ctl, data;
- union DL_primitives *dlp;
- char ctlbuf[BUFSIZE];
- ushort_t etype = ETHERTYPE_REVARP;
- int ifaddrlen = rrp->rdev->ifaddrlen;
-
- /*
- * Construct DL_UNITDATA_REQ.
- */
- /* LINTED pointer */
- dlp = (union DL_primitives *)ctlbuf;
- ctl.len = DL_UNITDATA_REQ_SIZE + ifaddrlen + abs(rrp->rdev->ifsaplen);
- ctl.buf = ctlbuf;
- data.len = rrp->rdev->ifrarplen;
- data.buf = (char *)rrp->arprep;
- if (ctl.len > sizeof (ctlbuf))
- return (-1);
-
- dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ;
- dlp->unitdata_req.dl_dest_addr_length = ifaddrlen +
- abs(rrp->rdev->ifsaplen);
- dlp->unitdata_req.dl_dest_addr_offset = DL_UNITDATA_REQ_SIZE;
- dlp->unitdata_req.dl_priority.dl_min = 0;
- dlp->unitdata_req.dl_priority.dl_max = 0;
- (void) memcpy(ctlbuf + DL_UNITDATA_REQ_SIZE, rrp->lldest, ifaddrlen);
- (void) memcpy(ctlbuf + DL_UNITDATA_REQ_SIZE + ifaddrlen, &etype,
- sizeof (etype));
-
- /*
- * Send DL_UNITDATA_REQ.
- */
- return (putmsg(fd, &ctl, &data, 0));
-}
-
/*
* See if we have a TFTP boot file for this guy. Filenames in TFTP
* boot requests are of the form <ipaddr> for Sun-3's and of the form
@@ -1180,7 +849,7 @@ mightboot(ipaddr_t ipa)
(void) closedir(dirp);
- return (dp? 1: 0);
+ return ((dp != NULL) ? 1 : 0);
}
/*
@@ -1207,25 +876,25 @@ get_ifdata(char *dev, int unit, ipaddr_t *ipp, ipaddr_t *maskp)
*/
(void) snprintf(ifr.ifr_name, sizeof (ifr.ifr_name), "%s%d", dev, unit);
if (strioctl(fd, SIOCGIFADDR, -1, sizeof (struct ifreq),
- (char *)&ifr) < 0)
+ (char *)&ifr) < 0)
syserr("SIOCGIFADDR");
*ipp = (ipaddr_t)ntohl(sin->sin_addr.s_addr);
if (dflag)
- debug("device %s%d address %s",
- dev, unit, inet_ntoa(sin->sin_addr));
+ debug("device %s%d address %s", dev, unit,
+ inet_ntoa(sin->sin_addr));
/*
* Ask IP for our netmask.
*/
if (strioctl(fd, SIOCGIFNETMASK, -1, sizeof (struct ifreq),
- (char *)&ifr) < 0)
+ (char *)&ifr) < 0)
syserr("SIOCGIFNETMASK");
*maskp = (ipaddr_t)ntohl(sin->sin_addr.s_addr);
if (dflag)
- debug("device %s%d subnet mask %s",
- dev, unit, inet_ntoa(sin->sin_addr));
+ debug("device %s%d subnet mask %s", dev, unit,
+ inet_ntoa(sin->sin_addr));
/*
* Thankyou ip.
@@ -1248,16 +917,15 @@ get_ipaddr(struct rarpdev *rdev, uchar_t *laddr, uchar_t *ipp, ipaddr_t *ipaddr)
char **p;
struct ifdev *ifdev;
- if (rdev->ifaddrlen != ETHERADDRL) {
+ if (rdev->physaddrlen != ETHERADDRL) {
if (dflag)
- debug("%s %s", " can not map non 6 byte hardware ",
+ debug("%s %s", " cannot map non 6 byte hardware ",
"address to IP address");
return (1);
}
/*
- * Translate mac address to hostname
- * and IP address.
+ * Translate mac address to hostname and IP address.
*/
if (ether_ntohost(host, (struct ether_addr *)laddr) != 0 ||
!(hp = gethostbyname_r(host, &res, hbuffer, sizeof (hbuffer),
@@ -1282,19 +950,17 @@ get_ipaddr(struct rarpdev *rdev, uchar_t *laddr, uchar_t *ipp, ipaddr_t *ipaddr)
(void) memcpy(&daddr, &netnum,
sizeof (ipaddr_t));
if (ifdev->lunit == -1)
- debug(
-"trying physical netnum %s mask %x",
- inet_ntoa(daddr),
- ifdev->if_netmask);
+ debug("trying physical netnum %s"
+ " mask %x", inet_ntoa(daddr),
+ ifdev->if_netmask);
else
- debug(
-"trying logical %d netnum %s mask %x",
- ifdev->lunit,
- inet_ntoa(daddr),
- ifdev->if_netmask);
+ debug("trying logical %d netnum %s"
+ " mask %x", ifdev->lunit,
+ inet_ntoa(daddr),
+ ifdev->if_netmask);
}
if ((ntohl(addr.s_addr) & ifdev->if_netmask) ==
- ifdev->if_netnum) {
+ ifdev->if_netnum) {
/*
* Return the correct IP address.
*/
@@ -1316,13 +982,6 @@ get_ipaddr(struct rarpdev *rdev, uchar_t *laddr, uchar_t *ipp, ipaddr_t *ipaddr)
return (1);
}
-/*ARGSUSED*/
-void
-sigalarm(int i)
-{
- error(alarmmsg);
-}
-
static int
strioctl(int fd, int cmd, int timout, int len, char *dp)
{
@@ -1336,14 +995,13 @@ strioctl(int fd, int cmd, int timout, int len, char *dp)
}
static void
-usage()
+usage(void)
{
error("Usage: %s [ -ad ] device unit", cmdname);
}
static void
-syserr(s)
-char *s;
+syserr(const char *s)
{
char buf[256];
int status = 1;
@@ -1354,9 +1012,8 @@ char *s;
thr_exit(&status);
}
-/*PRINTFLIKE1*/
static void
-error(char *fmt, ...)
+error(const char *fmt, ...)
{
char buf[256];
va_list ap;