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;
 

Reply via email to