This works alongside the BSD interface.
We use the BSD interface for receiving and the DLPI interface
for sending.
>>$CONFIG_MK
echo "DHCPCD_SRCS+= if-sun.c" >>$CONFIG_MK
echo "LDADD+= -ldlpi -lkstat" >>$CONFIG_MK
+ BPF_OS="bpf-bsd.c bpf-dlpi.c"
;;
*)
echo "DHCPCD_SRCS+= if-bsd.c" >>$CONFIG_MK
#include <string.h>
#include "bpf.h"
+#ifdef __sun
+#include "bpf-dlpi.h"
+#endif
#include "logerr.h"
const char *bpf_name = "Berkeley Packet Filter";
if (bpf->bpf_buffer == NULL)
goto eexit;
+#ifdef __sun
+ if (bpf_dlpi_open(bpf) == -1)
+ goto eexit;
+#endif
+
return bpf;
eexit:
void
bpf_close(struct bpf *bpf)
{
+#ifdef __sun
+ bpf_dlpi_close(bpf);
+#endif
if (bpf->bpf_fd != -1)
close(bpf->bpf_fd);
free(bpf->bpf_buffer);
--- /dev/null
+/*
+ * BPF DLPI interface
+ * SPDX-License-Identifier: BSD-2-Clause
+ * Copyright (c) 2006-2025 Roy Marples <roy@marples.name>
+ * All rights reserved
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <net/if.h>
+#include <netinet/if_ether.h>
+
+#include <errno.h>
+#include <libdlpi.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bpf.h"
+#include "bpf-dlpi.h"
+
+struct bpf_dlpi {
+ dlpi_handle_t bd_handle;
+ void *bd_buffer;
+ size_t bd_bufferlen;
+};
+
+int
+bpf_dlpi_open(struct bpf *bpf)
+{
+ const struct interface *ifp = bpf->bpf_ifp;
+ struct bpf_dlpi *bd;
+ int mtu;
+
+ bd = calloc(1, sizeof(*bd));
+ if (bd == NULL)
+ return -1;
+
+ if (dlpi_open(ifp->name, &bd->bd_handle, DLPI_RAW) != DLPI_SUCCESS) {
+ free(bd);
+ return -1;
+ }
+
+ bpf->bpf_handle = bd;
+
+ if (dlpi_bind(bd->bd_handle, DLPI_ANY_SAP, NULL) != DLPI_SUCCESS)
+ return -1;
+
+ mtu = ifp->mtu ? ifp->mtu : ETHERMTU;
+ bd->bd_bufferlen = bpf_frame_header_len(ifp) + (size_t)mtu;
+ bd->bd_buffer = malloc(bd->bd_bufferlen);
+ if (bpf->bpf_buffer == NULL)
+ return -1;
+
+ return 0;
+}
+
+ssize_t
+bpf_writev(const struct bpf *bpf, struct iovec *iov, int iovcnt)
+{
+ struct bpf_dlpi *bd = bpf->bpf_handle;
+ int i;
+ size_t len = 0;
+ uint8_t *bp = bd->bd_buffer;
+
+ for (i = 0; i < iovcnt; i++) {
+ /* This should be impossible. */
+ if (iov[i].iov_len > bd->bd_bufferlen - len) {
+ errno = ENOBUFS;
+ return -1;
+ }
+
+ memcpy(bp, iov[i].iov_base, iov[i].iov_len);
+ bp += iov[i].iov_len;
+ len += iov[i].iov_len;
+ }
+
+ i = dlpi_send(bd->bd_handle, NULL, 0, bd->bd_buffer, len, NULL);
+ return i == DLPI_SUCCESS ? (ssize_t)len : -1;
+}
+
+void
+bpf_dlpi_close(struct bpf *bpf)
+{
+ struct bpf_dlpi *bd = bpf->bpf_handle;
+
+ if (bd == NULL)
+ return;
+
+ dlpi_close(bd->bd_handle);
+ free(bd->bd_buffer);
+ free(bd);
+}
--- /dev/null
+/*
+ * BPF DLPI interface
+ * SPDX-License-Identifier: BSD-2-Clause
+ * Copyright (c) 2006-2025 Roy Marples <roy@marples.name>
+ * All rights reserved
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef BPF_DLPI_HEADER
+#define BPF_DLPI_HEADER
+
+struct bpf;
+
+int bpf_dlpi_open(struct bpf *);
+void bpf_dlpi_close(struct bpf *);
+#endif
}
}
-#ifndef __sun
ssize_t
bpf_send(const struct bpf *bpf, uint16_t protocol, const void *data, size_t len)
{
return bpf_writev(bpf, iov, __arraycount(iov));
}
-#endif
#ifdef ARP
#define BPF_CMP_HWADDR_LEN ((((HWADDR_LEN / 4) + 2) * 2) + 1)
* SUCH DAMAGE.
*/
+/* Stop sunos headers including the system queue ... */
+#include "queue.h"
+
#include <sys/ioctl.h>
#include <sys/mac.h>
#include <sys/pfmod.h>
#include <sys/tihdr.h>
#include <sys/utsname.h>
+#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
-#include <netinet/udp.h>
#include <netinet/if_ether.h>
+#include <netinet/in.h>
+#include <netinet/udp.h>
#include <assert.h>
#include <errno.h>
}
#ifdef INET
-/* XXX We should fix this to write via the BPF interface. */
-ssize_t
-bpf_send(const struct bpf *bpf, uint16_t protocol, const void *data, size_t len)
-{
- const struct interface *ifp = bpf->bpf_ifp;
- dlpi_handle_t dh;
- dlpi_info_t di;
- int r;
-
- if (dlpi_open(ifp->name, &dh, 0) != DLPI_SUCCESS)
- return -1;
- if ((r = dlpi_info(dh, &di, 0)) == DLPI_SUCCESS &&
- (r = dlpi_bind(dh, protocol, NULL)) == DLPI_SUCCESS)
- r = dlpi_send(dh, di.di_bcastaddr, ifp->hwlen, data, len, NULL);
- dlpi_close(dh);
- return r == DLPI_SUCCESS ? (ssize_t)len : -1;
-}
-
int
if_address(unsigned char cmd, const struct ipv4_addr *ia)
{