diff options
37 files changed, 568 insertions, 1853 deletions
diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c b/deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c index 3d0cf75273..3d0cf75273 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c +++ b/deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.c diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h b/deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h index 6169983c44..6169983c44 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h +++ b/deleted_files/usr/src/cmd/cmd-inet/sbin/dhcpagent/dlprims.h diff --git a/usr/src/cmd/zoneadm/dlprims.c b/deleted_files/usr/src/cmd/zoneadm/dlprims.c index 083e5a0743..083e5a0743 100644 --- a/usr/src/cmd/zoneadm/dlprims.c +++ b/deleted_files/usr/src/cmd/zoneadm/dlprims.c 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/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; diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c index 34a1448663..17a3d53e6a 100644 --- a/usr/src/cmd/dladm/dladm.c +++ b/usr/src/cmd/dladm/dladm.c @@ -2561,13 +2561,14 @@ do_show_linkprop(int argc, char **argv) static void show_linkprop_onelink(void *arg, const char *link) { - int i, fd; - char linkname[MAXPATHLEN]; + int i; + int retval; char *buf; dladm_status_t status; prop_list_t *proplist = NULL; show_linkprop_state_t *statep; const char *savep; + dlpi_handle_t dh; statep = (show_linkprop_state_t *)arg; savep = statep->ls_link; @@ -2580,9 +2581,8 @@ show_linkprop_onelink(void *arg, const char *link) * if there are no open links, the retrieval of link properties * (below) will proceed slowly unless we hold the link open. */ - (void) snprintf(linkname, MAXPATHLEN, "/dev/%s", link); - if ((fd = open(linkname, O_RDWR)) < 0) { - warn("cannot open %s: %s", link, strerror(errno)); + if ((retval = dlpi_open(link, &dh, 0)) != DLPI_SUCCESS) { + warn("cannot open %s: %s", link, dlpi_strerror(retval)); statep->ls_status = DLADM_STATUS_NOTFOUND; return; } @@ -2609,7 +2609,7 @@ show_linkprop_onelink(void *arg, const char *link) if (status != DLADM_STATUS_OK) warn_dlerr(status, "show-linkprop failed for %s", link); } - (void) close(fd); + dlpi_close(dh); free(buf); statep->ls_link = savep; } diff --git a/usr/src/cmd/fs.d/ufs/fsck/Makefile b/usr/src/cmd/fs.d/ufs/fsck/Makefile index ce8924b04e..33200494df 100644 --- a/usr/src/cmd/fs.d/ufs/fsck/Makefile +++ b/usr/src/cmd/fs.d/ufs/fsck/Makefile @@ -2,9 +2,8 @@ # 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. +# Common Development and Distribution License (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. @@ -22,7 +21,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # cmd/fs.d/ufs/fsck/Makefile @@ -45,15 +44,11 @@ UFSOBJS= ufs_subr.o ufs_tables.o UFSSRCS= $(UFSOBJS:%.o=$(UFSDIR)/%.c) ROLLDIR= ../roll_log -AVLDIR= ../../../../common/avl -AVLOBJS= avl.o -AVLSRCS= $(AVLOBJS:%.o=$(AVLDIR)/%.c) - -OBJS= $(FSCKOBJS) $(UFSOBJS) $(ROLLOBJS) $(AVLOBJS) $(FSLIB) -SRCS= $(FSCKSRCS) $(UFSSRCS) $(ROLLSRCS) $(AVLSRCS) $(FSLIBSRC) +OBJS= $(FSCKOBJS) $(UFSOBJS) $(ROLLOBJS) $(FSLIB) +SRCS= $(FSCKSRCS) $(UFSSRCS) $(ROLLSRCS) $(FSLIBSRC) CPPFLAGS += -D_LARGEFILE64_SOURCE -I../../ -I../../../../lib/libadm/inc -LDLIBS += -lefi +LDLIBS += -lefi -lavl $(LIBPROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(CTFMERGE_HOOK) @@ -62,9 +57,6 @@ $(LIBPROG): $(OBJS) %.o: $(UFSDIR)/%.c $(COMPILE.c) $< $(CTFCONVERT_HOOK) -%.o: $(AVLDIR)/%.c - $(COMPILE.c) $< $(CTFCONVERT_HOOK) - # Use DEVLINTFLAGS and the definition of LINT.c below for development # checking. Prior to putback, increase Nlevel to 4 for extra sanity. # Nlevel=2 is the default applied by lint. @@ -88,7 +80,7 @@ DEVLINTFLAGS = -errtags=yes -U__PRAGMA_REDEFINE_EXTNAME \ lint: lint_SRCS clean: - $(RM) $(FSCKOBJS) $(UFSOBJS) $(AVLOBJS) + $(RM) $(FSCKOBJS) $(UFSOBJS) cscope.out tags: FRC $(XREF) -f -x $@ diff --git a/usr/src/cmd/zoneadm/Makefile b/usr/src/cmd/zoneadm/Makefile index 27ced72cee..4428c23cb3 100644 --- a/usr/src/cmd/zoneadm/Makefile +++ b/usr/src/cmd/zoneadm/Makefile @@ -34,12 +34,12 @@ include ../Makefile.cmd ROOTMANIFESTDIR= $(ROOTSVCSYSTEM) -OBJS= zoneadm.o sw_cmp.o zfs.o dlprims.o +OBJS= zoneadm.o sw_cmp.o zfs.o SRCS = $(OBJS:.o=.c) POFILE=zoneadm_all.po POFILES= $(OBJS:%.o=%.po) -LDLIBS += -lzonecfg -lsocket -lgen -lpool -lbsm -lzfs -luuid -lnvpair -lbrand +LDLIBS += -lzonecfg -lsocket -lgen -lpool -lbsm -lzfs -luuid -lnvpair -lbrand -ldlpi .KEEP_STATE: diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c index c24ca44fb3..db7ef054cb 100644 --- a/usr/src/cmd/zoneadm/zoneadm.c +++ b/usr/src/cmd/zoneadm/zoneadm.c @@ -66,6 +66,7 @@ #include <limits.h> #include <dirent.h> #include <uuid/uuid.h> +#include <libdlpi.h> #include <fcntl.h> #include <door.h> @@ -147,7 +148,6 @@ struct cmd { static int cleanup_zonepath(char *, boolean_t); -extern int ifname_open(char *); static int help_func(int argc, char *argv[]); static int ready_func(int argc, char *argv[]); @@ -2836,7 +2836,7 @@ verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[]) int err; boolean_t in_alt_root; zone_iptype_t iptype; - int fd; + dlpi_handle_t dh; in_alt_root = zonecfg_in_alt_root(); if (in_alt_root) @@ -2907,19 +2907,21 @@ verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[]) nwiftab.zone_nwif_physical); break; } + /* - * Verify that the physical interface can - * be opened + * Verify that the physical interface can be opened. */ - fd = ifname_open(nwiftab.zone_nwif_physical); - if (fd == -1) { + err = dlpi_open(nwiftab.zone_nwif_physical, &dh, 0); + if (err != DLPI_SUCCESS) { (void) fprintf(stderr, gettext("WARNING: skipping network " - "interface '%s' which cannot be opened.\n"), - nwiftab.zone_nwif_physical); + "interface '%s' which cannot be opened: " + "dlpi error (%s).\n"), + nwiftab.zone_nwif_physical, + dlpi_strerror(err)); break; } else { - (void) close(fd); + dlpi_close(dh); } /* * Verify whether the physical interface is already diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index ef6a96f1b8..25d2e96f28 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -482,7 +482,7 @@ libinetcfg: libnsl libsocket libdevinfo libkmf: libcryptoutil pkcs11 openssl libnsl: libmd5 libscf libmapid: libresolv -libuuid: libsocket +libuuid: libdlpi libdladm libinetutil: libsocket libsecdb: libnsl libsasl: libgss libsocket pkcs11 libmd diff --git a/usr/src/lib/libdhcpagent/common/dhcp_stable.c b/usr/src/lib/libdhcpagent/common/dhcp_stable.c index e240164549..3f4c41e868 100644 --- a/usr/src/lib/libdhcpagent/common/dhcp_stable.c +++ b/usr/src/lib/libdhcpagent/common/dhcp_stable.c @@ -145,7 +145,7 @@ make_stable_duid(const char *physintf, size_t *duidlen) if (dlpi_open(physintf, &dh, 0) == DLPI_SUCCESS && dlpi_info(dh, &dlinfo, 0) == DLPI_SUCCESS && (len = dlinfo.di_physaddrlen) > 0 && - (arptype = dlpi_to_arp(dlinfo.di_mactype) != 0)) { + (arptype = dlpi_arptype(dlinfo.di_mactype) != 0)) { duid_llt_t *dllt; time_t now; diff --git a/usr/src/lib/libdhcputil/common/dhcp_inittab.c b/usr/src/lib/libdhcputil/common/dhcp_inittab.c index 861dbc3f57..0010fdfabe 100644 --- a/usr/src/lib/libdhcputil/common/dhcp_inittab.c +++ b/usr/src/lib/libdhcputil/common/dhcp_inittab.c @@ -101,58 +101,6 @@ static category_map_entry_t category_map[] = { }; /* - * dlpi_to_arp(): converts DLPI datalink types into ARP datalink types - * - * input: uint_t: the DLPI datalink type - * output: uint_t: the ARP datalink type (0 if no corresponding code) - * - * note: this function does not belong in this library, but it's here until - * dhcpagent is ported over to libdlpi. It should move to libdlpi - * instead. - */ - -uint_t -dlpi_to_arp(uint_t dlpi_type) -{ - switch (dlpi_type) { - - case DL_ETHER: - return (ARPHRD_ETHER); - - case DL_FRAME: - return (ARPHRD_FRAME); - - case DL_ATM: - return (ARPHRD_ATM); - - case DL_IPATM: - return (ARPHRD_IPATM); - - case DL_HDLC: - return (ARPHRD_HDLC); - - case DL_FC: - return (ARPHRD_FC); - - case DL_CSMACD: /* ieee 802 networks */ - case DL_TPB: - case DL_TPR: - case DL_METRO: - case DL_FDDI: - return (ARPHRD_IEEE802); - - case DL_IB: - return (ARPHRD_IB); - - case DL_IPV4: - case DL_IPV6: - return (ARPHRD_TUNNEL); - } - - return (0); -} - -/* * inittab_load(): returns all inittab entries with the specified criteria * * input: uchar_t: the categories the consumer is interested in @@ -571,7 +519,7 @@ get_mac_addr(const char *str, int *ierrnop, uint16_t *hwret, int hwtype, (void) memcpy(outbuf, dlinfo.di_physaddr, maclen); dlpi_close(dh); if (hwtype == -1) - hwtype = dlpi_to_arp(dlinfo.di_mactype); + hwtype = dlpi_arptype(dlinfo.di_mactype); } } if (hwtype == -1) diff --git a/usr/src/lib/libdhcputil/common/dhcp_inittab.h b/usr/src/lib/libdhcputil/common/dhcp_inittab.h index 030d057667..d4f94aabb8 100644 --- a/usr/src/lib/libdhcputil/common/dhcp_inittab.h +++ b/usr/src/lib/libdhcputil/common/dhcp_inittab.h @@ -111,9 +111,6 @@ extern char *inittab_decode(const dhcp_symbol_t *, const uchar_t *, extern char *inittab_decode_e(const dhcp_symbol_t *, const uchar_t *, uint16_t, boolean_t, int *); -/* temporary; should be in libdlpi */ -extern uint_t dlpi_to_arp(uint_t); - #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libdhcputil/common/mapfile-vers b/usr/src/lib/libdhcputil/common/mapfile-vers index 851b69b1b7..174dce2410 100644 --- a/usr/src/lib/libdhcputil/common/mapfile-vers +++ b/usr/src/lib/libdhcputil/common/mapfile-vers @@ -33,7 +33,6 @@ SUNWprivate_1.2 { dhcp_options_scan; dhcpv6_find_option; dhcpv6_pkt_option; - dlpi_to_arp; } SUNWprivate_1.1; SUNWprivate_1.1 { diff --git a/usr/src/lib/libdladm/Makefile b/usr/src/lib/libdladm/Makefile index 77c7824ae4..c1aa64b78b 100644 --- a/usr/src/lib/libdladm/Makefile +++ b/usr/src/lib/libdladm/Makefile @@ -32,6 +32,7 @@ HDRS = libdladm.h libdladm_impl.h libdllink.h libdlaggr.h \ HDRDIR = common SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) POFILE = libdladm.po MSGFILES = common/libdladm.c common/linkprop.c common/secobj.c \ diff --git a/usr/src/lib/libdladm/amd64/Makefile b/usr/src/lib/libdladm/amd64/Makefile new file mode 100644 index 0000000000..51f031cb3e --- /dev/null +++ b/usr/src/lib/libdladm/amd64/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index 0e0f990b7d..21ea999749 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -437,7 +437,8 @@ process_linkprop_init(linkprop_db_state_t *lsp, char *buf, * values from listp. */ for (lvp = lip->li_val, valcnt = 0; - lvp != NULL; lvp = lvp->lv_nextval, valcnt++); + lvp != NULL; lvp = lvp->lv_nextval, valcnt++) + ; propval = malloc(sizeof (char *) * valcnt); if (propval == NULL) { @@ -880,7 +881,7 @@ do_set_zone(const char *link, val_desc_t *vdp, uint_t val_cnt) return (status); /* Do nothing if setting to current value */ - zid_new = (zoneid_t)vdp->vd_val; + zid_new = (intptr_t)(void *)vdp->vd_val; if (zid_new == zid_old) return (DLADM_STATUS_OK); @@ -963,7 +964,7 @@ do_check_zone(prop_desc_t *pdp, char **prop_val, uint_t val_cnt, if (vdp == NULL) return (DLADM_STATUS_NOMEM); - vdp->vd_val = (void *)zid; + vdp->vd_val = (void *)(uintptr_t)zid; *vdpp = vdp; return (DLADM_STATUS_OK); } diff --git a/usr/src/lib/libdladm/sparcv9/Makefile b/usr/src/lib/libdladm/sparcv9/Makefile new file mode 100644 index 0000000000..51f031cb3e --- /dev/null +++ b/usr/src/lib/libdladm/sparcv9/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libdlpi/common/libdlpi.c b/usr/src/lib/libdlpi/common/libdlpi.c index 42ac808382..3fcddf1b31 100644 --- a/usr/src/lib/libdlpi/common/libdlpi.c +++ b/usr/src/lib/libdlpi/common/libdlpi.c @@ -42,6 +42,8 @@ #include <alloca.h> #include <sys/sysmacros.h> #include <ctype.h> +#include <net/if_types.h> +#include <netinet/arp.h> #include <libdlpi.h> #include <libintl.h> #include <libinetutil.h> @@ -586,7 +588,7 @@ dlpi_send(dlpi_handle_t dh, const void *daddrp, size_t daddrlen, if (dip->dli_oflags & DLPI_RAW) return (i_dlpi_strputmsg(dip->dli_fd, NULL, msgbuf, msglen, 0)); - if (daddrp == NULL || daddrlen > DLPI_PHYSADDR_MAX) + if ((daddrlen > 0 && daddrp == NULL) || daddrlen > DLPI_PHYSADDR_MAX) return (DLPI_EINVAL); DLPI_MSG_CREATE(req, DL_UNITDATA_REQ); @@ -765,6 +767,80 @@ dlpi_style(dlpi_handle_t dh) return (dip->dli_style); } +uint_t +dlpi_arptype(uint_t dlpitype) +{ + switch (dlpitype) { + + case DL_ETHER: + return (ARPHRD_ETHER); + + case DL_FRAME: + return (ARPHRD_FRAME); + + case DL_ATM: + return (ARPHRD_ATM); + + case DL_IPATM: + return (ARPHRD_IPATM); + + case DL_HDLC: + return (ARPHRD_HDLC); + + case DL_FC: + return (ARPHRD_FC); + + case DL_CSMACD: /* ieee 802 networks */ + case DL_TPB: + case DL_TPR: + case DL_METRO: + case DL_FDDI: + return (ARPHRD_IEEE802); + + case DL_IB: + return (ARPHRD_IB); + + case DL_IPV4: + case DL_IPV6: + return (ARPHRD_TUNNEL); + } + + return (0); +} + +uint_t +dlpi_iftype(uint_t dlpitype) +{ + switch (dlpitype) { + + case DL_ETHER: + return (IFT_ETHER); + + case DL_ATM: + return (IFT_ATM); + + case DL_CSMACD: + return (IFT_ISO88023); + + case DL_TPB: + return (IFT_ISO88024); + + case DL_TPR: + return (IFT_ISO88025); + + case DL_FDDI: + return (IFT_FDDI); + + case DL_IB: + return (IFT_IB); + + case DL_OTHER: + return (IFT_OTHER); + } + + return (0); +} + /* * This function attempts to open linkname under the following namespaces: * - /dev @@ -1094,6 +1170,8 @@ i_dlpi_strgetmsg(int fd, int msec, dlpi_msg_t *dlreplyp, t_uscalar_t dlreqprim, switch (poll(&pfd, 1, msec)) { default: + if (pfd.revents & POLLHUP) + return (DL_SYSERR); break; case 0: return (DLPI_ETIMEDOUT); diff --git a/usr/src/lib/libdlpi/common/libdlpi.h b/usr/src/lib/libdlpi/common/libdlpi.h index 0099727cc5..a0f5b918e8 100644 --- a/usr/src/lib/libdlpi/common/libdlpi.h +++ b/usr/src/lib/libdlpi/common/libdlpi.h @@ -160,6 +160,8 @@ extern int dlpi_send(dlpi_handle_t, const void *, size_t, const void *, size_t, const dlpi_sendinfo_t *); extern int dlpi_fd(dlpi_handle_t); extern int dlpi_set_timeout(dlpi_handle_t, int); +extern uint_t dlpi_arptype(uint_t); +extern uint_t dlpi_iftype(uint_t); /* * These are Consolidation Private interfaces and are subject to change. diff --git a/usr/src/lib/libdlpi/common/mapfile-vers b/usr/src/lib/libdlpi/common/mapfile-vers index 31ae2a5aa1..457f0b39cb 100644 --- a/usr/src/lib/libdlpi/common/mapfile-vers +++ b/usr/src/lib/libdlpi/common/mapfile-vers @@ -27,12 +27,14 @@ SUNW_1.1 { # first release of libdlpi, Solaris 11 global: + dlpi_arptype; dlpi_bind; dlpi_close; dlpi_disabmulti; dlpi_enabmulti; dlpi_fd; dlpi_get_physaddr; + dlpi_iftype; dlpi_info; dlpi_linkname; dlpi_mactype; diff --git a/usr/src/lib/libuuid/Makefile.com b/usr/src/lib/libuuid/Makefile.com index 7329255870..d1178c5bc6 100644 --- a/usr/src/lib/libuuid/Makefile.com +++ b/usr/src/lib/libuuid/Makefile.com @@ -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. # # ident "%Z%%M% %I% %E% SMI" @@ -35,7 +35,7 @@ include ../../Makefile.lib include ../../Makefile.rootfs LIBS = $(DYNLIB) $(LINTLIB) -LDLIBS += -lsocket -lnsl -lc +LDLIBS += -lsocket -lnsl -lc -ldlpi -ldladm SRCDIR = ../common $(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) diff --git a/usr/src/lib/libuuid/common/etheraddr.c b/usr/src/lib/libuuid/common/etheraddr.c index 527a82c98d..6b2011150e 100644 --- a/usr/src/lib/libuuid/common/etheraddr.c +++ b/usr/src/lib/libuuid/common/etheraddr.c @@ -2,9 +2,8 @@ * 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. + * Common Development and Distribution License (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. @@ -20,62 +19,35 @@ * 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. */ #pragma ident "%Z%%M% %I% %E% SMI" -#include "etheraddr.h" #include <stdlib.h> #include <stdio.h> -#include <fcntl.h> -#include <string.h> #include <strings.h> -#include <libdevinfo.h> #include <stropts.h> #include <unistd.h> #include <uuid/uuid.h> #include <sys/sockio.h> +#include <libdlpi.h> +#include <libdllink.h> #include <sys/utsname.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <sys/dlpi.h> +#include "etheraddr.h" + /* * debugging flag */ static int debug = 0; - -/* Timeout for DLPI acks */ -static int dlpi_timeout = DLPI_TIMEOUT; - -/* - * Global functions - */ -int dlpi_get_address(char *, struct ether_addr *); -int get_net_if_names(char ***); -void free_net_if_names(char **); - - -/* - * local functions - */ -static int dlpi_info_req(int, dl_info_ack_t *); -static int timed_getmsg(int, struct strbuf *, int *, int, char *, char *); -static int ifrm_num(char *, unsigned int *); -static int open_dev(dev_att_t *, int, int *, int); -static void pf_dev_att(dev_att_t *); -static void parse_ifname(dev_att_t *); -static int ifname_open(char *, dev_att_t *); -static int dlpi_open_attach(char *); -static int dlpi_attach(int, int, int); -static int dlpi_get_phys(int, uchar_t *); -static int dlpi_info_req(int, dl_info_ack_t *); -static int timed_getmsg(int, struct strbuf *, int *, int, char *, char *); +static void get_etheraddr(void *arg, const char *linkname); /* * get an individual arp entry @@ -122,764 +94,70 @@ arp_get(uuid_node_t *node) return (0); } - -/* Get all interface names. This will include IPv6 names. */ -int -get_net_if_names(char ***names) -{ - char *buf; /* buffer for socket info */ - int sd; /* socket descriptor */ - int ifn; /* interface count structure */ - struct ifconf ifc; /* interface config buffer */ - struct ifreq *ifrp; - int numifs; - char **tmpnames; - int n; - char *tmpname; - sd = socket(AF_INET, SOCK_DGRAM, 0); - if (sd < 0) - return (-1); - - if (ioctl(sd, SIOCGIFNUM, &ifn) < 0) { - (void) close(sd); - return (-1); - } - - if (!(buf = malloc(ifn * sizeof (struct ifreq)))) { - (void) close(sd); - return (-1); - } - - ifc.ifc_len = ifn * sizeof (struct ifreq); - ifc.ifc_buf = (caddr_t)buf; - if (ioctl(sd, SIOCGIFCONF, (char *)&ifc) < 0) { - free(buf); - (void) close(sd); - return (-1); - } - (void) close(sd); - - ifrp = ifc.ifc_req; - numifs = ifc.ifc_len / sizeof (struct ifreq); - tmpnames = (char **)calloc((numifs+1), sizeof (char *)); - - if (tmpnames == NULL) { - free(buf); - return (-1); - } - for (n = 0; n < numifs; n++, ifrp++) { - if ((tmpnames[n] = strdup(ifrp->ifr_name)) == NULL) - break; - } - free(buf); - *names = tmpnames; - return (0); -} - -/* - * frees previously-allocated array from get_net_if_names - */ -void -free_net_if_names(char **ifnames) -{ - int i; - - i = 0; - while (ifnames[i] != NULL) { - free(ifnames[i]); - i++; - } - free(ifnames); -} - - /* - * attempt to remove ppa from end of file name - * return -1 if none found - * return ppa if found and remove the ppa from the filename + * Name: get_ethernet_address + * + * Description: Obtains the system ethernet address. + * + * Returns: 0 on success, non-zero otherwise. The system ethernet + * address is copied into the passed-in variable. */ -static int -ifrm_num(char *fname, unsigned int *ppa) +int +get_ethernet_address(uuid_node_t *node) { - int i; - uint_t p = 0; - unsigned int m = 1; + walker_arg_t state; - i = strlen(fname) - 1; - while (i >= 0 && '0' <= fname[i] && fname[i] <= '9') { - p += (fname[i] - '0')*m; - m *= 10; - i--; - } - if (m == 1) { - return (-1); - } - fname[i + 1] = '\0'; - *ppa = p; - return (0); -} - -/* - * Open the device defined in dev_att with the given mode starting with - * the module indicated by mod_cnt (1 indexed). If mod_cnt > 0, fd must - * contain the file descriptor that modules are to be pushed on. - * Returns -1 if device could not be opened, the index of - * the module that could not be pushed or 0 on success. - */ -static int -open_dev(dev_att_t *dev_att, int mode, int *fd, int mod_cnt) -{ - int cnt; - int local_fd; + if (arp_get(node) == 0) + return (0); - if (debug) - (void) printf("open_dev: ifname: %s : dev %s fd %d " - " mod_cnt %d\n", - dev_att->ifname, dev_att->devname, *fd, mod_cnt); /* - * if no module count is given, try and open the device + * Try to get physical (ethernet) address from network interfaces. */ - if (mod_cnt == 0) { - if (debug) - (void) printf("open_dev: opening %s\n", - dev_att->devname); - if ((local_fd = open(dev_att->devname, mode)) < 0) { - if (debug) { - perror("open_dev: device"); - (void) printf("\n"); - } - *fd = local_fd; - return (-1); - } - *fd = local_fd; - cnt = 1; - } else { - local_fd = *fd; - cnt = mod_cnt; + state.wa_addrvalid = B_FALSE; + if (dladm_walk(get_etheraddr, &state) == 0 && state.wa_addrvalid) { + bcopy(state.wa_etheraddr, node, state.wa_etheraddrlen); } - /* - * Try and push modules (if any) onto the device stream - */ - for (; cnt <= dev_att->mod_cnt; cnt++) { - if (debug) - (void) printf(" pushing: mod %s", - dev_att->modlist[cnt - 1]); - if (ioctl(local_fd, I_PUSH, dev_att->modlist[cnt - 1]) == -1) { - if (debug) { - perror("open_dev: push"); - (void) printf("\n"); - } - return (cnt); - } - } - if (debug) - (void) printf("\n"); - return (0); -} - -/* - * Debug routine to print out dev_att_t structure - */ -static void -pf_dev_att(dev_att_t *dev_att) -{ - int cnt; - - (void) printf("\tifname: %s\n", dev_att->ifname); - (void) printf("\t style: %d\n", dev_att->style); - (void) printf("\t ppa: %d\n", dev_att->ppa); - (void) printf("\t mod_cnt: %d\n", dev_att->mod_cnt); - (void) printf("\t devname: %s\n", dev_att->devname); - for (cnt = 0; cnt < dev_att->mod_cnt; cnt++) { - (void) printf("\t module: %s\n", dev_att->modlist[cnt]); - } + return (state.wa_addrvalid ? 0 : -1); } /* - * This function parses a '.' delimited interface name of the form - * dev[.module[.module...]][:lun] - * and places the device and module name into dev_att + * Get the physical address via dlpi and update the flag to true upon success. */ static void -parse_ifname(dev_att_t *dev_att) +get_etheraddr(void *arg, const char *linkname) { - char *lunstr; - char *modlist = NULL; /* list of modules to push */ - int cnt = 0; /* number of modules to push */ - char modbuf[LIFNAMSIZ]; - char *nxtmod; - - /* - * check for specified lun at end of interface and - * strip it off. - */ - lunstr = strchr(dev_att->ifname, ':'); - - if (lunstr) { - char *endptr; - - *lunstr = '\0'; - lunstr++; - endptr = lunstr; - dev_att->lun = strtoul(lunstr, &endptr, 10); - - if (endptr == lunstr || *endptr != '\0') { - (void) printf("Invalid logical unit number:%s", lunstr); - exit(-1); - } - } else { - dev_att->lun = 0; - } - - (void) strlcpy(modbuf, dev_att->ifname, LIFNAMSIZ); - - /* parse '.' delmited module list */ - modlist = strchr(modbuf, '.'); - if (modlist) { - /* null-terminate interface name (device) */ - *modlist = '\0'; - modlist++; - if (strlen(modlist) == 0) - modlist = NULL; - while (modlist && cnt < MAX_MODS) { - nxtmod = strchr(modlist, '.'); - if (nxtmod) { - *nxtmod = '\0'; - nxtmod++; - } - (void) strncpy(dev_att->modlist[cnt], modlist, - LIFNAMSIZ); - cnt++; - modlist = nxtmod; - } - } - (void) snprintf(dev_att->devname, LIFNAMSIZ, "%s/%s", DEVDIR, modbuf); - dev_att->mod_cnt = cnt; -} - -/* - * given a interface name (with possible modules to push) - * interface name must have the format of - * dev[ppa][.module[.module...][ppa]][:lun] - * where only one ppa may be specified e.g. ip0.foo.tun or ip.foo.tun0 - */ -static int -ifname_open(char *dev_name, dev_att_t *dev_att) -{ - int fd; - uint_t ppa; - int res; - int style; - dl_info_ack_t dl_info; - int mod_id; - - if (debug) - (void) printf("ifname_open: %s\n", dev_name); - - if (strlen(dev_name) > LIFNAMSIZ - 1) { - errno = EINVAL; - return (-1); - } - - /* save copy of original device name */ - (void) strncpy(dev_att->ifname, dev_name, LIFNAMSIZ); - - /* parse modules */ - parse_ifname(dev_att); - - /* try DLPI style 1 device first */ + int retval; + dlpi_handle_t dh; + walker_arg_t *statep = arg; - if (debug) { - pf_dev_att(dev_att); - } - mod_id = open_dev(dev_att, O_RDWR, &fd, 0); - if (mod_id != 0) { - if (debug) { - (void) printf("Error on open_dev style 1 mod_id: %d" - " attemping style 2\n", mod_id); - pf_dev_att(dev_att); - } - if (mod_id == -1) { - res = ifrm_num(dev_att->devname, &ppa); - mod_id = 0; - if (res < 0) { - if (debug) - (void) fprintf(stderr, - "%s: No such file or directory\n", - dev_att->devname); - (void) close(fd); - return (-1); - } - /* - * ensure that it's the last module - * in the list to extract - * ppa - */ - } else if ((mod_id != dev_att->mod_cnt) || - (res = ifrm_num(dev_att->modlist[dev_att->mod_cnt - 1], - &ppa)) < 0) { + if (!(statep->wa_addrvalid)) { + if (debug) + (void) printf("get_etheraddr: opening %s\n", linkname); + if ((retval = dlpi_open(linkname, &dh, 0)) != DLPI_SUCCESS) { if (debug) { - (void) fprintf(stderr, - "Error on open_dev style 2 mod_id: %d \n", - mod_id); + (void) fprintf(stderr, "get_etheraddr: " + "cannot open link: \"%s\" %s\n", + linkname, retval); } - if (mod_id == dev_att->mod_cnt) - (void) fprintf(stderr, "libuuid: could not " - "locate ppa in %s\n", - dev_att->ifname); - (void) close(fd); - return (-1); + return; } - goto style2; - } - dev_att->style = 1; - dev_att->ppa = 0; - style = DL_STYLE1; - goto dl_info_chk; -style2: - dev_att->ppa = ppa; - mod_id = open_dev(dev_att, O_RDWR, &fd, mod_id); - if (mod_id != 0) { + if (debug) { - (void) fprintf(stderr, - "Error on open_dev style 2 mod_id: %d \n", - mod_id); - if (mod_id > 0) { - (void) fprintf(stderr, "%s: No such module\n", - dev_att->modlist[mod_id - 2]); - } - pf_dev_att(dev_att); + (void) printf("get_etheraddr: getting ethernet address" + " from link: %s\n", linkname); } - (void) close(fd); - return (-1); - } - dev_att->style = 2; - style = DL_STYLE2; -dl_info_chk: - if (dlpi_info_req(fd, &dl_info) < 0) { - (void) close(fd); - pf_dev_att(dev_att); - return (-1); - } - if (dl_info.dl_provider_style != style) { + statep->wa_etheraddrlen = DLPI_PHYSADDR_MAX; + retval = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, + statep->wa_etheraddr, &(statep->wa_etheraddrlen)); if (debug) { - (void) fprintf(stderr, "DLPI provider style mismatch: " - "expected style %s got style %s (0x%lx)\n", - style == DL_STYLE1 ? "1" : "2", - dl_info.dl_provider_style == DL_STYLE1 ? "1" : "2", - dl_info.dl_provider_style); + (void) fprintf(stderr, "get_etheraddr: " + "dlpi_get_physaddr: \"%s\" %s\n", linkname, retval); } - (void) close(fd); - return (-1); - } - if (debug) { - (void) printf("pars_dev_att() success\n"); - pf_dev_att(dev_att); - } - return (fd); -} -static int -dlpi_open_attach(char *ifname) -{ - int fd; - dev_att_t dev_att; - - if (debug) - (void) printf("dlpi_open_attach %s\n", ifname); + if (retval == DLPI_SUCCESS) + statep->wa_addrvalid = B_TRUE; - /* if lun is specified fail (backwards compat) */ - if (strchr(ifname, ':') != NULL) { - return (-1); - } - if ((fd = ifname_open(ifname, &dev_att)) < 0) { - /* Not found */ - errno = ENXIO; - return (-1); + dlpi_close(dh); } - if (dlpi_attach(fd, dev_att.ppa, dev_att.style) < 0) { - (void) close(fd); - return (-1); - } - return (fd); -} - -static int -dlpi_attach(int fd, int ppa, int style) -{ - union DL_primitives *dlp; - char *buf; - struct strbuf ctl; - int flags; - - if (style != 2) - return (0); - - /* Allocate required buffers */ - if ((buf = malloc(BUFSIZ)) == NULL) { - (void) fprintf(stderr, "libuuid: malloc() failed\n"); - return (-1); - } - - /* Issue DL_ATTACH_REQ */ - /* LINTED: malloc returns a pointer aligned for any use */ - dlp = (union DL_primitives *)buf; - dlp->attach_req.dl_primitive = DL_ATTACH_REQ; - dlp->attach_req.dl_ppa = ppa; - ctl.buf = (char *)dlp; - ctl.len = DL_ATTACH_REQ_SIZE; - if (putmsg(fd, &ctl, NULL, 0) < 0) { - perror("libuuid: putmsg"); - free(buf); - return (-1); - } - - /* read reply */ - ctl.buf = (char *)dlp; - ctl.len = 0; - ctl.maxlen = BUFSIZ; - flags = 0; - - /* start timeout for DL_OK_ACK reply */ - if (timed_getmsg(fd, &ctl, &flags, dlpi_timeout, - "DL_OK_ACK", "DL_ATTACH_REQ") == 0) { - free(buf); - return (-1); - } - - if (debug) { - (void) printf("ok_ack: ctl.len[%d] flags[%d]\n", ctl.len, - flags); - } - - /* Validate DL_OK_ACK reply. */ - if (ctl.len < sizeof (t_uscalar_t)) { - (void) fprintf(stderr, - "libuuid: attach failed: short reply to attach request\n"); - free(buf); - return (-1); - } - - if (dlp->dl_primitive == DL_ERROR_ACK) { - if (debug) - (void) fprintf(stderr, - "attach failed: dl_errno %lu errno %lu\n", - dlp->error_ack.dl_errno, - dlp->error_ack.dl_unix_errno); - free(buf); - errno = ENXIO; - return (-1); - } - if (dlp->dl_primitive != DL_OK_ACK) { - (void) fprintf(stderr, - "libuuid: attach failed: " - "unrecognizable dl_primitive %lu received", - dlp->dl_primitive); - free(buf); - return (-1); - } - if (ctl.len < DL_OK_ACK_SIZE) { - (void) fprintf(stderr, - "libuuid: attach failed: " - "short attach acknowledgement received\n"); - free(buf); - return (-1); - } - if (dlp->ok_ack.dl_correct_primitive != DL_ATTACH_REQ) { - (void) fprintf(stderr, - "libuuid: attach failed: " - "returned prim %lu != requested prim %lu\n", - dlp->ok_ack.dl_correct_primitive, - (t_uscalar_t)DL_ATTACH_REQ); - free(buf); - return (-1); - } - if (debug) - (void) printf("attach done\n"); - - free(buf); - return (0); -} - -static int -dlpi_get_phys(int fd, uchar_t *eaddr) -{ - union DL_primitives *dlp; - char *buf; - struct strbuf ctl; - int flags; - - /* Allocate required buffers */ - if ((buf = malloc(BUFSIZ)) == NULL) { - (void) fprintf(stderr, "libuuid: malloc() failed\n"); - return (-1); - } - /* Issue DL_PHYS_ADDR_REQ */ - /* LINTED: malloc returns a pointer aligned for any use */ - 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) { - perror("libuuid: putmsg"); - free(buf); - return (-1); - } - - /* read reply */ - ctl.buf = (char *)dlp; - ctl.len = 0; - ctl.maxlen = BUFSIZ; - flags = 0; - - if (timed_getmsg(fd, &ctl, &flags, dlpi_timeout, - "DL_PHYS_ADDR_ACK", "DL_PHYS_ADDR_REQ (DL_CURR_PHYS_ADDR)") == 0) { - free(buf); - return (-1); - } - - if (debug) { - (void) printf("phys_addr_ack: ctl.len[%d] flags[%d]\n", ctl.len, - flags); - } - - /* Validate DL_PHYS_ADDR_ACK reply. */ - if (ctl.len < sizeof (t_uscalar_t)) { - (void) fprintf(stderr, "libuuid: phys_addr failed: " - "short reply to phys_addr request\n"); - free(buf); - return (-1); - } - - if (dlp->dl_primitive == DL_ERROR_ACK) { - /* - * Do not print errors for DL_UNSUPPORTED and DL_NOTSUPPORTED - */ - if (dlp->error_ack.dl_errno != DL_UNSUPPORTED && - dlp->error_ack.dl_errno != DL_NOTSUPPORTED) { - (void) fprintf(stderr, "libuuid: phys_addr failed: " - "dl_errno %lu errno %lu\n", - dlp->error_ack.dl_errno, - dlp->error_ack.dl_unix_errno); - } - free(buf); - return (-1); - } - if (dlp->dl_primitive != DL_PHYS_ADDR_ACK) { - (void) fprintf(stderr, "libuuid: phys_addr failed: " - "unrecognizable dl_primitive %lu received\n", - dlp->dl_primitive); - free(buf); - return (-1); - } - if (ctl.len < DL_PHYS_ADDR_ACK_SIZE) { - (void) fprintf(stderr, "libuuid: phys_addr failed: " - "short phys_addr acknowledgement received\n"); - free(buf); - return (-1); - } - /* Check length of address. */ - if (dlp->physaddr_ack.dl_addr_length != ETHERADDRL) { - free(buf); - return (-1); - } - - /* copy Ethernet address */ - (void) memcpy(eaddr, &buf[dlp->physaddr_ack.dl_addr_offset], - ETHERADDRL); - - free(buf); - return (0); -} - - - -static int -dlpi_info_req(int fd, dl_info_ack_t *info_ack) -{ - dl_info_req_t info_req; - int buf[BUFSIZ/sizeof (int)]; - union DL_primitives *dlp = (union DL_primitives *)buf; - struct strbuf ctl; - int flags; - - info_req.dl_primitive = DL_INFO_REQ; - - ctl.len = DL_INFO_REQ_SIZE; - ctl.buf = (char *)&info_req; - - flags = RS_HIPRI; - - if (putmsg(fd, &ctl, (struct strbuf *)NULL, flags) < 0) { - perror("libuuid: putmsg"); - return (-1); - } - - /* read reply */ - ctl.buf = (char *)dlp; - ctl.len = 0; - ctl.maxlen = BUFSIZ; - flags = 0; - /* start timeout for DL_BIND_ACK reply */ - if (timed_getmsg(fd, &ctl, &flags, dlpi_timeout, "DL_INFO_ACK", - "DL_INFO_ACK") == 0) { - return (-1); - } - - if (debug) { - (void) printf("info_ack: ctl.len[%d] flags[%d]\n", ctl.len, - flags); - } - - /* Validate DL_BIND_ACK reply. */ - if (ctl.len < sizeof (t_uscalar_t)) { - (void) fprintf(stderr, - "libuuid: info req failed: short reply to info request\n"); - return (-1); - } - - if (dlp->dl_primitive == DL_ERROR_ACK) { - (void) fprintf(stderr, - "libuuid: info req failed: dl_errno %lu errno %lu\n", - dlp->error_ack.dl_errno, dlp->error_ack.dl_unix_errno); - return (-1); - } - if (dlp->dl_primitive != DL_INFO_ACK) { - (void) fprintf(stderr, - "libuuid: info req failed: " - "unrecognizable dl_primitive %lu received\n", - dlp->dl_primitive); - return (-1); - } - if (ctl.len < DL_INFO_ACK_SIZE) { - (void) fprintf(stderr, - "libuuid: info req failed: " - "short info acknowledgement received\n"); - return (-1); - } - *info_ack = *(dl_info_ack_t *)dlp; - return (0); -} - - -/* - * interface called from libuuid to get the ethernet address - jhf - */ -int -dlpi_get_address(char *ifname, struct ether_addr *ea) -{ - int fd; - - if (debug) - (void) printf("dlpi_get_address: dlpi_open_attach\t"); - fd = dlpi_open_attach(ifname); - if (fd < 0) { - /* Do not report an error */ - return (-1); - } - - if (debug) - (void) printf("dlpi_get_address: dlpi_get_phys %s\n", ifname); - if (dlpi_get_phys(fd, (uchar_t *)ea) < 0) { - (void) close(fd); - return (-1); - } - (void) close(fd); - return (0); -} - -static int -timed_getmsg(int fd, struct strbuf *ctlp, int *flagsp, int timeout, char *kind, - char *request) -{ - char perrorbuf[BUFSIZ]; - struct pollfd pfd; - int ret; - - pfd.fd = fd; - - pfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; - if ((ret = poll(&pfd, 1, timeout * 1000)) == 0) { - (void) fprintf(stderr, "libuuid: %s timed out\n", kind); - return (0); - } else if (ret == -1) { - (void) snprintf(perrorbuf, sizeof (perrorbuf), - "libuuid: poll for %s from %s", kind, request); - perror(perrorbuf); - return (0); - } - - /* poll returned > 0 for this fd so getmsg should not block */ - if ((ret = getmsg(fd, ctlp, NULL, flagsp)) < 0) { - (void) snprintf(perrorbuf, sizeof (perrorbuf), - "libuuid: getmsg expecting %s for %s", kind, request); - perror(perrorbuf); - return (0); - } - - return (1); -} - -/* - * Name: get_ethernet_address - * - * Description: Obtains the system ethernet address. - * - * Returns: 0 on success, non-zero otherwise. The system ethernet - * address is copied into the passed-in variable. - */ -int -get_ethernet_address(uuid_node_t *node) -{ - char **ifnames; - char *ifname; - int i; - struct ether_addr addr; - int found; - - if (arp_get(node) == 0) - return (0); - - /* - * go get all interface names - */ - if (get_net_if_names(&ifnames) != 0) { - return (-1); - } - - /* - * Assume failure - */ - found = -1; - - /* - * for each interface, query it through dlpi to get its physical - * (ethernet) address - */ - if (ifnames != NULL) { - i = 0; - while ((ifnames[i] != NULL) && found) { - ifname = ifnames[i]; - /* Gross hack to avoid getting errors from /dev/lo0 */ - if (strcmp(ifname, LOOPBACK_IF) != 0) { - if (dlpi_get_address(ifname, &addr) == 0) { - bcopy(&addr, node, 6); - /* - * found one, set result to successful - */ - found = 0; - continue; - } - } - i++; - } - free_net_if_names(ifnames); - } - - /* - * Couldn't get ethernet address from any interfaces... - */ - return (found); } diff --git a/usr/src/lib/libuuid/common/etheraddr.h b/usr/src/lib/libuuid/common/etheraddr.h index b2fdeaacf3..1f56a7b2e2 100644 --- a/usr/src/lib/libuuid/common/etheraddr.h +++ b/usr/src/lib/libuuid/common/etheraddr.h @@ -2,9 +2,8 @@ * 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. + * Common Development and Distribution License (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. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2000,2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -47,40 +46,14 @@ extern "C" { #include <netinet/if_ether.h> #include <sys/uuid.h> -/* max modules that can be pushed on intr */ -#define MAX_MODS 9 +typedef struct walker_arg { + uchar_t wa_etheraddr[DLPI_PHYSADDR_MAX]; + size_t wa_etheraddrlen; + boolean_t wa_addrvalid; +} walker_arg_t; -/* used to avoid getting errors from lo0 */ -#define LOOPBACK_IF "lo0" - -/* - * Local structure encapsulating an interface - * device and its associated modules - */ -typedef struct dev_att { - char ifname[LIFNAMSIZ]; /* interface name, such as "le0" */ - int style; /* DLPI message style */ - int ppa; /* Physical point of attachment */ - int lun; /* logical unit number */ - int mod_cnt; /* # modules to push onto stream */ - char devname[LIFNAMSIZ]; /* device name, such as "/dev/le0" */ - char modlist[MAX_MODS][LIFNAMSIZ]; /* modules to push onto stream */ -} dev_att_t; - - -/* where devices are located */ -#define DEVDIR "/dev" - -/* how long to wait for dlpi requests to succeed */ -#define DLPI_TIMEOUT 60 - -/* - * Global functions - */ +/* global function */ int arp_get(uuid_node_t *); -int dlpi_get_address(char *, struct ether_addr *); -int get_net_if_names(char ***); -void free_net_if_names(char **); int get_ethernet_address(uuid_node_t *); #ifdef __cplusplus diff --git a/usr/src/pkgdefs/SUNWcslr/prototype_i386 b/usr/src/pkgdefs/SUNWcslr/prototype_i386 index 94057d2a78..cd3f254f42 100644 --- a/usr/src/pkgdefs/SUNWcslr/prototype_i386 +++ b/usr/src/pkgdefs/SUNWcslr/prototype_i386 @@ -78,6 +78,7 @@ s none lib/amd64/libdevinfo.so=libdevinfo.so.1 f none lib/amd64/libdevinfo.so.1 755 root bin s none lib/amd64/libdl.so=libdl.so.1 f none lib/amd64/libdl.so.1 755 root bin +f none lib/amd64/libdladm.so.1 755 root bin s none lib/amd64/libdlpi.so=libdlpi.so.1 f none lib/amd64/libdlpi.so.1 755 root bin s none lib/amd64/libdoor.so=libdoor.so.1 diff --git a/usr/src/pkgdefs/SUNWcslr/prototype_sparc b/usr/src/pkgdefs/SUNWcslr/prototype_sparc index c902bf36f4..9cdc618110 100644 --- a/usr/src/pkgdefs/SUNWcslr/prototype_sparc +++ b/usr/src/pkgdefs/SUNWcslr/prototype_sparc @@ -79,6 +79,7 @@ s none lib/sparcv9/libdevinfo.so=libdevinfo.so.1 f none lib/sparcv9/libdevinfo.so.1 755 root bin s none lib/sparcv9/libdl.so=libdl.so.1 f none lib/sparcv9/libdl.so.1 755 root bin +f none lib/sparcv9/libdladm.so.1 755 root bin s none lib/sparcv9/libdlpi.so=libdlpi.so.1 f none lib/sparcv9/libdlpi.so.1 755 root bin s none lib/sparcv9/libdoor.so=libdoor.so.1 diff --git a/usr/src/pkgdefs/etc/exception_list_i386 b/usr/src/pkgdefs/etc/exception_list_i386 index 939c658c7b..80a32243bb 100644 --- a/usr/src/pkgdefs/etc/exception_list_i386 +++ b/usr/src/pkgdefs/etc/exception_list_i386 @@ -100,6 +100,8 @@ usr/include/libdlwlan.h i386 usr/include/libdlwlan_impl.h i386 lib/libdladm.so i386 lib/llib-ldladm.ln i386 +lib/amd64/libdladm.so i386 +lib/amd64/llib-ldladm.ln i386 lib/llib-ldladm i386 # # Installed in the proto area for building utilties dependent on diff --git a/usr/src/pkgdefs/etc/exception_list_sparc b/usr/src/pkgdefs/etc/exception_list_sparc index b5b64c2dbf..d10863238e 100644 --- a/usr/src/pkgdefs/etc/exception_list_sparc +++ b/usr/src/pkgdefs/etc/exception_list_sparc @@ -89,6 +89,8 @@ usr/include/libdlwlan.h sparc usr/include/libdlwlan_impl.h sparc lib/libdladm.so sparc lib/llib-ldladm.ln sparc +lib/sparcv9/libdladm.so sparc +lib/sparcv9/llib-ldladm.ln sparc lib/llib-ldladm sparc # # Installed in the proto area for building those things |