- Fixed a cosmetic bug where pretty-printing valid domain-search options would
result in an erroneous error log message ('garbage in format string').
+- A bug in DLPI packet transmission (Solaris, HP/UX) that caused the server
+ to stop receiving packets is fixed. The same fix also means that the MAC
+ address will no longer appear 'bogus' on DLPI-based systems.
+
+- A bug in select handling was discovered where the results of one select()
+ call were discarded, causing the server to process the next select() call
+ and use more system calls than required. This has been repaired - the
+ sockets will be handled after the first return from select(), resulting in
+ fewer system calls.
+
Changes since 4.1.0b1
- A missing "else" in dhcrelay.c could have caused an interface not to
log_fatal ("Can't open DLPI device for %s: %m", info -> name);
}
-
/*
* Submit a DL_INFO_REQ request, to find the dl_mac_type and
* dl_provider_style
}
#endif
- get_hw_addr(info->name, &info->hw_address);
-
return sock;
}
#endif
if (length <= 0) {
+ log_error("receive_packet: %m");
return length;
}
memcpy ((char *) &hfrom -> hbuf [1], srcaddr, phys_len);
}
else {
- memcpy ((char *) &hfrom -> hbuf [1], (char *) &srcaddr [phys_len],
- phys_len);
+ memcpy((char *)&hfrom->hbuf[1], srcaddr + sap_len, phys_len);
}
}
else if (hfrom) {
offset = decode_udp_ip_header (interface, dbuf, bufix,
from, length, &paylen);
- /* If the IP or UDP checksum was bad, skip the packet... */
+ /*
+ * If the IP or UDP checksum was bad, skip the packet...
+ *
+ * Note: this happens all the time when writing packets via the
+ * fallback socket. The packet received by streams does not have
+ * the IP or UDP checksums filled in, as those are calculated by
+ * the hardware.
+ */
if (offset < 0) {
- return 0;
+ return 0;
}
bufix += offset;
ctl.maxlen = DLPI_MAXDLBUF;
ctl.len = 0;
ctl.buf = (char *)buf;
-
+
data.maxlen = dlen;
data.len = 0;
data.buf = (char *)dbuf;
-
+
result = getmsg (fd, &ctl, &data, &flags);
-
+
+ /*
+ * The getmsg() manpage says:
+ *
+ * "On successful completion, a non-negative value is returned."
+ *
+ * This suggests that if MOREDATA or MORECTL are set, we error?
+ * This seems to be safe as it never seems to happen. Still,
+ * set a log message, so we know if it ever starts happening.
+ */
if (result != 0) {
+ log_debug("dlpiunitdataind: %m");
return -1;
}
-
+
if (ctl.len < sizeof (dl_unitdata_ind_t) ||
dlp -> unitdata_ind.dl_primitive != DL_UNITDATA_IND) {
return -1;
}
-
+
if (data.len <= 0) {
return data.len;
}
if (daddrlen) {
*daddrlen = dlp -> unitdata_ind.dl_dest_addr_length;
}
-
+
if (grpaddr) {
*grpaddr = dlp -> unitdata_ind.dl_group_address;
}
-
+
return data.len;
}
void
get_hw_addr(const char *name, struct hardware *hw) {
- int sock;
+ int sock, unit;
long buf[DLPI_MAXDLBUF];
union DL_primitives *dlp;
(unsigned long)dlp->info_ack.dl_mac_type);
}
+ if (dlp->info_ack.dl_provider_style == DL_STYLE2) {
+ /*
+ * Attach to the device. If this fails, the device
+ * does not exist.
+ */
+ unit = dlpiunit((char *)name);
+
+ if (dlpiattachreq(sock, unit) < 0 ||
+ dlpiokack(sock, (char *)buf) < 0) {
+ log_fatal("Can't attach DLPI device for %s: %m",
+ name);
+ }
+ }
+
/*
* Submit a DL_PHYS_ADDR_REQ request, to find
* the hardware address.