Andreas, p2, This is a known issue that has been fixed upstream on 10/19/2006 in CVS :
*** cvs diff -ub starts here *** diff -u -b -r1.24 -r1.25 --- hercifc.c 23 Apr 2006 04:59:57 -0000 1.24 +++ hercifc.c 19 Oct 2006 21:15:45 -0000 1.25 @@ -36,8 +36,10 @@ void* pArg = NULL; // -> ifreq or rtentry CTLREQ ctlreq; // Request Buffer int sockfd; // Socket descriptor + int fd; // FD for ioctl int rc; // Return code pid_t ppid; // Parent's PID + int answer; // 1 = write answer to stdout char szMsgBuffer[255]; UNREFERENCED( argc ); @@ -90,8 +92,19 @@ exit( 4 ); } + fd = sockfd; + answer = 0; + switch( ctlreq.iCtlOp ) { + case TUNSETIFF: + pOp = "TUNSETIFF"; + pArg = &ctlreq.iru.ifreq; + pIF = "?"; + fd = ctlreq.iProcID; + answer = 1; + break; + case SIOCSIFADDR: pOp = "SIOCSIFADDR"; pArg = &ctlreq.iru.ifreq; @@ -115,6 +128,7 @@ pOp = "SIOCGIFFLAGS"; pArg = &ctlreq.iru.ifreq; pIF = ctlreq.iru.ifreq.ifr_name; + answer = 1; break; #endif /* (caller should do 'ioctl' directly themselves instead) */ @@ -194,7 +208,7 @@ write( STDERR_FILENO, szMsgBuffer, strlen( szMsgBuffer ) ); #endif /*defined(DEBUG) || defined(_DEBUG)*/ - rc = ioctl( sockfd, ctlreq.iCtlOp, pArg ); + rc = ioctl( fd, ctlreq.iCtlOp, pArg ); if( rc < 0 ) { snprintf( szMsgBuffer,sizeof(szMsgBuffer), @@ -203,6 +217,10 @@ write( STDERR_FILENO, szMsgBuffer, strlen( szMsgBuffer ) ); } + else if (answer) + { + write( STDOUT_FILENO, &ctlreq, CTLREQ_SIZE ); + } } // Never reached. @@ -210,3 +228,4 @@ } #endif // defined(BUILD_HERCIFC) + --- tuntap.c 25 Apr 2006 19:41:35 -0000 1.42 +++ tuntap.c 19 Oct 2006 21:15:45 -0000 1.43 @@ -51,6 +51,93 @@ // Primary Module Entry Points // ==================================================================== +static int TUNTAP_SetMode (int fd, struct ifreq *ifr) +{ + int rc; + + /* Try TUNTAP_ioctl first */ + rc = TUNTAP_IOCtl (fd, TUNSETIFF, (char *) ifr); + +#if !defined(OPTION_W32_CTCI) + /* If invalid value, try with the pre-2.4.5 value */ + if (rc != 0 && errno == EINVAL) + rc = TUNTAP_IOCtl (fd, ('T' << 8) | 202, (char *) ifr); + + /* kludge for EPERM and linux 2.6.18 */ + if (rc != 0 && errno == EPERM) + { + int ifd[2]; + char *hercifc; + pid_t pid; + CTLREQ ctlreq; + fd_set selset; + struct timeval tv; + int sv_err; + int status; + + if (socketpair (AF_UNIX, SOCK_STREAM, 0, ifd) < 0) + return -1; + + if (!(hercifc = getenv ("HERCULES_IFC"))) + hercifc = HERCIFC_CMD; + + pid = fork(); + + if (pid < 0) + return -1; + else if (pid == 0) + { + /* child */ + dup2 (ifd[0], STDIN_FILENO); + dup2 (STDOUT_FILENO, STDERR_FILENO); + dup2 (ifd[0], STDOUT_FILENO); + close (ifd[1]); + rc = execlp (hercifc, hercifc, NULL ); + return -1; + } + + /* parent */ + close(ifd[0]); + + /* Request hercifc to issue the TUNSETIFF ioctl */ + memset (&ctlreq, 0, CTLREQ_SIZE); + ctlreq.iCtlOp = TUNSETIFF; + ctlreq.iProcID = fd; + memcpy (&ctlreq.iru.ifreq, ifr, sizeof (struct ifreq)); + write (ifd[1], &ctlreq, CTLREQ_SIZE); + + /* Get response, if any, from hercifc */ + FD_ZERO (&selset); + FD_SET (ifd[1], &selset); + tv.tv_sec = 5; + tv.tv_usec = 0; + rc = select (ifd[1]+1, &selset, NULL, NULL, &tv); + if (rc > 0) + { + rc = read (ifd[1], &ctlreq, CTLREQ_SIZE); + if (rc > 0) + memcpy (ifr, &ctlreq.iru.ifreq, sizeof (struct ifreq)); + } + else if (rc == 0) + { + logmsg (_("HHCTU001E %s timeout, possible older version?\n"), + hercifc); + errno = EPERM; + rc = -1; + } + + /* clean-up */ + sv_err = errno; + close (ifd[1]); + kill (pid, SIGINT); + waitpid (pid, &status, 0); + errno = sv_err; + } +#endif /* if !defined(OPTION_W32_CTCI) */ + + return rc; +} + // // TUNTAP_CreateInterface // @@ -142,14 +229,9 @@ struct ifreq ifr; memset( &ifr, 0, sizeof( ifr ) ); - ifr.ifr_flags = iFlags; - // First try the value from the header that we ship (2.4.8) - // If this fails with EINVAL, try with the pre-2.4.5 value - if( TUNTAP_IOCtl( fd, TUNSETIFF, (char*)&ifr ) != 0 && - ( errno != EINVAL || - TUNTAP_IOCtl( fd, ('T' << 8) | 202, (char*)&ifr ) != 0 ) ) + if( TUNTAP_SetMode (fd, &ifr) < 0 ) { logmsg( _("HHCTU003E Error setting TUN/TAP mode: %s: %s\n"), pszTUNDevice, strerror( errno ) ); *** cvs diff -ub ends here *** Thanks, --Ivan -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]