PATCH: Add -i IFACE option to wget

Denis Vlasenko vda.linux at googlemail.com
Thu Oct 26 00:10:28 UTC 2006


On Wednesday 25 October 2006 15:02, Raphaël HUCK wrote:
> Here is the patch which applies to the last version from svn (16429).

Okay...

                if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
                        bb_error_msg_and_die("can't bind to %s", iface);
                memset(&addr, 0, sizeof(struct sockaddr_in));
                addr.sin_family = AF_INET;
                sa = (struct sockaddr_in *)&ifr.ifr_addr;
                memcpy(&addr.sin_addr, &sa->sin_addr, sizeof(struct in_addr));

So you are finding out IPv4 address of the iface.
Looks like you are doing something very similar to
regular wget's --bind-address=ADDRESS.

Is there any special reason to implement what you need
in incompatible way? There are real benefits in being compatible.

(side note: we probably are close to needing libbb function
a2sockaddr(), which will be able to convert IPv4 _and_ IPv6
into struct sockaddr...)

By the way:
what will happen if iface has IPv6 addr only?
what will happen if interface has 2 IP addresses?

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <string.h>
int main(int argc, char *argv[]) {
    struct if_nameindex *ifnames, *ifnm;
    struct ifreq ifr;
    struct sockaddr_in sin, destaddr;
    int sock;

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    ifnames = if_nameindex();
    for(ifnm = ifnames; ifnm && ifnm->if_name && ifnm->if_name[0]; ifnm++) {
        strncpy(ifr.ifr_name, ifnm->if_name, IFNAMSIZ);
        if(ioctl(sock, SIOCGIFADDR, &ifr) == 0) {
            memcpy(&sin, &(ifr.ifr_addr), sizeof(sin));
            printf("Interface %s = IP %s, sin.sin_family %d (AF_INET=%d)\n",
                ifnm->if_name, inet_ntoa(sin.sin_addr), sin.sin_family, AF_INET);
        }
    }
    if_freenameindex(ifnames);
    return 0;
}

# ./a.out
Interface lo = IP 127.0.0.1, sin.sin_family 2 (AF_INET=2)
Interface if = IP 192.168.1.111, sin.sin_family 2 (AF_INET=2)
# ip a
1: lo: <LOOPBACK,UP,10000> mtu 16436 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet 127.0.0.2/8 scope host secondary lo
2: if: <BROADCAST,MULTICAST,UP,10000> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:16:17:6d:77:db brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.111/24 brd 192.168.1.255 scope global if

See? It did not pick up 127.0.0.2... IPv6 case might be much worse I suspect,
because your code blindly assumes AF_INET!


Reading further...

        if (connect(s, (struct sockaddr *) s_in, sizeof(struct sockaddr_in)) < 0) {
                if (ENABLE_FEATURE_CLEAN_UP) close(s);
                        bb_perror_msg_and_die("can't connect to remote host (%s)",
                inet_ntoa(s_in->sin_addr));
        }

Why not xconnect? Aha.. our xconnect is not conforming to "be like libc one"
xfunc rule.... I'm fixing it now...

Please find modified wget.c attached. Please fix code so that IPv6 case
will not be catastrofic or better yet reimplement it as --bind-address.

Please submit patch so that it can be applied with "patch -p1 <patchname"
issued in top directory of source tree.

Thank you for your efforts.
--
vda
-------------- next part --------------
A non-text attachment was scrubbed...
Name: wget.c.bz2
Type: application/x-bzip2
Size: 8162 bytes
Desc: not available
Url : http://lists.busybox.net/pipermail/busybox/attachments/20061026/b3428beb/attachment-0002.bin 


More information about the busybox mailing list