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