We have a bunch of really old PXE clients that ignore IP packets with the
DF bit set, and we cannot (due to security updates on the system) change the
ip_pmtu_strategy in a way that causes hp-ux to not set the DF bit when sending
packets over normal sockets. Thus I forward-ported the DLPI stuff to have
more control.
diff -urp dhcp-3.0.1/common/discover.c dhcp-3.0.1-new/common/discover.c
--- dhcp-3.0.1/common/discover.c 2004-06-10 19:59:16.000000000 +0200
+++ dhcp-3.0.1-new/common/discover.c 2004-08-30 15:25:49.000000000 +0200
@@ -678,9 +678,10 @@ void discover_interfaces (state)
#if defined (HAVE_SETFD)
if (fallback_interface) {
- if (fcntl (fallback_interface -> rfdesc, F_SETFD, 1) < 0)
- log_error ("Can't set close-on-exec on fallback: %m");
- if (fallback_interface -> rfdesc != fallback_interface -> wfdesc) {
+ if ( fallback_interface -> rfdesc != -1)
+ if (fcntl (fallback_interface -> rfdesc, F_SETFD, 1) < 0)
+ log_error ("Can't set close-on-exec on fallback: %m");
+ if ( (fallback_interface -> wfdesc != -1) && (fallback_interface -> rfdesc != fallback_interface -> wfdesc) ) {
if (fcntl (fallback_interface -> wfdesc, F_SETFD, 1) < 0)
log_error ("Can't set close-on-exec on fallback: %m");
}
diff -urp dhcp-3.0.1/common/dlpi.c dhcp-3.0.1-new/common/dlpi.c
--- dhcp-3.0.1/common/dlpi.c 2004-06-10 19:59:17.000000000 +0200
+++ dhcp-3.0.1-new/common/dlpi.c 2004-08-30 15:31:47.000000000 +0200
@@ -77,6 +77,24 @@
* to sleep.
*/
+/*
+ * Notes about HP-UX
+ *
+ * Most of the HP-DLPI code is taken from http://www.j-mulders.demon.nl/unix/hp-related/dlpi.c
+ * which implements the use of the HP-UX DLPI for dhcpd 2.0 (I don't know precisely
+ * which version, it is not the latest).
+ *
+ * Some more code was taken from revision 1.107 of pcap-dlpi.c
+ * from the libpcap project, which is licensed under a BSD license.
+ * See http://cvs.tcpdump.org/cgi-bin/cvsweb/libpcap/pcap-dlpi.c?rev=1.107
+ * for the exact sources.
+ * Specifically, split_dname, send_dlpi_request and get_dlpi_ppa were taken
+ * from there and adapted to dhcpd's error handling etc.
+ *
+ * August 2004, Johannes Berg <johannes@sipsolutions.net>
+ */
+
+
#ifndef lint
static char copyright[] =
"$Id: dlpi.c,v 1.28.2.2 2004/06/10 17:59:17 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
@@ -102,6 +120,11 @@ static char copyright[] =
# include "includes/netinet/udp.h"
# include "includes/netinet/if_ether.h"
+#ifdef HP_DLPI
+# include <sys/dlpi_ext.h>
+# define HP_DLPI_DEVICE "/dev/dlpi"
+#endif
+
# ifdef USE_DLPI_PFMOD
# ifdef USE_DLPI_RAW
# define DLPI_MODNAME "DLPI+RAW+PFMOD"
@@ -112,7 +135,11 @@ static char copyright[] =
# ifdef USE_DLPI_RAW
# define DLPI_MODNAME "DLPI+RAW"
# else
-# define DLPI_MODNAME "DLPI"
+# ifdef HP_DLPI
+# define DLPI_MODNAME "HP-DLPI"
+# else
+# define DLPI_MODNAME "DLPI"
+# endif
# endif
# endif
@@ -120,6 +147,10 @@ static char copyright[] =
# define ABS(x) ((x) >= 0 ? (x) : 0-(x))
# endif
+#if defined(HP_DLPI) && defined(USE_DLPI_RECEIVE)
+# error "HP_DLPI and USE_DLPI_RECEIVE are incompatible"
+#endif
+
static int strioctl PROTO ((int fd, int cmd, int timeout, int len, char *dp));
#define DLPI_MAXDLBUF 8192 /* Buffer size */
@@ -127,7 +158,10 @@ static int strioctl PROTO ((int fd, int
#define DLPI_DEVDIR "/dev/" /* Device directory */
static int dlpiopen PROTO ((char *ifname));
-static int dlpiunit PROTO ((char *ifname));
+#ifdef HP_DLPI
+static char * split_dname PROTO ((char *device, int *unitp));
+#endif
+static int dlpiunit PROTO ((int fd, char *ifname));
static int dlpiinforeq PROTO ((int fd));
static int dlpiphysaddrreq PROTO ((int fd, unsigned long addrtype));
static int dlpiattachreq PROTO ((int fd, unsigned long ppa));
@@ -241,7 +275,7 @@ int if_register_dlpi (info)
* Attach to the device. If this fails, the device
* does not exist.
*/
- unit = dlpiunit (info -> name);
+ unit = dlpiunit (sock, info -> name);
if (dlpiattachreq (sock, unit) < 0
|| dlpiokack (sock, (char *)buf) < 0) {
@@ -252,7 +286,31 @@ int if_register_dlpi (info)
/*
* Bind to the IP service access point (SAP), connectionless (CLDLS).
*/
+
+#ifdef HP_DLPI
+ /*
+ * AAARRRGGGGGGH !!!!!!
+ *
+ * We want to bind (talk here, and listen for) .. ETHERTYPE_IP (0x800).
+ * This does not work. It responds with DL_BADARR (0x04).
+ *
+ * The manual: Valid ethernet types range from 0x600 to 0xFFFF,
+ * excluding reserved ethertypes.
+ *
+ * Sjjjeeeeezzzz !
+ *
+ * Bind here to an unexisting SAP and use raw dlpi for
+ * sending packets.
+ * This means we cannot use dlpi's filtering capabilities for RECEIVING
+ * ethertype_ip packets. This will mean even more packets to appear in
+ * the userland filter. DLPI_RECEIVE without a packetfilter is a bad
+ * thing and therefore not done.
+ *
+ */
+ if (dlpibindreq (sock, ETHERTYPE_IP+1, 0, DL_HP_RAWDLS, 0, 0) < 0
+#else
if (dlpibindreq (sock, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0) < 0
+#endif
|| dlpibindack (sock, (char *)buf) < 0) {
log_fatal ("Can't bind DLPI device for %s: %m", info -> name);
}
@@ -347,7 +405,8 @@ void if_register_send (info)
#endif
if (!quiet_interface_discovery)
- log_info ("Sending on DLPI/%s/%s%s%s",
+ log_info ("Sending on %s/%s/%s%s%s",
+ DLPI_MODNAME,
info -> name,
print_hw_addr (info -> hw_address.hbuf [0],
info -> hw_address.hlen - 1,
@@ -377,7 +436,8 @@ void if_deregister_send (info)
info -> wfdesc = -1;
if (!quiet_interface_discovery)
- log_info ("Disabling output on DLPI/%s/%s%s%s",
+ log_info ("Disabling output on %s/%s/%s%s%s",
+ DLPI_MODNAME,
info -> name,
print_hw_addr (info -> hw_address.hbuf [0],
info -> hw_address.hlen - 1,
@@ -462,7 +522,8 @@ void if_register_receive (info)
#endif /* USE_DLPI_PFMOD */
if (!quiet_interface_discovery)
- log_info ("Listening on DLPI/%s/%s%s%s",
+ log_info ("Listening on %s/%s/%s%s%s",
+ DLPI_MODNAME,
info -> name,
print_hw_addr (info -> hw_address.hbuf [0],
info -> hw_address.hlen - 1,
@@ -492,7 +553,8 @@ void if_deregister_receive (info)
info -> rfdesc = -1;
if (!quiet_interface_discovery)
- log_info ("Disabling input on DLPI/%s/%s%s%s",
+ log_info ("Disabling input on %s/%s/%s%s%s",
+ DLPI_MODNAME,
info -> name,
print_hw_addr (info -> hw_address.hbuf [0],
info -> hw_address.hlen - 1,
@@ -513,6 +575,52 @@ ssize_t send_packet (interface, packet,
struct sockaddr_in *to;
struct hardware *hto;
{
+#ifdef HP_DLPI
+ int result;
+ struct strbuf dlpi_ctrl;
+ struct strbuf dlpi_data;
+ u_long dlpi_ctrl_area [1500];
+ u_long dlpi_data_area [1500];
+ dl_hp_rawdata_req_t *rawdat_req;
+ /*
+ * check if we need to fallback
+ */
+ if (!strcmp (interface -> name, "fallback"))
+ return send_fallback (interface, packet, raw,
+ len, from, to, hto);
+ /*
+ * send the packet using DLPI
+ */
+ dlpi_ctrl.maxlen = sizeof (dlpi_ctrl_area);
+ dlpi_ctrl.buf = (char *) dlpi_ctrl_area;
+ dlpi_ctrl.len = 0;
+
+ dlpi_data.maxlen = sizeof (dlpi_data_area);
+ dlpi_data.buf = (char *) dlpi_data_area;
+ dlpi_data.len = 0;
+
+ assemble_hw_header (interface, (unsigned char*)dlpi_data.buf, (unsigned*)&dlpi_data.len, hto);
+ assemble_udp_ip_header (interface, (unsigned char*)dlpi_data.buf,
+ (unsigned*)&dlpi_data.len, from.s_addr,
+ to -> sin_addr.s_addr, to -> sin_port,
+ (unsigned char *)raw, len);
+
+ /*
+ * append the data for this packet
+ */
+ memcpy ((u_char *) dlpi_data.buf + dlpi_data.len, raw, len);
+ dlpi_data.len += len;
+
+ rawdat_req = (dl_hp_rawdata_req_t *) dlpi_ctrl.buf;
+ rawdat_req -> dl_primitive = DL_HP_RAWDATA_REQ;
+ dlpi_ctrl.len = sizeof (dl_unitdata_req_t);
+ dlpi_ctrl.maxlen = 0;
+
+ if ((result = putmsg (interface -> wfdesc, &dlpi_ctrl, &dlpi_data, 0)) < 0)
+ log_error ("send_packet: %m");
+ return result;
+
+#else
unsigned hbufp = 0;
double hh [32];
double ih [1536 / sizeof (double)];
@@ -600,6 +708,7 @@ ssize_t send_packet (interface, packet,
if (result < 0)
log_error ("send_packet: %m");
return result;
+#endif /* HP_DLPI */
}
#endif /* USE_DLPI_SEND */
@@ -715,15 +824,292 @@ ssize_t receive_packet (interface, buf,
#define DLPI_MAXWAIT 15 /* Max timeout */
+#ifdef HP_DLPI
+/*
+ * The code in this section is from libpcap
+ */
+
+
+/*
+ * Split a device name into a device type name and a unit number;
+ * return the a pointer to the beginning of the unit number, which
+ * is the end of the device type name, and set "*unitp" to the unit
+ * number.
+ */
+static char *
+split_dname(char *device, int *unitp)
+{
+ char *cp;
+ char *eos;
+ long unit;
+
+ /*
+ * Look for a number at the end of the device name string.
+ */
+ cp = device + strlen(device) - 1;
+ if (*cp < '0' || *cp > '9') {
+ log_fatal("%s missing unit number",
+ device);
+ return (NULL);
+ }
+
+ /* Digits at end of string are unit number */
+ while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9')
+ cp--;
+
+ errno = 0;
+ unit = strtol(cp, &eos, 10);
+ if (*eos != '\0') {
+ log_fatal("%s bad unit number", device);
+ return (NULL);
+ }
+ if (errno == ERANGE || unit > INT_MAX) {
+ log_fatal("%s unit number too large",
+ device);
+ return (NULL);
+ }
+ if (unit < 0) {
+ log_fatal("%s unit number is negative",
+ device);
+ return (NULL);
+ }
+ *unitp = (int)unit;
+ return (cp);
+}
+
+static int
+send_dlpi_request(fd, ptr, len, what)
+ int fd;
+ char * ptr;
+ int len;
+ char * what;
+{
+ struct strbuf ctl;
+ int flags;
+
+ ctl.maxlen = 0;
+ ctl.len = len;
+ ctl.buf = ptr;
+
+ flags = 0;
+ if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
+ log_fatal ("send_dlpi_request: putmsg error");
+ return (-1);
+ }
+ return (0);
+}
+
/*
- * Parse an interface name and extract the unit number
+ * Determine ppa number that specifies ifname.
+ *
+ * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member,
+ * the code that's used here is the old code for HP-UX 10.x.
+ *
+ * However, HP-UX 10.20, at least, appears to have such a member
+ * in its "dl_hp_ppa_info_t" structure, so the new code is used.
+ * The new code didn't work on an old 10.20 system on which Rick
+ * Jones of HP tried it, but with later patches installed, it
+ * worked - it appears that the older system had those members but
+ * didn't put anything in them, so, if the search by name fails, we
+ * do the old search.
+ *
+ * Rick suggests that making sure your system is "up on the latest
+ * lancommon/DLPI/driver patches" is probably a good idea; it'd fix
+ * that problem, as well as allowing libpcap to see packets sent
+ * from the system on which the libpcap application is being run.
+ * (On 10.20, in addition to getting the latest patches, you need
+ * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB;
+ * a posting to "comp.sys.hp.hpux" at
+ *
+ * http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266
+ *
+ * says that, to see the machine's outgoing traffic, you'd need to
+ * apply the right patches to your system, and also set that variable
+ * with:
+
+echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem
+
+ * which could be put in, for example, "/sbin/init.d/lan".
+ *
+ * Setting the variable is not necessary on HP-UX 11.x.
+ */
+static int
+get_dlpi_ppa(register int fd, register const char *device, register int unit)
+{
+ register dl_hp_ppa_ack_t *ap;
+ register dl_hp_ppa_info_t *ipstart, *ip;
+ register int i;
+ char dname[100];
+ register u_long majdev;
+ struct stat statbuf;
+ dl_hp_ppa_req_t req;
+ char buf[DLPI_MAXDLBUF];
+ char *ppa_data_buf;
+ dl_hp_ppa_ack_t *dlp;
+ struct strbuf ctl;
+ int flags;
+ int ppa;
+
+ memset((char *)&req, 0, sizeof(req));
+ req.dl_primitive = DL_HP_PPA_REQ;
+
+ memset((char *)buf, 0, sizeof(buf));
+ if (send_dlpi_request(fd, (char *)&req, sizeof(req), "hpppa") < 0)
+ return (-1);
+
+ ctl.maxlen = DL_HP_PPA_ACK_SIZE;
+ ctl.len = 0;
+ ctl.buf = (char *)buf;
+
+ flags = 0;
+ /*
+ * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal
+ * recv_ack will fail because it set the maxlen to MAXDLBUF (8192)
+ * which is NOT big enough for a DL_HP_PPA_REQ.
+ *
+ * This causes libpcap applications to fail on a system with HP-APA
+ * installed.
+ *
+ * To figure out how big the returned data is, we first call getmsg
+ * to get the small head and peek at the head to get the actual data
+ * length, and then issue another getmsg to get the actual PPA data.
+ */
+ /* get the head first */
+ if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
+ log_fatal ("get_dlpi_ppa: hpppa getmsg error");
+ return (-1);
+ }
+
+ dlp = (dl_hp_ppa_ack_t *)ctl.buf;
+ if (dlp->dl_primitive != DL_HP_PPA_ACK) {
+ log_fatal("get_dlpi_ppa: hpppa unexpected primitive ack0x%x",
+ (int)dlp->dl_primitive);
+ return (-1);
+ }
+
+ if (ctl.len < DL_HP_PPA_ACK_SIZE) {
+ log_fatal ("get_dlpi_ppa: hpppa ack too small (%d < %lu)",
+ ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
+ return (-1);
+ }
+
+ /* allocate buffer */
+ if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
+ log_fatal("get_dlpi_ppa: hpppa malloc error number %d", errno);
+ return (-1);
+ }
+ ctl.maxlen = dlp->dl_length;
+ ctl.len = 0;
+ ctl.buf = (char *)ppa_data_buf;
+ /* get the data */
+ if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
+ log_fatal("get_dlpi_ppa: hpppa getmsg error number %d", errno);
+ free(ppa_data_buf);
+ return (-1);
+ }
+ if (ctl.len < dlp->dl_length) {
+ log_fatal ("get_dlpi_ppa: hpppa ack too small (%d < %d)",
+ ctl.len, dlp->dl_length);
+ free(ppa_data_buf);
+ return (-1);
+ }
+
+ ap = (dl_hp_ppa_ack_t *)buf;
+ ipstart = (dl_hp_ppa_info_t *)ppa_data_buf;
+ ip = ipstart;
+
+ /*
+ * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1"
+ * member that should, in theory, contain the part of the
+ * name for the device that comes before the unit number,
+ * and should also have a "dl_module_id_2" member that may
+ * contain an alternate name (e.g., I think Ethernet devices
+ * have both "lan", for "lanN", and "snap", for "snapN", with
+ * the former being for Ethernet packets and the latter being
+ * for 802.3/802.2 packets).
+ *
+ * Search for the device that has the specified name and
+ * instance number.
+ */
+ for (i = 0; i < ap->dl_count; i++) {
+ if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 ||
+ strcmp((const char *)ip->dl_module_id_2, device) == 0) &&
+ ip->dl_instance_num == unit)
+ break;
+
+ ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset);
+ }
+
+ if (i == ap->dl_count) {
+ /*
+ * Well, we didn't, or can't, find the device by name.
+ *
+ * HP-UX 10.20, whilst it has "dl_module_id_1" and
+ * "dl_module_id_2" fields in the "dl_hp_ppa_info_t",
+ * doesn't seem to fill them in unless the system is
+ * at a reasonably up-to-date patch level.
+ *
+ * Older HP-UX 10.x systems might not have those fields
+ * at all.
+ *
+ * Therefore, we'll search for the entry with the major
+ * device number of a device with the name "/dev/<dev><unit>",
+ * if such a device exists, as the old code did.
+ */
+ snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
+ if (stat(dname, &statbuf) < 0) {
+ log_fatal ("stat: %s: %d",
+ dname, errno);
+ return (-1);
+ }
+ majdev = major(statbuf.st_rdev);
+
+ ip = ipstart;
+
+ for (i = 0; i < ap->dl_count; i++) {
+ if (ip->dl_mjr_num == majdev &&
+ ip->dl_instance_num == unit)
+ break;
+
+ ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset);
+ }
+ }
+ if (i == ap->dl_count) {
+ log_fatal("can't find /dev/dlpi PPA for %s%d", device, unit);
+ return (-1);
+ }
+ if (ip->dl_hdw_state == HDW_DEAD) {
+ log_fatal("%s%d: hardware state: DOWN\n", device, unit);
+ free(ppa_data_buf);
+ return (-1);
+ }
+ ppa = ip->dl_ppa;
+ free(ppa_data_buf);
+ return (ppa);
+}
+#endif
+
+/*
+ * Parse an interface name and extract the unit number.
+ * This does not necessarily work on HP-UX always, so use
+ * different code there.
*/
-static int dlpiunit (ifname)
+static int dlpiunit (fd, ifname)
+ int fd; /* only used for HP-UX */
char *ifname;
{
- int fd;
+#ifdef HP_DLPI
+ char * res;
+ int unitnumber;
+ char tmpbuf[100];
+ tmpbuf[99]=0;
+ strncpy(tmpbuf, ifname, 99);
+ res = split_dname(tmpbuf, &unitnumber);
+ *res = 0; /* 0 terminate device type name */
+ return get_dlpi_ppa (fd, tmpbuf, unitnumber);
+#else
char *cp, *dp, *ep;
int unit;
@@ -745,6 +1131,7 @@ static int dlpiunit (ifname)
}
return unit;
+#endif
}
/*
@@ -753,6 +1140,9 @@ static int dlpiunit (ifname)
static int dlpiopen (ifname)
char *ifname;
{
+#ifdef HP_DLPI
+ return open(HP_DLPI_DEVICE, O_RDWR);
+#else
char devname [50];
char *cp, *dp, *ep;
@@ -784,6 +1174,7 @@ static int dlpiopen (ifname)
*dp = '\0';
return open (devname, O_RDWR, 0);
+#endif
}
/*
@@ -1034,7 +1425,7 @@ static int dlpiinfoack (fd, bufp)
/*
* dlpiphysaddrack - receive an ack to a dlpiphysaddrreq.
*/
-int dlpiphysaddrack (fd, bufp)
+static int dlpiphysaddrack (fd, bufp)
char *bufp;
int fd;
{
@@ -1065,7 +1456,7 @@ int dlpiphysaddrack (fd, bufp)
return 0;
}
-int dlpiunitdatareq (fd, addr, addrlen, minpri, maxpri, dbuf, dbuflen)
+static int dlpiunitdatareq (fd, addr, addrlen, minpri, maxpri, dbuf, dbuflen)
int fd;
unsigned char *addr;
int addrlen;
@@ -1080,7 +1471,11 @@ int dlpiunitdatareq (fd, addr, addrlen,
/* Set up the control information... */
dlp = (union DL_primitives *)buf;
+ #ifdef HP_DLPI
+ dlp -> unitdata_req.dl_primitive = DL_HP_RAWDATA_REQ;
+ #else
dlp -> unitdata_req.dl_primitive = DL_UNITDATA_REQ;
+ #endif
dlp -> unitdata_req.dl_dest_addr_length = addrlen;
dlp -> unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t);
dlp -> unitdata_req.dl_priority.dl_min = minpri;
diff -urp dhcp-3.0.1/common/socket.c dhcp-3.0.1-new/common/socket.c
--- dhcp-3.0.1/common/socket.c 2004-06-10 19:59:21.000000000 +0200
+++ dhcp-3.0.1-new/common/socket.c 2004-08-30 15:24:17.000000000 +0200
@@ -153,6 +153,8 @@ int if_register_socket (info)
}
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */
+static int read_file_descriptor;
+
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_FALLBACK)
void if_register_send (info)
struct interface_info *info;
@@ -165,7 +167,7 @@ void if_register_send (info)
info -> rfdesc = info -> wfdesc;
#endif
#else
- info -> wfdesc = info -> rfdesc;
+ info -> wfdesc = read_file_descriptor;
#endif
if (!quiet_interface_discovery)
log_info ("Sending on Socket/%s%s%s",
@@ -200,7 +202,7 @@ void if_register_receive (info)
{
/* If we're using the socket API for sending and receiving,
we don't need to register this interface twice. */
- info -> rfdesc = if_register_socket (info);
+ read_file_descriptor = info -> rfdesc = if_register_socket (info);
if (!quiet_interface_discovery)
log_info ("Listening on Socket/%s%s%s",
info -> name,
diff -urp dhcp-3.0.1/includes/cf/hpux.h dhcp-3.0.1-new/includes/cf/hpux.h
--- dhcp-3.0.1/includes/cf/hpux.h 2004-06-14 20:50:06.000000000 +0200
+++ dhcp-3.0.1-new/includes/cf/hpux.h 2004-08-30 15:24:17.000000000 +0200
@@ -81,7 +81,9 @@ extern int h_errno;
#define VA_start(list, last) va_start (list)
#endif
-#define USE_SOCKETS 1
+#define USE_SOCKET_RECEIVE 1
+#define USE_DLPI_SEND 1
+#define HP_DLPI 1
#define EOL '\n'
#define VOIDPTR void *