Sorry about the noise.. There was a issue and a compiler warning in the original patch. This should fix that. Also I renamed the file to simply getaddrinfo.patch since I don't own the numbering.
> 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
Description: change socket opening to use getaddrinfo Author: Michael Saxl <[email protected]> --- a/io/hpmud/jd.c 2024-08-13 23:38:20.000000000 +0200 +++ b/io/hpmud/jd.c 2026-06-27 17:01:31.429920558 +0200 @@ -335,71 +335,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; + int r, len, port, mem_fax_cfg_chnl = 0; 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; + hints.ai_flags = 0; + hints.ai_protocol = 0; /* Any protocol, in practice TCP when SOCK_STREAM */ + 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: @@ -409,170 +367,103 @@ 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; - } - } - + mem_fax_cfg_chnl = 1; 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,6,"%u",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 (mem_fax_cfg_chnl && 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; + } + } + else if (pc->index == HPMUD_SCAN_CHANNEL && 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; + } + } stat = HPMUD_R_OK;
