* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <time.h>
#include <memory.h>
+#ifdef HAVE_UTMP_H
#include <utmp.h>
+#endif
#include <mntent.h>
#include <signal.h>
#include <fcntl.h>
if (x == 0 && req_ifname[0] != '\0') {
struct ifreq ifr;
- char t[MAXIFNAMELEN];
+ char t[IFNAMSIZ];
memset(&ifr, 0, sizeof(struct ifreq));
slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
- strlcpy(ifr.ifr_name, t, IF_NAMESIZE);
- strlcpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE);
+ strlcpy(ifr.ifr_name, t, IFNAMSIZ);
+ strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
if (x < 0)
error("Couldn't rename interface %s to %s: %m", t, req_ifname);
while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
if (errno != EINTR)
fatal("tcsetattr: %m (line %d)", __LINE__);
+ restore_term = 1;
/* Most Linux architectures and drivers support arbitrary baud rate values via BOTHER */
#ifdef TCGETS2
else
fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
}
-
- restore_term = 1;
}
/********************************************************************
/* error == 0 indicates success, negative value is errno code */
if (nlresp.nlerr.error != 0) {
- error("sif6addr_rtnetlink: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
+ /*
+ * Linux kernel versions prior 3.11 do not support setting IPv6 peer
+ * addresses and error response is expected. On older kernel versions
+ * do not show this error message. On error pppd tries to fallback to
+ * the old IOCTL method.
+ */
+ if (kernel_version >= KVERSION(3,11,0))
+ error("sif6addr_rtnetlink: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
return 0;
}
struct in6_ifreq ifr6;
struct ifreq ifr;
struct in6_rtmsg rt6;
+ int ret;
if (sock6_fd < 0) {
errno = -sock6_fd;
if (kernel_version >= KVERSION(2,1,16)) {
/* Set both local address and remote peer address (with route for it) via rtnetlink */
- return sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
+ ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
} else {
+ ret = 0;
+ }
+
+ /*
+ * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
+ * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
+ */
+ if (!ret) {
/* Local interface */
memset(&ifr6, 0, sizeof(ifr6));
IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);