diff options
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; |