Hello Debian printing team
As you might know hplip only supports connecting to a printer via ipv4. The
reason is that in io/hpmud/jd.c only AF_INET is used.
Also the file seems have never seen a refactor considering that practically the
same code is copied abut 10 times over..
I have attached a patch that rewrites the part to use getaddrinfo.
Tested with both hp:/net/<type>?hostname=hostname.local
hp:/net/<type>?ip=1.2.3.4 or hp:/net/<type>?ip=fc00::1,
even hp:/net/<type>?ip=fe80::111%interface seems to work
The reason why I don't send upstream is because I have not found a proper way
to contact HP about this, so maybe if there is interest in this enhancement at
least debian and its derivatives will benefit..
Regards
Michael Saxl
--- a/io/hpmud/jd.c 2026-06-27 15:57:57.000000000 +0200
+++ b/io/hpmud/jd.c 2026-06-27 15:57:24.222072547 +0200
@@ -336,71 +336,29 @@
enum HPMUD_RESULT __attribute__ ((visibility ("hidden"))) jd_s_channel_open(mud_channel *pc)
{
mud_device *pd = &msp->device[pc->dindex];
- struct sockaddr_in pin,tmp_pin;
- struct hostent *he;
char buf[HPMUD_LINE_SIZE];
int r, len, port;
enum HPMUD_RESULT stat = HPMUD_R_IO_ERROR;
- bzero(&tmp_pin, sizeof(tmp_pin));
- bzero(&pin, sizeof(pin));
- pin.sin_family = AF_INET;
-
- if(inet_pton(AF_INET, pd->ip, &(tmp_pin.sin_addr))) //Returns 0 when IP is invalid.
- pin.sin_addr.s_addr = inet_addr(pd->ip);
- else
- {
- if((he=gethostbyname(pd->ip)) == NULL)
- {
- BUG("gethostbyname() returned NULL\n");
- goto bugout;
- }
-
- pin.sin_addr = *((struct in_addr *)he->h_addr);
- }
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_STREAM; /* All possible solution seem to be socket */
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0; /* Any protocol */
+ struct addrinfo *result, *rp;
+ char portnumber [7];
switch (pc->index)
{
case HPMUD_PRINT_CHANNEL:
- port = PrintPort[pd->port];
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open print port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to print port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
+ port = PrintPort[pd->port];
break;
case HPMUD_SCAN_CHANNEL:
if (pd->io_mode == HPMUD_DOT4_PHOENIX_MODE)
port = ScanPort1[pd->port];
else
port = ScanPort0[pd->port];
- pin.sin_port = htons(port);
-
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to scan err=%d port %d: %m %s\n", errno, port, pd->uri);
- goto bugout;
- }
- if (pd->io_mode != HPMUD_DOT4_PHOENIX_MODE)
- {
- r = ReadReply(pc);
- if (r != 0)
- {
- BUG("invalid scan response %d port %d %s\n", r, port, pd->uri);
- goto bugout;
- }
- }
break;
case HPMUD_MEMORY_CARD_CHANNEL:
case HPMUD_FAX_SEND_CHANNEL:
@@ -410,170 +368,93 @@
port = GenericPort1[pd->port];
else
port = GenericPort[pd->port];
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
-
- if (pd->io_mode != HPMUD_DOT4_PHOENIX_MODE)
- {
- r = ReadReply(pc);
- if (r != 220)
- {
- BUG("invalid response %d port %d %s\n", r, port, pd->uri);
- goto bugout;
- }
- len = sprintf(buf, "open %d\n", pc->index);
- send(pc->socket, buf, len, 0);
- r = ReadReply(pc);
- if (r != 200)
- {
- BUG("invalid response %d port %d %s\n", r, port, pd->uri);
- goto bugout;
- }
- len = sprintf(buf, "data\n");
- send(pc->socket, "data\n", len, 0);
- r = ReadReply(pc);
- if (r != 200)
- {
- BUG("invalid response %d port %d %s\n", r, port, pd->uri);
- goto bugout;
- }
- }
-
break;
- case HPMUD_EWS_CHANNEL:
- port = 80;
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open ews port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to ews port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- break;
case HPMUD_SOAPSCAN_CHANNEL:
port = 8289;
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open soap-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to soap-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
break;
case HPMUD_SOAPFAX_CHANNEL:
port = 8295;
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open soap-fax port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to soap-fax port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
break;
case HPMUD_MARVELL_SCAN_CHANNEL:
port = 8290; /* same as ScanPort1[1] */
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open marvell-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to marvell-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
break;
case HPMUD_LEDM_SCAN_CHANNEL:
case HPMUD_EWS_LEDM_CHANNEL:
port = 8080;
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open ledm-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to ledm-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
break;
case HPMUD_ESCL_SCAN_CHANNEL:
- port = 80;
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open escl-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to escl-scan port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- break;
+ case HPMUD_EWS_CHANNEL:
case HPMUD_IPP_CHANNEL:
port = 80;
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open ipp port %d: %m %s\n", port, pd->uri);
- port = 631;
- pin.sin_port = htons(port);
- if((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to ipp port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- break;
+ break;
case HPMUD_MARVELL_FAX_CHANNEL:
port = 8285;
- pin.sin_port = htons(port);
- if ((pc->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- BUG("unable to open marvell-fax port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
- if (connect(pc->socket, (struct sockaddr *)&pin, sizeof(pin)) == -1)
- {
- BUG("unable to connect to marvell-fax port %d: %m %s\n", port, pd->uri);
- goto bugout;
- }
break;
case HPMUD_PML_CHANNEL:
/* Do nothing here, use GetPml/SetPml instead of ReadData/WriteData. */
+ return HPMUD_R_OK;
break;
default:
BUG("unsupported service %d %s\n", pc->index, pd->uri);
stat = HPMUD_R_INVALID_SN;
goto bugout;
break;
- }
+ }
+
+ snprintf(portnumber,5,"%d",port);
+
+ if ((r=getaddrinfo(pd->ip, portnumber, &hints, &result)) != 0) {
+ BUG("getaddrinfo: %s\n", gai_strerror(r));
+ goto bugout;
+ }
+
+ /* getaddrinfo() returns a list of address structures.
+ Try each address until we successfully connect(2).
+ If socket(2) (or connect(2)) fails, we (close the socket
+ and) try the next address. */
+
+ for (rp = result; rp != NULL; rp = rp->ai_next) {
+ pc->socket = socket(rp->ai_family, rp->ai_socktype,
+ rp->ai_protocol);
+ if (pc->socket == -1)
+ continue;
+ if (connect(pc->socket , rp->ai_addr, rp->ai_addrlen) != -1)
+ break; /* Success */
+ close(pc->socket);
+ }
+
+ freeaddrinfo(result); /* No longer needed */
+
+ if(rp == NULL) {
+ BUG("unable to open port %d: %m %s\n", port, pd->uri);
+ goto bugout;
+ }
+
+ if (pc->index == HPMUD_CONFIG_DOWNLOAD_CHANNEL && pd->io_mode != HPMUD_DOT4_PHOENIX_MODE)
+ {
+ r = ReadReply(pc);
+ if (r != 220)
+ {
+ BUG("invalid response %d port %d %s\n", r, port, pd->uri);
+ goto bugout;
+ }
+ len = sprintf(buf, "open %d\n", pc->index);
+ send(pc->socket, buf, len, 0);
+ r = ReadReply(pc);
+ if (r != 200)
+ {
+ BUG("invalid response %d port %d %s\n", r, port, pd->uri);
+ goto bugout;
+ }
+ len = sprintf(buf, "data\n");
+ send(pc->socket, "data\n", len, 0);
+ r = ReadReply(pc);
+ if (r != 200)
+ {
+ BUG("invalid response %d port %d %s\n", r, port, pd->uri);
+ goto bugout;
+ }
+ }
stat = HPMUD_R_OK;