diff -Naur rp-pppoe-3.8.original/src/discovery.c rp-pppoe-3.8/src/discovery.c --- rp-pppoe-3.8.original/src/discovery.c 2007-02-24 08:53:09.000000000 +0000 +++ rp-pppoe-3.8/src/discovery.c 2007-02-24 08:53:35.000000000 +0000 @@ -596,15 +596,6 @@ int padrAttempts = 0; int timeout = conn->discoveryTimeout; - /* Skip discovery and don't open discovery socket? */ - if (conn->skipDiscovery && conn->noDiscoverySocket) { - conn->discoveryState = STATE_SESSION; - return; - } - - conn->discoverySocket = - openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); - /* Skip discovery? */ if (conn->skipDiscovery) { conn->discoveryState = STATE_SESSION; diff -Naur rp-pppoe-3.8.original/src/plugin.c rp-pppoe-3.8/src/plugin.c --- rp-pppoe-3.8.original/src/plugin.c 2007-02-24 08:53:09.000000000 +0000 +++ rp-pppoe-3.8/src/plugin.c 2007-02-24 08:53:35.000000000 +0000 @@ -136,6 +136,17 @@ { struct sockaddr_pppox sp; + /* Open session socket before discovery phase, to avoid losing session */ + /* packets sent by peer just after PADS packet (noted on some Cisco */ + /* server equipment). */ + /* Opening this socket just before waitForPADS in the discovery() */ + /* function would be more appropriate, but it would mess-up the code */ + conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); + if (conn->sessionSocket < 0) { + error("Failed to create PPPoE socket: %m"); + return -1; + } + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); if (existingSession) { unsigned int mac[ETH_ALEN]; @@ -150,7 +161,9 @@ conn->peerEth[i] = (unsigned char) mac[i]; } } else { - discovery(conn); + conn->discoverySocket = + openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); + discovery(conn); if (conn->discoveryState != STATE_SESSION) { error("Unable to complete PPPoE Discovery"); return -1; @@ -160,12 +173,6 @@ /* Set PPPoE session-number for further consumption */ ppp_session_number = ntohs(conn->session); - /* Make the session socket */ - conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); - if (conn->sessionSocket < 0) { - error("Failed to create PPPoE socket: %m"); - return -1; - } sp.sa_family = AF_PPPOX; sp.sa_protocol = PX_PROTO_OE; sp.sa_addr.pppoe.sid = conn->session; diff -Naur rp-pppoe-3.8.original/src/pppoe.c rp-pppoe-3.8/src/pppoe.c --- rp-pppoe-3.8.original/src/pppoe.c 2007-02-24 08:53:09.000000000 +0000 +++ rp-pppoe-3.8/src/pppoe.c 2007-02-24 08:53:36.000000000 +0000 @@ -232,9 +232,6 @@ int maxFD = 0; int r; - /* Open a session socket */ - conn->sessionSocket = openInterface(conn->ifName, Eth_PPPOE_Session, conn->myEth); - /* Drop privileges */ dropPrivs(); @@ -617,6 +614,8 @@ if (conn.printACNames) { fprintf(stderr, "Sending discovery flood %d\n", n+1); } + conn.discoverySocket = + openInterface(conn.ifName, Eth_PPPOE_Discovery, conn.myEth); discovery(&conn); conn.discoveryState = STATE_SENT_PADI; close(conn.discoverySocket); @@ -624,7 +623,23 @@ exit(EXIT_SUCCESS); } - discovery(&conn); + /* Open session socket before discovery phase, to avoid losing session */ + /* packets sent by peer just after PADS packet (noted on some Cisco */ + /* server equipment). */ + /* Opening this socket just before waitForPADS in the discovery() */ + /* function would be more appropriate, but it would mess-up the code */ + if (!optSkipSession) + conn.sessionSocket = openInterface(conn.ifName, Eth_PPPOE_Session, conn.myEth); + + /* Skip discovery and don't open discovery socket? */ + if (conn.skipDiscovery && conn.noDiscoverySocket) { + conn.discoveryState = STATE_SESSION; + } + else { + conn.discoverySocket = + openInterface(conn.ifName, Eth_PPPOE_Discovery, conn.myEth); + discovery(&conn); + } if (optSkipSession) { printf("%u:%02x:%02x:%02x:%02x:%02x:%02x\n", ntohs(conn.session),