allow tun/tap specification without IP address

This commit is contained in:
Gerhard Rieger 2012-11-16 21:08:46 +01:00
parent 46313470b8
commit dbb6ea3a52
3 changed files with 35 additions and 31 deletions

View file

@ -133,6 +133,8 @@ new features:
added option max-children that limits the number of concurrent child
processes. Thanks to Sam Liddicott for providing the patch.
Till Maas added support for tun/tap addresses without IP address
####################### V 2.0.0-b7:
security:

View file

@ -1021,12 +1021,13 @@ label(ADDRESS_TCP6_LISTEN)dit(bf(tt(TCP6-LISTEN:<port>)))
Additional useful option:
link(ipv6only)(OPTION_IPV6_V6ONLY)nl()
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl()
label(ADDRESS_TUN)dit(bf(tt(TUN:<if-addr>/<bits>)))
Creates a Linux TUN/TAP device and assignes to it the address and netmask
defined by the parameters. The resulting network interface is ready for use
by other processes; socat() serves its "wire side". This address requires read
and write access to the tunnel cloning device, usually code(/dev/net/tun).
nl()
label(ADDRESS_TUN)dit(bf(tt(TUN[:<if-addr>/<bits>])))
Creates a Linux TUN/TAP device and optionally assignes it the address and
netmask given by the parameters. The resulting network interface is almost
ready for use by other processes; socat serves its "wire side". This address
requires read and write access to the tunnel cloning device, usually
code(/dev/net/tun), as well as permission to set some tt(ioctl()s).
bf(Option iff-up is required to immediately activate the interface!)nl()
Option groups: link(FD)(GROUP_FD),link(NAMED)(GROUP_NAMED),link(OPEN)(GROUP_OPEN),link(TUN)(GROUP_TUN) nl()
Useful options:
link(iff-up)(OPTION_IFF_UP),

View file

@ -83,8 +83,8 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
char *ifaddr;
int result;
if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)",
if (argc > 2 || argc < 0) {
Error2("%s: wrong number of parameters (%d instead of 0 or 1)",
argv[0], argc-1);
}
@ -152,30 +152,31 @@ static int xioopen_tun(int argc, const char *argv[], struct opt *opts, int xiofl
}
/*--------------------- setting interface address and netmask ------------*/
if ((ifaddr = strdup(argv[1])) == NULL) {
Error1("strdup(\"%s\"): out of memory", argv[1]);
return STAT_RETRYLATER;
if (argc == 2) {
if ((ifaddr = strdup(argv[1])) == NULL) {
Error1("strdup(\"%s\"): out of memory", argv[1]);
return STAT_RETRYLATER;
}
if ((result = xioparsenetwork(ifaddr, pf, &network)) != STAT_OK) {
/*! recover */
return result;
}
socket_init(pf, (union sockaddr_union *)&ifr.ifr_addr);
((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr =
network.netaddr.ip4.sin_addr;
if (Ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
Error4("ioctl(%d, SIOCSIFADDR, {\"%s\", \"%s\"}: %s",
sockfd, ifr.ifr_name, ifaddr, strerror(errno));
}
((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr =
network.netmask.ip4.sin_addr;
if (Ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
Error4("ioctl(%d, SIOCSIFNETMASK, {\"0x%08u\", \"%s\"}, %s",
sockfd, ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr,
ifaddr, strerror(errno));
}
free(ifaddr);
}
if ((result = xioparsenetwork(ifaddr, pf, &network)) != STAT_OK) {
/*! recover */
return result;
}
socket_init(pf, (union sockaddr_union *)&ifr.ifr_addr);
((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr =
network.netaddr.ip4.sin_addr;
if (Ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
Error4("ioctl(%d, SIOCSIFADDR, {\"%s\", \"%s\"}: %s",
sockfd, ifr.ifr_name, ifaddr, strerror(errno));
}
((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr =
network.netmask.ip4.sin_addr;
if (Ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
Error4("ioctl(%d, SIOCSIFNETMASK, {\"0x%08u\", \"%s\"}, %s",
sockfd, ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr,
ifaddr, strerror(errno));
}
free(ifaddr);
/*--------------------- setting interface flags --------------------------*/
applyopts_single(&xfd->stream, opts, PH_FD);