[haiku-commits] haiku: hrev49969 - in src: add-ons/kernel/network/ppp/shared/libkernelppp add-ons/kernel/network/ppp/ipcp add-ons/kernel/network/ppp/pppoe bin/network/pppconfig add-ons/kernel/network/ppp/shared/libppp

  • From: waddlesplash@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 2 Jan 2016 18:23:42 +0100 (CET)

hrev49969 adds 1 changeset to branch 'master'
old head: 7121057cb7b04dbcc123f93939bdb790479560d9
new head: e3724c38cb7666bfcd615bebe384b9281d148ede
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=e3724c38cb76+%5E7121057cb7b0

----------------------------------------------------------------------------

e3724c38cb76: PPP: Port to the new stack.
  
  Signed-off-by: Augustin Cavalier <waddlesplash@xxxxxxxxx>
  
  This is a squash of the 42 commits by @mshlyn, as I couldn't find a
  way to break them into logical chunks. I did not include these in the build,
  as it appears that they only partially work anyway, and much more cleanup is
  still needed. However, this is a huge improvement on what was in the tree
  before, which looked horrendous and didn't even compile (as it was designed
  for the old stack).
  
  Mostly fixes #812.

                                            [ mshlyn <linlongzhou@xxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev49969
Commit:      e3724c38cb7666bfcd615bebe384b9281d148ede
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e3724c38cb76
Author:      mshlyn <linlongzhou@xxxxxxx>
Date:        Sat Jan  4 15:49:30 2014 UTC
Committer:   Augustin Cavalier <waddlesplash@xxxxxxxxx>
Commit-Date: Sat Jan  2 12:22:13 2016 UTC

Ticket:      https://dev.haiku-os.org/ticket/812

----------------------------------------------------------------------------

62 files changed, 5213 insertions(+), 2292 deletions(-)
build/jam/images/definitions/minimum             |    2 +-
build/jam/packages/Haiku                         |    2 +-
build/jam/packages/HaikuBootstrap                |    2 +-
src/add-ons/kernel/network/Jamfile               |    1 +
src/add-ons/kernel/network/ppp/Jamfile           |    5 +-
src/add-ons/kernel/network/ppp/ipcp/Jamfile      |   42 +-
src/add-ons/kernel/network/ppp/ipcp/Protocol.cpp | 1130 +++++++++++-------
src/add-ons/kernel/network/ppp/ipcp/Protocol.h   |   64 +-
src/add-ons/kernel/network/ppp/ipcp/ipcp.cpp     |   55 +-
src/add-ons/kernel/network/ppp/pap/Jamfile       |   12 +-
src/add-ons/kernel/network/ppp/pap/Protocol.cpp  |  314 ++---
src/add-ons/kernel/network/ppp/pap/Protocol.h    |   35 +-
src/add-ons/kernel/network/ppp/pap/pap.cpp       |   45 +-
src/add-ons/kernel/network/ppp/ppp/Jamfile       |   28 +
src/add-ons/kernel/network/ppp/ppp/ppp.cpp       |  388 ++++++
src/add-ons/kernel/network/ppp/ppp_frame/Jamfile |   26 +
.../kernel/network/ppp/ppp_frame/ppp_frame.cpp   |  265 ++++
.../kernel/network/ppp/ppp_manager/Jamfile       |   31 +
.../network/ppp/ppp_manager/KPPPManager.cpp      |  373 ++++++
.../kernel/network/ppp/pppoe/DiscoveryPacket.cpp |   61 +-
.../kernel/network/ppp/pppoe/DiscoveryPacket.h   |    9 +-
src/add-ons/kernel/network/ppp/pppoe/Jamfile     |   12 +-
src/add-ons/kernel/network/ppp/pppoe/PPPoE.h     |   11 +-
.../kernel/network/ppp/pppoe/PPPoEDevice.cpp     |  522 ++++----
.../kernel/network/ppp/pppoe/PPPoEDevice.h       |   13 +-
src/add-ons/kernel/network/ppp/pppoe/pppoe.cpp   |  347 ++++--
.../network/ppp/shared/libkernelppp/Jamfile      |    6 +-
.../shared/libkernelppp/KPPPConfigurePacket.cpp  |  126 +-
.../ppp/shared/libkernelppp/KPPPDevice.cpp       |   28 +-
.../ppp/shared/libkernelppp/KPPPInterface.cpp    | 1072 +++++++++++------
.../network/ppp/shared/libkernelppp/KPPPLCP.cpp  |  142 +--
.../ppp/shared/libkernelppp/KPPPLCPExtension.cpp |    1 +
.../ppp/shared/libkernelppp/KPPPLayer.cpp        |   18 +-
.../shared/libkernelppp/KPPPOptionHandler.cpp    |    1 +
.../shared/libkernelppp/KPPPReportManager.cpp    |   86 +-
.../ppp/shared/libkernelppp/KPPPStateMachine.cpp |  964 ++++++++-------
.../libkernelppp/headers/KPPPConfigurePacket.h   |    9 +-
.../ppp/shared/libkernelppp/headers/KPPPDevice.h |    6 +-
.../shared/libkernelppp/headers/KPPPInterface.h  |   22 +-
.../ppp/shared/libkernelppp/headers/KPPPLCP.h    |   10 +-
.../libkernelppp/headers/KPPPLCPExtension.h      |    2 +-
.../ppp/shared/libkernelppp/headers/KPPPLayer.h  |    7 +-
.../shared/libkernelppp/headers/KPPPManager.h    |   13 +-
.../shared/libkernelppp/headers/KPPPProtocol.h   |    4 +-
.../libkernelppp/headers/KPPPReportManager.h     |    7 +-
.../libkernelppp/headers/KPPPStateMachine.h      |   81 +-
.../ppp/shared/libkernelppp/headers/PPPControl.h |   70 ++
.../ppp/shared/libkernelppp/headers/PPPDefs.h    |    5 +-
.../ppp/shared/libkernelppp/headers/ppp_device.h |   18 +
.../kernel/network/ppp/shared/libppp/Jamfile     |    9 +-
.../network/ppp/shared/libppp/PPPInterface.cpp   |  206 +++-
.../network/ppp/shared/libppp/PPPManager.cpp     |  199 ++-
.../network/ppp/shared/libppp/_libppputils.cpp   |   24 -
.../network/ppp/shared/libppp/_libppputils.h     |   15 -
.../ppp/shared/libppp/headers/PPPInterface.h     |    6 +
.../ppp/shared/libppp/headers/PPPManager.h       |    2 +
src/add-ons/kernel/network/stack/stack.cpp       |    3 +
src/bin/network/Jamfile                          |    4 +-
src/bin/network/ppp_up/Jamfile                   |    9 +-
src/bin/network/ppp_up/PPPStatusView.h           |    3 +-
src/bin/network/pppconfig/Jamfile                |    5 +-
src/bin/network/pppconfig/pppconfig.cpp          |  527 +++++++-

----------------------------------------------------------------------------

diff --git a/build/jam/images/definitions/minimum 
b/build/jam/images/definitions/minimum
index eba4c4f..0ba75d0 100644
--- a/build/jam/images/definitions/minimum
+++ b/build/jam/images/definitions/minimum
@@ -134,7 +134,7 @@ SYSTEM_NETWORK_DATALINK_PROTOCOLS =
        loopback_frame
 ;
 
-#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe ;
+#SYSTEM_NETWORK_PPP = ipcp modem pap pppoe KPPPManager ;
 
 SYSTEM_NETWORK_PROTOCOLS =
        icmp icmp6 ipv4 ipv6
diff --git a/build/jam/packages/Haiku b/build/jam/packages/Haiku
index 2f6a054..4539aad 100644
--- a/build/jam/packages/Haiku
+++ b/build/jam/packages/Haiku
@@ -250,7 +250,7 @@ AddFilesToPackage add-ons kernel network : dns_resolver ;
 AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
 AddFilesToPackage add-ons kernel network datalink_protocols
        : $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
-AddFilesToPackage add-ons kernel network ppp: $(SYSTEM_NETWORK_PPP) ;
+AddFilesToPackage add-ons kernel network ppp : $(SYSTEM_NETWORK_PPP) ;
 AddFilesToPackage add-ons kernel network protocols
        : $(SYSTEM_NETWORK_PROTOCOLS) ;
 
diff --git a/build/jam/packages/HaikuBootstrap 
b/build/jam/packages/HaikuBootstrap
index 8d91004..72e57ea 100644
--- a/build/jam/packages/HaikuBootstrap
+++ b/build/jam/packages/HaikuBootstrap
@@ -209,7 +209,7 @@ AddFilesToPackage add-ons kernel network : dns_resolver ;
 AddFilesToPackage add-ons kernel network devices : $(SYSTEM_NETWORK_DEVICES) ;
 AddFilesToPackage add-ons kernel network datalink_protocols
        : $(SYSTEM_NETWORK_DATALINK_PROTOCOLS) ;
-AddFilesToPackage add-ons kernel network ppp: $(SYSTEM_NETWORK_PPP) ;
+AddFilesToPackage add-ons kernel network ppp : $(SYSTEM_NETWORK_PPP) ;
 AddFilesToPackage add-ons kernel network protocols
        : $(SYSTEM_NETWORK_PROTOCOLS) ;
 
diff --git a/src/add-ons/kernel/network/Jamfile 
b/src/add-ons/kernel/network/Jamfile
index 7667873..5862dab 100644
--- a/src/add-ons/kernel/network/Jamfile
+++ b/src/add-ons/kernel/network/Jamfile
@@ -6,3 +6,4 @@ SubInclude HAIKU_TOP src add-ons kernel network dns_resolver ;
 SubInclude HAIKU_TOP src add-ons kernel network notifications ;
 SubInclude HAIKU_TOP src add-ons kernel network protocols ;
 SubInclude HAIKU_TOP src add-ons kernel network stack ;
+SubInclude HAIKU_TOP src add-ons kernel network ppp ;
diff --git a/src/add-ons/kernel/network/ppp/Jamfile 
b/src/add-ons/kernel/network/ppp/Jamfile
index 2a05e24..0124e01 100644
--- a/src/add-ons/kernel/network/ppp/Jamfile
+++ b/src/add-ons/kernel/network/ppp/Jamfile
@@ -1,7 +1,10 @@
 SubDir HAIKU_TOP src add-ons kernel network ppp ;
 
 SubInclude HAIKU_TOP src add-ons kernel network ppp ipcp ;
-SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
+# SubInclude HAIKU_TOP src add-ons kernel network ppp modem ;
 SubInclude HAIKU_TOP src add-ons kernel network ppp pap ;
 SubInclude HAIKU_TOP src add-ons kernel network ppp pppoe ;
 SubInclude HAIKU_TOP src add-ons kernel network ppp shared ;
+SubInclude HAIKU_TOP src add-ons kernel network ppp ppp ;
+SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_frame ;
+SubInclude HAIKU_TOP src add-ons kernel network ppp ppp_manager ;
diff --git a/src/add-ons/kernel/network/ppp/ipcp/Jamfile 
b/src/add-ons/kernel/network/ppp/ipcp/Jamfile
index cb3a5e2..9a77ff1 100644
--- a/src/add-ons/kernel/network/ppp/ipcp/Jamfile
+++ b/src/add-ons/kernel/network/ppp/ipcp/Jamfile
@@ -1,41 +1,51 @@
 SubDir HAIKU_TOP src add-ons kernel network ppp ipcp ;
 
 SetSubDirSupportedPlatformsBeOSCompatible ;
+SubDirC++Flags -fno-rtti ;
 
 if $(TARGET_PLATFORM) != haiku {
-       UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
-               # We need the public network headers also when not compiling 
for Haiku.
-               # Unfortunately we get more than we want, namely all POSIX 
headers.
+       UseHeaders [ FStandardOSHeaders ] : true ;
+               # Needed for the atomic_add64() prototype.
 }
 
-# for kernel_cpp.h and BLocker
-UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
+UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
+       # We need the public network headers also when not compiling for Haiku.
+       # Unfortunately we get more than we want, namely all POSIX headers.
+
+UsePrivateKernelHeaders ;
 UsePrivateHeaders net ;
+
+UsePrivateHeaders libroot net ;
 UsePrivateHeaders [ FDirName kernel ] ;
 UsePrivateHeaders [ FDirName kernel util ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
        libkernelppp headers ] : true ;
-
-
-{
-       SubDirC++Flags -fno-rtti ;
-}
-
+UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp pppoe
+       ] : true ;
 
 KernelAddon ipcp :
-       # imported from libnet
+       atomic.S
+       kernel_cpp.cpp
+
+       # imported from kernel util
        inet_addr.c
-       
+
        ipcp.cpp
        Protocol.cpp
 ;
 
+
 SEARCH on [ FGristFiles inet_addr.c ]
-       = [ FDirName $(HAIKU_TOP) src kits network compat libnet ] ;
+       = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
+
+SEARCH on [ FGristFiles kernel_cpp.cpp ]
+        = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
+SEARCH on [ FGristFiles atomic.S ]
+        = [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ;
 
 LinkAgainst ipcp : libkernelppp.a ;
 
-# Installation
+
 HaikuInstall install-networking
-       : /boot/home/config/add-ons/kernel/obos_network/ppp
+       : /boot/home/config/add-ons/kernel/network/ppp
        : ipcp ;
diff --git a/src/add-ons/kernel/network/ppp/ipcp/Protocol.cpp 
b/src/add-ons/kernel/network/ppp/ipcp/Protocol.cpp
index 7105440..f6595af 100644
--- a/src/add-ons/kernel/network/ppp/ipcp/Protocol.cpp
+++ b/src/add-ons/kernel/network/ppp/ipcp/Protocol.cpp
@@ -13,11 +13,29 @@
 #include <KPPPInterface.h>
 #include <settings_tools.h>
 
+#include <PPPoEDevice.h>
+
 #include <cstring>
-#include <netinet/in_var.h>
-#include <core_funcs.h>
+
+#include <arpa/inet.h>
+#include <net_buffer.h>
+#include <net_stack.h>
+#include <net/route.h>
 #include <sys/sockio.h>
 
+// For updating resolv.conf
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define RESOLV_CONF_FILE "/boot/system/settings/network/resolv.conf"
+
+extern net_buffer_module_info *gBufferModule;
+static struct net_datalink_module_info *sDatalinkModule;
+static struct net_stack_module_info *sStackModule;
 
 #if DEBUG
 #include <unistd.h>
@@ -26,23 +44,23 @@ static int sFD;
        // the file descriptor for debug output
 static char sDigits[] = "0123456789ABCDEF";
 void
-dump_packet(struct mbuf *packet, const char *direction)
+dump_packet(net_buffer *packet, const char *direction)
 {
-       if(!packet)
+       if (!packet)
                return;
-       
+
        uint8 *data = mtod(packet, uint8*);
        uint8 buffer[128];
        uint8 bufferIndex = 0;
-       
+
        sprintf((char*) buffer, "Dumping %s packet;len=%ld;pkthdr.len=%d\n", 
direction,
                packet->m_len, packet->m_flags & M_PKTHDR ? 
packet->m_pkthdr.len : -1);
        write(sFD, buffer, strlen((char*) buffer));
-       
-       for(uint32 index = 0; index < packet->m_len; index++) {
+
+       for (uint32 index = 0; index < packet->m_len; index++) {
                buffer[bufferIndex++] = sDigits[data[index] >> 4];
                buffer[bufferIndex++] = sDigits[data[index] & 0x0F];
-               if(bufferIndex == 32 || index == packet->m_len - 1) {
+               if (bufferIndex == 32 || index == packet->m_len - 1) {
                        buffer[bufferIndex++] = '\n';
                        buffer[bufferIndex] = 0;
                        write(sFD, buffer, strlen((char*) buffer));
@@ -75,18 +93,20 @@ IPCP::IPCP(KPPPInterface& interface, driver_parameter 
*settings)
        // reset configurations
        memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration));
        memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration));
-       
+
        // reset requests
        memset(&fLocalRequests, 0, sizeof(ipcp_requests));
        memset(&fPeerRequests, 0, sizeof(ipcp_requests));
-       
+
        // Parse settings:
        // "Local" and "Peer" describe each side's settings
        ParseSideRequests(get_parameter_with_name(IPCP_LOCAL_SIDE_KEY, 
Settings()),
                PPP_LOCAL_SIDE);
        ParseSideRequests(get_parameter_with_name(IPCP_PEER_SIDE_KEY, 
Settings()),
                PPP_PEER_SIDE);
-       
+
+       get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
+       get_module(NET_DATALINK_MODULE_NAME, (module_info **)&sDatalinkModule);
 #if DEBUG
        sFD = open("/boot/home/ipcpdebug", O_WRONLY | O_CREAT | O_TRUNC);
 #endif
@@ -95,6 +115,9 @@ IPCP::IPCP(KPPPInterface& interface, driver_parameter 
*settings)
 
 IPCP::~IPCP()
 {
+
+       put_module(NET_DATALINK_MODULE_NAME);
+       put_module(NET_STACK_MODULE_NAME);
 #if DEBUG
        close(sFD);
 #endif
@@ -112,28 +135,28 @@ status_t
 IPCP::StackControl(uint32 op, void *data)
 {
        TRACE("IPCP: StackControl(op=%ld)\n", op);
-       
+
        // TODO:
        // check values
-       
-       switch(op) {
+
+       switch (op) {
                case SIOCSIFADDR:
                break;
-               
+
                case SIOCSIFFLAGS:
                break;
-               
+
                case SIOCSIFDSTADDR:
                break;
-               
+
                case SIOCSIFNETMASK:
                break;
-               
+
                default:
                        ERROR("IPCP: Unknown ioctl: %ld\n", op);
                        return KPPPProtocol::StackControl(op, data);
        }
-       
+
        return B_OK;
 }
 
@@ -142,23 +165,23 @@ bool
 IPCP::Up()
 {
        TRACE("IPCP: Up() state=%d\n", State());
-       
+
        // Servers do not send a configure-request when Up() is called. They 
wait until
        // the client requests this protocol.
-       if(Interface().Mode() == PPP_SERVER_MODE)
+       if (Interface().Mode() == PPP_SERVER_MODE)
                return true;
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_INITIAL_STATE:
                        NewState(PPP_REQ_SENT_STATE);
                        InitializeRestartCount();
                        SendConfigureRequest();
                break;
-               
+
                default:
                        ;
        }
-       
+
        return true;
 }
 
@@ -167,49 +190,49 @@ bool
 IPCP::Down()
 {
        TRACE("IPCP: Down() state=%d\n", State());
-       
-       switch(Interface().Phase()) {
+
+       switch (Interface().Phase()) {
                case PPP_DOWN_PHASE:
                        // interface finished terminating
                        NewState(PPP_INITIAL_STATE);
                        ReportDownEvent();
                                // this will also reset and update addresses
                break;
-               
+
 /*             case PPP_TERMINATION_PHASE:
                        // interface is terminating
                break;
-               
+
                case PPP_ESTABLISHMENT_PHASE:
                        // interface is reconfiguring
                break;
-*/             
+*/
                case PPP_ESTABLISHED_PHASE:
                        // terminate this NCP individually (block until we 
finished terminating)
-                       if(State() != PPP_INITIAL_STATE && State() != 
PPP_CLOSING_STATE) {
+                       if (State() != PPP_INITIAL_STATE && State() != 
PPP_CLOSING_STATE) {
                                NewState(PPP_CLOSING_STATE);
                                InitializeRestartCount();
                                SendTerminateRequest();
                        }
-                       
-                       while(State() == PPP_CLOSING_STATE)
+
+                       while (State() == PPP_CLOSING_STATE)
                                snooze(50000);
                break;
-               
+
                default:
                        ;
        }
-       
+
        return true;
 }
 
 
 status_t
-IPCP::Send(struct mbuf *packet, uint16 protocolNumber)
+IPCP::Send(net_buffer *packet, uint16 protocolNumber)
 {
        TRACE("IPCP: Send(0x%X)\n", protocolNumber);
-       
-       if((protocolNumber == IP_PROTOCOL && State() == PPP_OPENED_STATE)
+
+       if ((protocolNumber == IP_PROTOCOL && State() == PPP_OPENED_STATE)
                        || protocolNumber == IPCP_PROTOCOL) {
 #if DEBUG
                dump_packet(packet, "outgoing");
@@ -217,96 +240,94 @@ IPCP::Send(struct mbuf *packet, uint16 protocolNumber)
                Interface().UpdateIdleSince();
                return SendToNext(packet, protocolNumber);
        }
-       
+
        ERROR("IPCP: Send() failed because of wrong state or protocol 
number!\n");
-       
-       m_freem(packet);
+
+       gBufferModule->free(packet);
        return B_ERROR;
 }
 
 
 status_t
-IPCP::Receive(struct mbuf *packet, uint16 protocolNumber)
+IPCP::Receive(net_buffer *packet, uint16 protocolNumber)
 {
        TRACE("IPCP: Receive(0x%X)\n", protocolNumber);
-       
-       if(!packet)
+
+       if (!packet)
                return B_ERROR;
-       
-       if(protocolNumber == IP_PROTOCOL)
+
+       if (protocolNumber == IP_PROTOCOL)
                return ReceiveIPPacket(packet, protocolNumber);
-       
-       if(protocolNumber != IPCP_PROTOCOL)
+
+       if (protocolNumber != IPCP_PROTOCOL)
                return PPP_UNHANDLED;
-       
-       ppp_lcp_packet *data = mtod(packet, ppp_lcp_packet*);
-       
-       // remove padding
-       int32 length = packet->m_len;
-       if(packet->m_flags & M_PKTHDR)
-               length = packet->m_pkthdr.len;
-       length -= ntohs(data->length);
-       if(length)
-               m_adj(packet, -length);
-       
-       if(ntohs(data->length) < 4)
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
                return B_ERROR;
-       
+       ppp_lcp_packet &data = bufferheader.Data();
+
+       if (ntohs(data.length) < 4)
+               return B_ERROR;
+
        // packet is freed by event methods
-       switch(data->code) {
+       switch (data.code) {
                case PPP_CONFIGURE_REQUEST:
                        RCREvent(packet);
                break;
-               
+
                case PPP_CONFIGURE_ACK:
                        RCAEvent(packet);
                break;
-               
+
                case PPP_CONFIGURE_NAK:
                case PPP_CONFIGURE_REJECT:
                        RCNEvent(packet);
                break;
-               
+
                case PPP_TERMINATE_REQUEST:
                        RTREvent(packet);
                break;
-               
+
                case PPP_TERMINATE_ACK:
                        RTAEvent(packet);
                break;
-               
+
                case PPP_CODE_REJECT:
                        RXJBadEvent(packet);
                                // we implemented the minimum requirements
                break;
-               
+
                default:
                        RUCEvent(packet);
                        return PPP_REJECTED;
        }
-       
+
        return B_OK;
 }
 
 
 status_t
-IPCP::ReceiveIPPacket(struct mbuf *packet, uint16 protocolNumber)
+IPCP::ReceiveIPPacket(net_buffer *packet, uint16 protocolNumber)
 {
-       if(protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE)
+       if (protocolNumber != IP_PROTOCOL || State() != PPP_OPENED_STATE)
                return PPP_UNHANDLED;
-       
+
        // TODO: add VJC support (the packet would be decoded here)
-       
-       if (gProto[IPPROTO_IP] && gProto[IPPROTO_IP]->pr_input) {
+
+       if (packet)
+       {
 #if DEBUG
                dump_packet(packet, "incoming");
 #endif
                Interface().UpdateIdleSince();
-               gProto[IPPROTO_IP]->pr_input(packet, 0);
+
+               TRACE("We got 1 IP packet from %s::%s\n", __FILE__, __func__);
+               gBufferModule->free(packet);
                return B_OK;
        } else {
                ERROR("IPCP: Error: Could not find input function for IP!\n");
-               m_freem(packet);
+               gBufferModule->free(packet);
                return B_ERROR;
        }
 }
@@ -315,27 +336,27 @@ IPCP::ReceiveIPPacket(struct mbuf *packet, uint16 
protocolNumber)
 void
 IPCP::Pulse()
 {
-       if(fNextTimeout == 0 || fNextTimeout > system_time())
+       if (fNextTimeout == 0 || fNextTimeout > system_time())
                return;
        fNextTimeout = 0;
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_CLOSING_STATE:
-                       if(fTerminateCounter <= 0)
+                       if (fTerminateCounter <= 0)
                                TOBadEvent();
                        else
                                TOGoodEvent();
                break;
-               
+
                case PPP_REQ_SENT_STATE:
                case PPP_ACK_RCVD_STATE:
                case PPP_ACK_SENT_STATE:
-                       if(fRequestCounter <= 0)
+                       if (fRequestCounter <= 0)
                                TOBadEvent();
                        else
                                TOGoodEvent();
                break;
-               
+
                default:
                        ;
        }
@@ -345,128 +366,209 @@ IPCP::Pulse()
 bool
 IPCP::ParseSideRequests(const driver_parameter *requests, ppp_side side)
 {
-       if(!requests)
+       if (!requests)
                return false;
-       
+
        ipcp_requests *selectedRequests;
-       
-       if(side == PPP_LOCAL_SIDE) {
+
+       if (side == PPP_LOCAL_SIDE) {
                selectedRequests = &fLocalRequests;
                fRequestPrimaryDNS = fRequestSecondaryDNS = false;
        } else
                selectedRequests = &fPeerRequests;
-       
+
        memset(selectedRequests, 0, sizeof(ipcp_requests));
                // reset current requests
-       
+
        // The following values are allowed:
        //  "Address"           the ip address that will be suggested
        //  "Netmask"           the netmask that should be used
        //  "PrimaryDNS"        primary DNS server
        //  "SecondaryDNS"      secondary DNS server
        // Setting any value to 0.0.0.0 or "auto" means it should be chosen 
automatically.
-       
+
        in_addr_t address = INADDR_ANY;
-       for(int32 index = 0; index < requests->parameter_count; index++) {
-               if(requests->parameters[index].value_count == 0)
+       for (int32 index = 0; index < requests->parameter_count; index++) {
+               if (requests->parameters[index].value_count == 0)
                        continue;
-               
+
                // all values are IP addresses, so parse the address here
-               if(strcasecmp(requests->parameters[index].values[0], "auto")) {
+               if (strcasecmp(requests->parameters[index].values[0], "auto")) {
                        address = 
inet_addr(requests->parameters[index].values[0]);
-                       if(address == INADDR_NONE)
+                       // address = INADDR_ANY;
+                       if (address == INADDR_NONE)
                                continue;
                }
-               
-               if(!strcasecmp(requests->parameters[index].name, 
IPCP_IP_ADDRESS_KEY))
+
+               if (!strcasecmp(requests->parameters[index].name, 
IPCP_IP_ADDRESS_KEY))
                        selectedRequests->address = address;
-               else if(!strcasecmp(requests->parameters[index].name, 
IPCP_NETMASK_KEY))
+               else if (!strcasecmp(requests->parameters[index].name, 
IPCP_NETMASK_KEY))
                        selectedRequests->netmask = address;
-               else if(!strcasecmp(requests->parameters[index].name, 
IPCP_PRIMARY_DNS_KEY)) {
+               else if (!strcasecmp(requests->parameters[index].name, 
IPCP_PRIMARY_DNS_KEY)) {
                        selectedRequests->primaryDNS = address;
-                       if(side == PPP_LOCAL_SIDE)
+                       if (side == PPP_LOCAL_SIDE)
                                fRequestPrimaryDNS = true;
-               } else if(!strcasecmp(requests->parameters[index].name,
+               } else if (!strcasecmp(requests->parameters[index].name,
                                IPCP_SECONDARY_DNS_KEY)) {
                        selectedRequests->secondaryDNS = address;
-                       if(side == PPP_LOCAL_SIDE)
+                       if (side == PPP_LOCAL_SIDE)
                                fRequestSecondaryDNS = true;
                }
        }
-       
+
        return true;
 }
 
 
+net_interface *
+get_interface_by_name(net_domain *domain, const char *name)
+{
+       ifreq request;
+       memset(&request, 0, sizeof(request));
+       size_t size = sizeof(request);
+
+       strlcpy(request.ifr_name, name, IF_NAMESIZE);
+
+       if (sDatalinkModule->control(domain, SIOCGIFINDEX, &request, &size) != 
B_OK) {
+               TRACE("sDatalinkModule->control failure\n");
+               return NULL;
+       }
+       return sDatalinkModule->get_interface(domain, request.ifr_index);
+}
+
+
+status_t
+set_interface_address(net_domain* domain, struct ifaliasreq* inreq)
+{
+       size_t size = sizeof(struct ifaliasreq);
+       return sDatalinkModule->control(domain, B_SOCKET_SET_ALIAS, inreq, 
&size);
+}
+
+
 void
 IPCP::UpdateAddresses()
 {
+       TRACE("%s::%s: entering UpdateAddresses\n", __FILE__, __func__);
        RemoveRoutes();
-       
-       if(State() != PPP_OPENED_STATE && !Interface().DoesConnectOnDemand())
+
+       if (State() != PPP_OPENED_STATE && !Interface().DoesConnectOnDemand())
                return;
-       
-       struct in_aliasreq inreq;
-       struct ifreq ifreqAddress, ifreqDestination;
-       memset(&inreq, 0, sizeof(struct in_aliasreq));
-       memset(&ifreqAddress, 0, sizeof(struct ifreq));
-       memset(&ifreqDestination, 0, sizeof(struct ifreq));
-       memset(&fGateway, 0, sizeof(struct sockaddr_in));
-       
-       // create local address
-       inreq.ifra_addr.sin_family = AF_INET;
-       if(fLocalRequests.address != INADDR_ANY)
-               inreq.ifra_addr.sin_addr.s_addr = fLocalRequests.address;
-       else if(fLocalConfiguration.address == INADDR_ANY)
-               inreq.ifra_addr.sin_addr.s_addr = 0x010F0F0F; // was: 
INADDR_BROADCAST
-       else
-               inreq.ifra_addr.sin_addr.s_addr = fLocalConfiguration.address;
-       inreq.ifra_addr.sin_len = sizeof(struct sockaddr_in);
-       memcpy(&ifreqAddress.ifr_addr, &inreq.ifra_addr, sizeof(struct 
sockaddr_in));
-       
-       // create destination address
-       fGateway.sin_family = AF_INET;
-       if(fPeerRequests.address != INADDR_ANY)
-               fGateway.sin_addr.s_addr = fPeerRequests.address;
-       else if(fPeerConfiguration.address == INADDR_ANY)
-               fGateway.sin_addr.s_addr = 0x020F0F0F; // was: INADDR_BROADCAST
-       else
-               fGateway.sin_addr.s_addr = fPeerConfiguration.address;
-       fGateway.sin_len = sizeof(struct sockaddr_in);
-       memcpy(&inreq.ifra_dstaddr, &fGateway,
-               sizeof(struct sockaddr_in));
-       memcpy(&ifreqDestination.ifr_dstaddr, &inreq.ifra_dstaddr,
-               sizeof(struct sockaddr_in));
-       
-       // create netmask
-       inreq.ifra_mask.sin_family = AF_INET;
-       inreq.ifra_mask.sin_addr.s_addr = fLocalRequests.netmask;
-       inreq.ifra_mask.sin_len = sizeof(struct sockaddr_in);
-       
-       // tell stack to use these values
-       if(in_control(NULL, SIOCAIFADDR, (caddr_t) &inreq,
-                       Interface().Ifnet()) != B_OK)
-               ERROR("IPCP: UpdateAddress(): SIOCAIFADDR returned error!\n");
-       if(in_control(NULL, SIOCSIFADDR, (caddr_t) &ifreqAddress,
-                       Interface().Ifnet()) != B_OK)
-               ERROR("IPCP: UpdateAddress(): SIOCSIFADDR returned error!\n");
-       if(in_control(NULL, SIOCSIFDSTADDR, (caddr_t) &ifreqDestination,
-                       Interface().Ifnet()) != B_OK)
-               ERROR("IPCP: UpdateAddress(): SIOCSIFDSTADDR returned 
error!\n");
-       memcpy(&inreq.ifra_addr, &inreq.ifra_mask, sizeof(struct sockaddr_in));
-               // SIOCISFNETMASK wants the netmask to be in ifra_addr
-       if(in_control(NULL, SIOCSIFNETMASK, (caddr_t) &inreq,
-                       Interface().Ifnet()) != B_OK)
-               ERROR("IPCP: UpdateAddress(): SIOCSIFNETMASK returned 
error!\n");
-       
+
+       TRACE("%s::%s: entering ChangeAddress\n", __FILE__, __func__);
+       if (sDatalinkModule == NULL) {
+               TRACE("%s::%s: some module not found!\n", __FILE__, __func__);
+               return;
+       }
+
+
+       struct sockaddr newAddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 
0x00}};
+       struct sockaddr netmask = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 
0x00}};
+       struct sockaddr broadaddr = {6, AF_INET, {0x00, 0x00, 0x00, 0x00, 0x00, 
0x00}};
+
+       if (fLocalRequests.address != INADDR_ANY)
+               memcpy(newAddr.sa_data + 2, &fLocalRequests.address, 
sizeof(in_addr_t));
+       else if (fLocalConfiguration.address == INADDR_ANY) {
+               in_addr_t inaddrBroadcast = 0x010F0F0F; // was: INADDR_BROADCAST
+               memcpy(newAddr.sa_data + 2, &inaddrBroadcast, 
sizeof(in_addr_t));
+       } else
+               memcpy(newAddr.sa_data + 2, &fLocalConfiguration.address, 
sizeof(in_addr_t));
+
+       struct ifaliasreq inreq;
+       memset(&inreq, 0, sizeof(struct ifaliasreq));
+       memcpy(inreq.ifra_name, Interface().Name(), IF_NAMESIZE);
+       memcpy(&inreq.ifra_addr, &newAddr, sizeof(struct sockaddr));
+       memcpy(&inreq.ifra_mask, &netmask, sizeof(struct sockaddr));
+       memcpy(&inreq.ifra_broadaddr, &broadaddr, sizeof(struct sockaddr));
+       inreq.ifra_index = -1;
+               // create a new interface address
+               // Is it OK when we already have one?
+               // test case:   ifconfig ppp up
+               //              ifconfig ppp down
+               //              ifconfig ppp up
+               //              check if some weird things happen
+
+       net_domain* domain = sStackModule->get_domain(AF_INET);
+       status_t status = set_interface_address(domain, &inreq);
+
+       if (status != B_OK) {
+               TRACE("%s:%s: set_interface_address Fail!!!!\n", __FILE__, 
__func__);
+               return;
+       }
+       TRACE("%s:%s: set_interface_address fine\n", __FILE__, __func__);
+
+
+       net_interface* pppInterface = get_interface_by_name(domain, 
Interface().Name());
+       if (pppInterface == NULL) {
+               TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__);
+               return;
+       }
+
+       net_interface_address* pppInterfaceAddress = NULL;
+       while (sDatalinkModule->get_next_interface_address(pppInterface,
+                               &pppInterfaceAddress)) {
+               if (pppInterfaceAddress->domain->family != AF_INET)
+                       continue;
+               break;
+       }
+
        // add default/subnet route
-       if(Side() == PPP_LOCAL_SIDE) {
-               if(rtrequest(RTM_ADD, (struct sockaddr*) &inreq.ifra_mask,
-                               (struct sockaddr*) &fGateway, (struct 
sockaddr*) &inreq.ifra_mask,
-                               RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
-                       ERROR("IPCP: UpdateAddress(): could not add 
default/subnet route!\n");
-               
-               --fDefaultRoute->rt_refcnt;
+       if (Side() == PPP_LOCAL_SIDE && pppInterfaceAddress != NULL) {
+               struct sockaddr addrGateway = {8, AF_INET, {0x00, 0x00, 0x00, 
0x00,
+                       0x00, 0x00} };
+
+               // create destination address
+               if (fPeerRequests.address != INADDR_ANY)
+                       memcpy(addrGateway.sa_data + 2, &fPeerRequests.address,
+                               sizeof(in_addr_t));
+               else if (fPeerConfiguration.address == INADDR_ANY) {
+                       in_addr_t gateway = 0x020F0F0F;
+                       memcpy(addrGateway.sa_data + 2, &gateway, 
sizeof(in_addr_t));
+                               // was: INADDR_BROADCAST
+               } else
+                       memcpy(addrGateway.sa_data + 2, 
&fPeerConfiguration.address,
+                               sizeof(in_addr_t));
+
+               net_route defaultRoute;
+               defaultRoute.destination = NULL;
+               defaultRoute.mask = NULL;
+               defaultRoute.gateway = &addrGateway;
+               defaultRoute.flags = RTF_DEFAULT | RTF_GATEWAY;
+               defaultRoute.interface_address = pppInterfaceAddress;
+                       // route->interface_address;
+
+               status_t status = sDatalinkModule->add_route(domain, 
&defaultRoute);
+               if (status == B_OK)
+                       dprintf("%s::%s: add route default OK!\n", __FILE__, 
__func__);
+               else
+                       dprintf("%s::%s: add route default Fail!\n", __FILE__, 
__func__);
+
+               sDatalinkModule->put_interface_address(pppInterfaceAddress);
+       }
+
+       if (Side() == PPP_LOCAL_SIDE) {
+               int file;
+               int primary_dns, secondary_dns;
+               char buf[256];
+
+               file = open(RESOLV_CONF_FILE, O_RDWR);
+
+               primary_dns = ntohl(fLocalConfiguration.primaryDNS);
+               secondary_dns = ntohl(fLocalConfiguration.secondaryDNS);
+
+               sprintf(buf, "%s\t%d.%d.%d.%d\n%s\t%d.%d.%d.%d\n",
+                               "nameserver",
+                               (primary_dns & 0xff000000) >> 24,
+                               (primary_dns & 0x00ff0000) >> 16,
+                               (primary_dns & 0x0000ff00) >> 8,
+                               (primary_dns & 0x000000ff),
+                               "nameserver",
+                               (secondary_dns & 0xff000000) >> 24,
+                               (secondary_dns & 0x00ff0000) >> 16,
+                               (secondary_dns & 0x0000ff00) >> 8,
+                               (secondary_dns & 0x000000ff));
+
+               write(file, buf, strlen(buf));
+               close(file);
        }
 }
 
@@ -474,21 +576,71 @@ IPCP::UpdateAddresses()
 void
 IPCP::RemoveRoutes()
 {
-       // note: netstack creates and deletes destination route automatically
-       
-       if(fDefaultRoute) {
+       // note:
+       //      haiku supports multi default route. But for Desktop, ppp is 
generally
+       //      the only default route. So is it necessary to remove other 
default
+       //      route?
+       TRACE("%s::%s: entering RemoveRoutes!\n", __FILE__, __func__);
+
+       char *ethernetName = NULL;
+       PPPoEDevice* pppoeDevice = (PPPoEDevice *)Interface().Device();
+       if (pppoeDevice == NULL)
+               return;
+       ethernetName = pppoeDevice->EthernetIfnet()->name;
+       if (ethernetName == NULL)
+               return;
+
+       net_domain* domain = sStackModule->get_domain(AF_INET);
+       net_interface* pppInterface = get_interface_by_name(domain, 
ethernetName);
+
+       if (pppInterface == NULL) {
+               TRACE("%s::%s: pppInterface not found!\n", __FILE__, __func__);
+               return;
+       }
+
+       net_interface_address* pppInterfaceAddress = NULL;
+
+       while (sDatalinkModule->get_next_interface_address(pppInterface,
+                               &pppInterfaceAddress)) {
+               if (pppInterfaceAddress->domain->family != AF_INET)
+                       continue;
+
+               net_route oldDefaultRoute;
+               oldDefaultRoute.destination = NULL;
+               oldDefaultRoute.mask = NULL;
+               oldDefaultRoute.gateway = NULL;
+               oldDefaultRoute.flags= RTF_DEFAULT;
+               oldDefaultRoute.interface_address = pppInterfaceAddress;
+
+               status_t status = sDatalinkModule->remove_route(domain, 
&oldDefaultRoute);
+                       // current: can not get the system default route so we 
fake
+                       //          one default route for delete
+                       // Todo: save the oldDefaultRoute to fDefaultRoute
+                       //       restore the fDefaultRoute when ppp is down
+
+               sDatalinkModule->put_interface_address(pppInterfaceAddress);
+
+               if (status == B_OK)
+                       dprintf("IPCP::RemoveRoutes: remove old default route 
OK!\n");
+               else
+                       dprintf("IPCP::RemoveRoutes: remove old default route 
Fail!\n");
+
+               break;
+       }
+
+       if (fDefaultRoute) {
                struct sockaddr_in netmask;
                memset(&netmask, 0, sizeof(struct sockaddr_in));
-               
+
                netmask.sin_family = AF_INET;
                netmask.sin_addr.s_addr = fLocalRequests.netmask;
                netmask.sin_len = sizeof(struct sockaddr_in);
-               
-               if(rtrequest(RTM_DELETE, (struct sockaddr*) &netmask,
-                               (struct sockaddr*) &fGateway, (struct 
sockaddr*) &netmask,
-                               RTF_UP | RTF_GATEWAY, &fDefaultRoute) != B_OK)
+
+               // if (rtrequest(RTM_DELETE, (struct sockaddr*) &netmask,
+                               // (struct sockaddr*) &fGateway, (struct 
sockaddr*) &netmask,
+                               // RTF_UP | RTF_GATEWAY, &fDefaultRoute) != 
B_OK)
                        ERROR("IPCP: RemoveRoutes(): could not remove 
default/subnet route!\n");
-               
+
                fDefaultRoute = NULL;
        }
 }
@@ -505,17 +657,17 @@ void
 IPCP::NewState(ppp_state next)
 {
        TRACE("IPCP: NewState(%d) state=%d\n", next, State());
-       
+
        // report state changes
-       if(State() == PPP_INITIAL_STATE && next != State())
+       if (State() == PPP_INITIAL_STATE && next != State())
                UpStarted();
-       else if(State() == PPP_OPENED_STATE && next != State())
+       else if (State() == PPP_OPENED_STATE && next != State())
                DownStarted();
-       
+
        // maybe we do not need the timer anymore
-       if(next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE)
+       if (next < PPP_CLOSING_STATE || next == PPP_OPENED_STATE)
                fNextTimeout = 0;
-       
+
        fState = next;
 }
 
@@ -524,22 +676,22 @@ void
 IPCP::TOGoodEvent()
 {
 #if DEBUG
-printf("IPCP: TOGoodEvent() state=%d\n", State());
+       printf("IPCP: TOGoodEvent() state=%d\n", State());
 #endif
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_CLOSING_STATE:
                        SendTerminateRequest();
                break;
-               
+
                case PPP_ACK_RCVD_STATE:
                        NewState(PPP_REQ_SENT_STATE);
-               
+
                case PPP_REQ_SENT_STATE:
                case PPP_ACK_SENT_STATE:
                        SendConfigureRequest();
                break;
-               
+
                default:
                        IllegalEvent(PPP_TO_GOOD_EVENT);
        }
@@ -550,20 +702,20 @@ void
 IPCP::TOBadEvent()
 {
        TRACE("IPCP: TOBadEvent() state=%d\n", State());
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_CLOSING_STATE:
                        NewState(PPP_INITIAL_STATE);
                        ReportDownEvent();
                break;
-               
+
                case PPP_REQ_SENT_STATE:
                case PPP_ACK_RCVD_STATE:
                case PPP_ACK_SENT_STATE:
                        NewState(PPP_INITIAL_STATE);
                        ReportUpFailedEvent();
                break;
-               
+
                default:
                        IllegalEvent(PPP_TO_BAD_EVENT);
        }
@@ -571,71 +723,76 @@ IPCP::TOBadEvent()
 
 
 void
-IPCP::RCREvent(struct mbuf *packet)
+IPCP::RCREvent(net_buffer *packet)
 {
        TRACE("IPCP: RCREvent() state=%d\n", State());
-       
+
        KPPPConfigurePacket request(packet);
        KPPPConfigurePacket nak(PPP_CONFIGURE_NAK);
        KPPPConfigurePacket reject(PPP_CONFIGURE_REJECT);
-       
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
+               return;
+       ppp_lcp_packet &lcpHeader = bufferheader.Data();
+
        // we should not use the same id as the peer
-       if(fID == mtod(packet, ppp_lcp_packet*)->id)
+       if (fID == lcpHeader.id)
                fID -= 128;
-       
+
        nak.SetID(request.ID());
        reject.SetID(request.ID());
-       
+
        // parse each item
        ppp_configure_item *item;
        in_addr_t *requestedAddress, *wishedAddress = NULL;
-       for(int32 index = 0; index < request.CountItems(); index++) {
+       for (int32 index = 0; index < request.CountItems(); index++) {
                item = request.ItemAt(index);
-               if(!item)
+               if (!item)
                        continue;
-               
+
                // addresses have special handling to reduce code size
-               switch(item->type) {
+               switch (item->type) {
                        case IPCP_ADDRESSES:
                                // abandoned by the standard
                        case IPCP_ADDRESS:
                                wishedAddress = &fPeerRequests.address;
                        break;
-                       
+
                        case IPCP_PRIMARY_DNS:
                                wishedAddress = &fPeerRequests.primaryDNS;
                        break;
-                       
+
                        case IPCP_SECONDARY_DNS:
                                wishedAddress = &fPeerRequests.secondaryDNS;
                        break;
                }
-               
+
                // now parse item
-               switch(item->type) {
+               switch (item->type) {
                        case IPCP_ADDRESSES:
                                // abandoned by the standard
                        case IPCP_ADDRESS:
                        case IPCP_PRIMARY_DNS:
                        case IPCP_SECONDARY_DNS:
-                               if(item->length != 6) {
+                               if (item->length != 6) {
                                        // the packet is invalid
-                                       m_freem(packet);
+                                       gBufferModule->free(packet);
                                        NewState(PPP_INITIAL_STATE);
                                        ReportUpFailedEvent();
                                        return;
                                }
-                               
+
                                requestedAddress = (in_addr_t*) item->data;
-                               if(*wishedAddress == INADDR_ANY) {
-                                       if(*requestedAddress == INADDR_ANY) {
+                               if (*wishedAddress == INADDR_ANY) {
+                                       if (*requestedAddress == INADDR_ANY) {
                                                // we do not have an address 
for you
-                                               m_freem(packet);
+                                               gBufferModule->free(packet);
                                                NewState(PPP_INITIAL_STATE);
                                                ReportUpFailedEvent();
                                                return;
                                        }
-                               } else if(*requestedAddress != *wishedAddress) {
+                               } else if (*requestedAddress != *wishedAddress) 
{
                                        // we do not want this address
                                        ip_item ipItem;
                                        ipItem.type = item->type;
@@ -644,18 +801,18 @@ IPCP::RCREvent(struct mbuf *packet)
                                        nak.AddItem((ppp_configure_item*) 
&ipItem);
                                }
                        break;
-                       
+
 //                     case IPCP_COMPRESSION_PROTOCOL:
                                // TODO: implement me!
 //                     break;
-                       
+
                        default:
                                reject.AddItem(item);
                }
        }
-       
+
        // append additional values to the nak
-       if(!request.ItemWithType(IPCP_ADDRESS) && fPeerRequests.address == 
INADDR_ANY) {
+       if (!request.ItemWithType(IPCP_ADDRESS) && fPeerRequests.address == 
INADDR_ANY) {
                // The peer did not provide us his address. Tell him to do so.
                ip_item ipItem;
                ipItem.type = IPCP_ADDRESS;
@@ -663,430 +820,467 @@ IPCP::RCREvent(struct mbuf *packet)
                ipItem.address = INADDR_ANY;
                nak.AddItem((ppp_configure_item*) &ipItem);
        }
-       
-       if(nak.CountItems() > 0) {
-               RCRBadEvent(nak.ToMbuf(Interface().MRU(), 
Interface().PacketOverhead()), NULL);
-               m_freem(packet);
-       } else if(reject.CountItems() > 0) {
-               RCRBadEvent(NULL, reject.ToMbuf(Interface().MRU(),
-                       Interface().PacketOverhead()));
-               m_freem(packet);
+
+       if (nak.CountItems() > 0) {
+               RCRBadEvent(nak.ToNetBuffer(Interface().MRU()), NULL);
+               gBufferModule->free(packet);
+       } else if (reject.CountItems() > 0) {
+               RCRBadEvent(NULL, reject.ToNetBuffer(Interface().MRU()));
+               gBufferModule->free(packet);
        } else
                RCRGoodEvent(packet);
 }
 
 
 void
-IPCP::RCRGoodEvent(struct mbuf *packet)
+IPCP::RCRGoodEvent(net_buffer *packet)
 {
        TRACE("IPCP: RCRGoodEvent() state=%d\n", State());
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_INITIAL_STATE:
                        NewState(PPP_ACK_SENT_STATE);
                        InitializeRestartCount();
                        SendConfigureRequest();
                        SendConfigureAck(packet);
                break;
-               
+
                case PPP_REQ_SENT_STATE:
                        NewState(PPP_ACK_SENT_STATE);
-               
+
                case PPP_ACK_SENT_STATE:
                        SendConfigureAck(packet);
                break;
-               
+
                case PPP_ACK_RCVD_STATE:
                        NewState(PPP_OPENED_STATE);
                        SendConfigureAck(packet);
                        ReportUpEvent();
                break;
-               
+
                case PPP_OPENED_STATE:
                        NewState(PPP_ACK_SENT_STATE);
                        SendConfigureRequest();
                        SendConfigureAck(packet);
                break;
-               
+
                default:
-                       m_freem(packet);
+                       gBufferModule->free(packet);
        }
 }
 
 
 void
-IPCP::RCRBadEvent(struct mbuf *nak, struct mbuf *reject)
+IPCP::RCRBadEvent(net_buffer *nak, net_buffer *reject)
 {
        TRACE("IPCP: RCRBadEvent() state=%d\n", State());
-       
-       switch(State()) {
+
+       uint16 lcpHdrRejectLength = 0;
+       uint16 lcpHdrNakLength = 0;
+
+       if (nak) {
+               NetBufferHeaderReader<ppp_lcp_packet> 
nakBufferHeaderReader(nak);
+               if (nakBufferHeaderReader.Status() != B_OK)
+                       return;
+               ppp_lcp_packet &lcpNakPacket = nakBufferHeaderReader.Data();
+               lcpHdrNakLength = lcpNakPacket.length;
+       }
+
+
+       if (reject) {
+               NetBufferHeaderReader<ppp_lcp_packet> 
rejectBufferHeaderReader(reject);
+               if (rejectBufferHeaderReader.Status() != B_OK)
+                       return;
+               ppp_lcp_packet &lcpRejectPacket = 
rejectBufferHeaderReader.Data();
+               lcpHdrRejectLength = lcpRejectPacket.length;
+       }
+
+       switch (State()) {
                case PPP_OPENED_STATE:
                        NewState(PPP_REQ_SENT_STATE);
                        SendConfigureRequest();
-               
+
                case PPP_ACK_SENT_STATE:
-                       if(State() == PPP_ACK_SENT_STATE)
+                       if (State() == PPP_ACK_SENT_STATE)
                                NewState(PPP_REQ_SENT_STATE);
                                        // OPENED_STATE might have set this 
already
-               
+
                case PPP_INITIAL_STATE:
                case PPP_REQ_SENT_STATE:
                case PPP_ACK_RCVD_STATE:
-                       if(nak && ntohs(mtod(nak, ppp_lcp_packet*)->length) > 3)
+                       if (nak && ntohs(lcpHdrNakLength) > 3)
                                SendConfigureNak(nak);
-                       else if(reject && ntohs(mtod(reject, 
ppp_lcp_packet*)->length) > 3)
+                       else if (reject && ntohs(lcpHdrRejectLength) > 3)
                                SendConfigureNak(reject);
                return;
                        // prevents the nak/reject from being m_freem()'d
-               
+
                default:
                        ;
        }
-       
-       if(nak)
-               m_freem(nak);
-       if(reject)
-               m_freem(reject);
+
+       if (nak)
+               gBufferModule->free(nak);
+       if (reject)
+               gBufferModule->free(reject);
 }
 
 
 void
-IPCP::RCAEvent(struct mbuf *packet)
+IPCP::RCAEvent(net_buffer *packet)
 {
-       TRACE("IPCP: RCAEvent() state=%d\n", State());
-       
-       if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
+       ERROR("IPCP: RCAEvent() state=%d\n", State());
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
+               return;
+       ppp_lcp_packet &lcpHeader = bufferheader.Data();
+       if (fRequestID != lcpHeader.id) {
                // this packet is not a reply to our request
-               
+
                // TODO: log this event
-               m_freem(packet);
+               gBufferModule->free(packet);
                return;
        }
-       
+
        // parse this ack
        KPPPConfigurePacket ack(packet);
        ppp_configure_item *item;
        in_addr_t *requestedAddress, *wishedAddress = NULL, *configuredAddress 
= NULL;
-       for(int32 index = 0; index < ack.CountItems(); index++) {
+       for (int32 index = 0; index < ack.CountItems(); index++) {
                item = ack.ItemAt(index);
-               if(!item)
+               if (!item)
                        continue;
-               
+
                // addresses have special handling to reduce code size
-               switch(item->type) {
+               switch (item->type) {
                        case IPCP_ADDRESSES:
                                // abandoned by the standard
                        case IPCP_ADDRESS:
                                wishedAddress = &fLocalRequests.address;
                                configuredAddress = 
&fLocalConfiguration.address;
                        break;
-                       
+
                        case IPCP_PRIMARY_DNS:
                                wishedAddress = &fLocalRequests.primaryDNS;
                                configuredAddress = 
&fLocalConfiguration.primaryDNS;
                        break;
-                       
+
                        case IPCP_SECONDARY_DNS:
                                wishedAddress = &fLocalRequests.secondaryDNS;
                                configuredAddress = 
&fLocalConfiguration.secondaryDNS;
                        break;
                }
-               
+
                // now parse item
-               switch(item->type) {
+               switch (item->type) {
                        case IPCP_ADDRESSES:
                                // abandoned by the standard
                        case IPCP_ADDRESS:
                        case IPCP_PRIMARY_DNS:
                        case IPCP_SECONDARY_DNS:
                                requestedAddress = (in_addr_t*) item->data;
-                               if((*wishedAddress == INADDR_ANY && 
*requestedAddress != INADDR_ANY)
+                               if ((*wishedAddress == INADDR_ANY && 
*requestedAddress != INADDR_ANY)
                                                || *wishedAddress == 
*requestedAddress)
                                        *configuredAddress = *requestedAddress;
                        break;
-                       
+
 //                     case IPCP_COMPRESSION_PROTOCOL:
                                // TODO: implement me
 //                     break;
-                       
+
                        default:
                                ;
                }
        }
-       
+
        // if address was not specified we should select the given one
-       if(!ack.ItemWithType(IPCP_ADDRESS))
+       if (!ack.ItemWithType(IPCP_ADDRESS))
                fLocalConfiguration.address = fLocalRequests.address;
-       
-       
-       switch(State()) {
+
+
+       switch (State()) {
                case PPP_INITIAL_STATE:
                        IllegalEvent(PPP_RCA_EVENT);
                break;
-               
+
                case PPP_REQ_SENT_STATE:
                        NewState(PPP_ACK_RCVD_STATE);
                        InitializeRestartCount();
                break;
-               
+
                case PPP_ACK_RCVD_STATE:
                        NewState(PPP_REQ_SENT_STATE);
                        SendConfigureRequest();
                break;
-               
+
                case PPP_ACK_SENT_STATE:
                        NewState(PPP_OPENED_STATE);
                        InitializeRestartCount();
                        ReportUpEvent();
                break;
-               
+
                case PPP_OPENED_STATE:
                        NewState(PPP_REQ_SENT_STATE);
                        SendConfigureRequest();
                break;
-               
+
                default:
                        ;
        }
-       
-       m_freem(packet);
+
+       gBufferModule->free(packet);
 }
 
 
 void
-IPCP::RCNEvent(struct mbuf *packet)
+IPCP::RCNEvent(net_buffer *packet)
 {
        TRACE("IPCP: RCNEvent() state=%d\n", State());
-       
-       if(fRequestID != mtod(packet, ppp_lcp_packet*)->id) {
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
+               return;
+       ppp_lcp_packet &lcpHeader = bufferheader.Data();
+
+       if (fRequestID != lcpHeader.id) {
                // this packet is not a reply to our request
-               
+
                // TODO: log this event
-               m_freem(packet);
+               gBufferModule->free(packet);
                return;
        }
-       
+
        // parse this nak/reject
        KPPPConfigurePacket nak_reject(packet);
        ppp_configure_item *item;
        in_addr_t *requestedAddress;
-       if(nak_reject.Code() == PPP_CONFIGURE_NAK)
-               for(int32 index = 0; index < nak_reject.CountItems(); index++) {
+       if (nak_reject.Code() == PPP_CONFIGURE_NAK)
+               for (int32 index = 0; index < nak_reject.CountItems(); index++) 
{
                        item = nak_reject.ItemAt(index);
-                       if(!item)
+                       if (!item)
                                continue;
-                       
-                       switch(item->type) {
+
+                       switch (item->type) {
                                case IPCP_ADDRESSES:
                                        // abandoned by the standard
                                case IPCP_ADDRESS:
-                                       if(item->length != 6)
+                                       if (item->length != 6)
                                                continue;
-                                       
+
                                        requestedAddress = (in_addr_t*) 
item->data;
-                                       if(fLocalRequests.address == INADDR_ANY
+                                       if (fLocalRequests.address == INADDR_ANY
                                                        && *requestedAddress != 
INADDR_ANY)
                                                fLocalConfiguration.address = 
*requestedAddress;
                                                        // this will be used in 
our next request
                                break;
-                               
+
 //                             case IPCP_COMPRESSION_PROTOCOL:
                                        // TODO: implement me!
 //                             break;
-                               
+
                                case IPCP_PRIMARY_DNS:
-                                       if(item->length != 6)
+                                       if (item->length != 6)
                                                continue;
-                                       
+
                                        requestedAddress = (in_addr_t*) 
item->data;
-                                       if(fRequestPrimaryDNS
+                                       if (fRequestPrimaryDNS
                                                        && 
fLocalRequests.primaryDNS == INADDR_ANY
                                                        && *requestedAddress != 
INADDR_ANY)
                                                fLocalConfiguration.primaryDNS 
= *requestedAddress;
                                                        // this will be used in 
our next request
                                break;
-                               
+
                                case IPCP_SECONDARY_DNS:
-                                       if(item->length != 6)
+                                       if (item->length != 6)
                                                continue;
-                                       
+
                                        requestedAddress = (in_addr_t*) 
item->data;
-                                       if(fRequestSecondaryDNS
+                                       if (fRequestSecondaryDNS
                                                        && 
fLocalRequests.secondaryDNS == INADDR_ANY
                                                        && *requestedAddress != 
INADDR_ANY)
                                                
fLocalConfiguration.secondaryDNS = *requestedAddress;
                                                        // this will be used in 
our next request
                                break;
-                               
+
                                default:
                                        ;
                        }
                }
-       else if(nak_reject.Code() == PPP_CONFIGURE_REJECT)
-               for(int32 index = 0; index < nak_reject.CountItems(); index++) {
+       else if (nak_reject.Code() == PPP_CONFIGURE_REJECT)
+               for (int32 index = 0; index < nak_reject.CountItems(); index++) 
{
                        item = nak_reject.ItemAt(index);
-                       if(!item)
+                       if (!item)
                                continue;
-                       
-                       switch(item->type) {
+
+                       switch (item->type) {
 //                             case IPCP_COMPRESSION_PROTOCOL:
                                        // TODO: implement me!
 //                             break;
-                               
+
                                default:
                                        // DNS and addresses must be supported 
if we set them to auto
-                                       m_freem(packet);
+                                       gBufferModule->free(packet);
                                        NewState(PPP_INITIAL_STATE);
                                        ReportUpFailedEvent();
                                        return;
                        }
                }
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_INITIAL_STATE:
                        IllegalEvent(PPP_RCN_EVENT);
                break;
-               
+
                case PPP_REQ_SENT_STATE:
                case PPP_ACK_SENT_STATE:
                        InitializeRestartCount();
-               
+
                case PPP_ACK_RCVD_STATE:
                case PPP_OPENED_STATE:
-                       if(State() == PPP_ACK_RCVD_STATE || State() == 
PPP_OPENED_STATE)
+                       if (State() == PPP_ACK_RCVD_STATE || State() == 
PPP_OPENED_STATE)
                                NewState(PPP_REQ_SENT_STATE);
                        SendConfigureRequest();
                break;
-               
+
                default:
                        ;
        }
-       
-       m_freem(packet);
+
+       gBufferModule->free(packet);
 }
 
 
 void
-IPCP::RTREvent(struct mbuf *packet)
+IPCP::RTREvent(net_buffer *packet)
 {
        TRACE("IPCP: RTREvent() state=%d\n", State());
-       
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
+               return;
+       ppp_lcp_packet &lcpHeader = bufferheader.Data();
+
        // we should not use the same ID as the peer
-       if(fID == mtod(packet, ppp_lcp_packet*)->id)
+       if (fID == lcpHeader.id)
                fID -= 128;
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_INITIAL_STATE:
                        IllegalEvent(PPP_RTR_EVENT);
                break;
-               
+
                case PPP_ACK_RCVD_STATE:
                case PPP_ACK_SENT_STATE:
                        NewState(PPP_REQ_SENT_STATE);
-               
+
                case PPP_CLOSING_STATE:
                case PPP_REQ_SENT_STATE:
                        SendTerminateAck(packet);
                return;
-                       // do not m_freem() packet
-               
+                       // do not free packet
+
                case PPP_OPENED_STATE:
                        NewState(PPP_CLOSING_STATE);
                        ResetRestartCount();
                        SendTerminateAck(packet);
                return;
-                       // do not m_freem() packet
-               
+                       // do not free packet
+
                default:
                        ;
        }
-       
-       m_freem(packet);
+
+       gBufferModule->free(packet);
 }
 
 
 void
-IPCP::RTAEvent(struct mbuf *packet)
+IPCP::RTAEvent(net_buffer *packet)
 {
        TRACE("IPCP: RTAEvent() state=%d\n", State());
-       
-       if(fTerminateID != mtod(packet, ppp_lcp_packet*)->id) {
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
+               return;
+       ppp_lcp_packet &lcpHeader = bufferheader.Data();
+       if (fTerminateID != lcpHeader.id) {
                // this packet is not a reply to our request
-               
+
                // TODO: log this event
-               m_freem(packet);
+               gBufferModule->free(packet);
                return;
        }
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_INITIAL_STATE:
                        IllegalEvent(PPP_RTA_EVENT);
                break;
-               
+
                case PPP_CLOSING_STATE:
                        NewState(PPP_INITIAL_STATE);
                        ReportDownEvent();
                break;
-               
+
                case PPP_ACK_RCVD_STATE:
                        NewState(PPP_REQ_SENT_STATE);
                break;
-               
+
                case PPP_OPENED_STATE:
                        NewState(PPP_REQ_SENT_STATE);
                        SendConfigureRequest();
                break;
-               
+
                default:
                        ;
        }
-       
-       m_freem(packet);
+
+       gBufferModule->free(packet);
 }
 
 
 void
-IPCP::RUCEvent(struct mbuf *packet)
+IPCP::RUCEvent(net_buffer *packet)
 {
        TRACE("IPCP: RUCEvent() state=%d\n", State());
-       
+
        SendCodeReject(packet);
 }
 
 
 void
-IPCP::RXJBadEvent(struct mbuf *packet)
+IPCP::RXJBadEvent(net_buffer *packet)
 {
        TRACE("IPCP: RXJBadEvent() state=%d\n", State());
-       
-       switch(State()) {
+
+       switch (State()) {
                case PPP_INITIAL_STATE:
                        IllegalEvent(PPP_RXJ_BAD_EVENT);
                break;
-               
+
                case PPP_CLOSING_STATE:
                        NewState(PPP_INITIAL_STATE);
                        ReportDownEvent();
                break;
-               
+
                case PPP_REQ_SENT_STATE:
                case PPP_ACK_RCVD_STATE:
                case PPP_ACK_SENT_STATE:
                        NewState(PPP_INITIAL_STATE);
                        ReportUpFailedEvent();
                break;
-               
+
                case PPP_OPENED_STATE:
                        NewState(PPP_CLOSING_STATE);
                        InitializeRestartCount();
                        SendTerminateRequest();
                break;
-               
+
                default:
                        ;
        }
-       
-       m_freem(packet);
+
+       gBufferModule->free(packet);
 }
 
 
@@ -1105,9 +1299,9 @@ IPCP::ReportUpFailedEvent()
        // reset configurations
        memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration));
        memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration));
-       
+
        UpdateAddresses();
-       
+
        UpFailedEvent();
 }
 
@@ -1116,7 +1310,7 @@ void
 IPCP::ReportUpEvent()
 {
        UpdateAddresses();
-       
+
        UpEvent();
 }
 
@@ -1127,9 +1321,11 @@ IPCP::ReportDownEvent()
        // reset configurations
        memset(&fLocalConfiguration, 0, sizeof(ipcp_configuration));
        memset(&fPeerConfiguration, 0, sizeof(ipcp_configuration));
-       
-       UpdateAddresses();
-       
+
+       // don't update address if connect on demand is enabled
+       dprintf("ppp down, and leaving old address and rotues\n");
+       // UpdateAddresses();
+
        DownEvent();
 }
 
@@ -1156,137 +1352,150 @@ bool
 IPCP::SendConfigureRequest()
 {
        TRACE("IPCP: SendConfigureRequest() state=%d\n", State());
-       
+
        --fRequestCounter;
        fNextTimeout = system_time() + kIPCPStateMachineTimeout;
-       
+
        KPPPConfigurePacket request(PPP_CONFIGURE_REQUEST);
        request.SetID(NextID());
        fRequestID = request.ID();
        ip_item ipItem;
        ipItem.length = 6;
-       
+
        // add address
        ipItem.type = IPCP_ADDRESS;
-       if(fLocalRequests.address == INADDR_ANY)
-               ipItem.address = fLocalConfiguration.address;
+       if (fLocalRequests.address == INADDR_ANY)
+               ipItem.address = (fLocalConfiguration.address);
        else
-               ipItem.address = fLocalRequests.address;
+               ipItem.address =(fLocalRequests.address);
        request.AddItem((ppp_configure_item*) &ipItem);
-       
-       TRACE("IPCP: SCR: confaddr=%lX; reqaddr=%lX; addr=%lX\n",
+
+       TRACE("IPCP: SCR: confaddr=%X; reqaddr=%X; addr=%X\n",
                fLocalConfiguration.address, fLocalRequests.address,
                ((ip_item*)request.ItemAt(0))->address);
-       
+
        // add primary DNS (if needed)
-       if(fRequestPrimaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) {
+       if (fRequestPrimaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) {
                ipItem.type = IPCP_PRIMARY_DNS;
                ipItem.address = fLocalConfiguration.primaryDNS;
                        // at first this is 0.0.0.0, but a nak might have set 
it to a correct value
                request.AddItem((ppp_configure_item*) &ipItem);
        }
-       
+
        // add secondary DNS (if needed)
-       if(fRequestSecondaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) {
+       if (fRequestSecondaryDNS && fLocalRequests.primaryDNS == INADDR_ANY) {
                ipItem.type = IPCP_SECONDARY_DNS;
                ipItem.address = fLocalConfiguration.secondaryDNS;
                        // at first this is 0.0.0.0, but a nak might have set 
it to a correct value
                request.AddItem((ppp_configure_item*) &ipItem);
        }
-       
+
        // TODO: add VJC support
-       
-       return Send(request.ToMbuf(Interface().MRU(),
-               Interface().PacketOverhead())) == B_OK;
+
+       return Send(request.ToNetBuffer(Interface().MRU())) == B_OK;
 }
 
 
 bool
-IPCP::SendConfigureAck(struct mbuf *packet)
+IPCP::SendConfigureAck(net_buffer *packet)
 {
        TRACE("IPCP: SendConfigureAck() state=%d\n", State());
-       
-       if(!packet)
+
+       if (!packet)
+               return false;
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
                return false;
-       
-       mtod(packet, ppp_lcp_packet*)->code = PPP_CONFIGURE_ACK;
+       ppp_lcp_packet &lcpheader = bufferheader.Data();
+       lcpheader.code = PPP_CONFIGURE_ACK;
+
+       bufferheader.Sync();
+
        KPPPConfigurePacket ack(packet);
-       
+
        // verify items
        ppp_configure_item *item;
        in_addr_t *requestedAddress, *wishedAddress = NULL, *configuredAddress 
= NULL;
-       for(int32 index = 0; index < ack.CountItems(); index++) {
+       for (int32 index = 0; index < ack.CountItems(); index++) {
                item = ack.ItemAt(index);
-               if(!item)
+               if (!item)
                        continue;
-               
+
                // addresses have special handling to reduce code size
-               switch(item->type) {
+               switch (item->type) {
                        case IPCP_ADDRESSES:
                                // abandoned by the standard
                        case IPCP_ADDRESS:
                                wishedAddress = &fPeerRequests.address;
                                configuredAddress = &fPeerConfiguration.address;
                        break;
-                       
+
                        case IPCP_PRIMARY_DNS:
                                wishedAddress = &fPeerRequests.primaryDNS;
                                configuredAddress = 
&fPeerConfiguration.primaryDNS;
                        break;
-                       
+
                        case IPCP_SECONDARY_DNS:
                                wishedAddress = &fPeerRequests.secondaryDNS;
                                configuredAddress = 
&fPeerConfiguration.secondaryDNS;
                        break;
                }
-               
+
                // now parse item
-               switch(item->type) {
+               switch (item->type) {
                        case IPCP_ADDRESSES:
                                // abandoned by the standard
                        case IPCP_ADDRESS:
                        case IPCP_PRIMARY_DNS:
                        case IPCP_SECONDARY_DNS:
                                requestedAddress = (in_addr_t*) item->data;
-                               if((*wishedAddress == INADDR_ANY && 
*requestedAddress != INADDR_ANY)
+                               if ((*wishedAddress == INADDR_ANY && 
*requestedAddress != INADDR_ANY)
                                                || *wishedAddress == 
*requestedAddress)
                                        *configuredAddress = *requestedAddress;
                        break;
-                       
+
 //                     case IPCP_COMPRESSION_PROTOCOL:
                                // TODO: implement me!
 //                     break;
-                       
+
                        default:
                                ;
                }
        }
-       
+
        // if address was not specified we should select the given one
-       if(!ack.ItemWithType(IPCP_ADDRESS))
+       if (!ack.ItemWithType(IPCP_ADDRESS))
                fPeerConfiguration.address = fPeerRequests.address;
-       
+
        return Send(packet) == B_OK;
 }
 
 
 bool
-IPCP::SendConfigureNak(struct mbuf *packet)
+IPCP::SendConfigureNak(net_buffer *packet)
 {
        TRACE("IPCP: SendConfigureNak() state=%d\n", State());
-       
-       if(!packet)
+
+       if (!packet)
                return false;
-       
-       ppp_lcp_packet *nak = mtod(packet, ppp_lcp_packet*);
-       if(nak->code == PPP_CONFIGURE_NAK) {
-               if(fNakCounter == 0) {
+
+       NetBufferHeaderReader<ppp_lcp_packet> bufferheader(packet);
+       if (bufferheader.Status() != B_OK)
+               return false;
+
+       ppp_lcp_packet &nak = bufferheader.Data();
+
+       if (nak.code == PPP_CONFIGURE_NAK) {
+               if (fNakCounter == 0) {
                        // We sent enough naks. Let's try a reject.
-                       nak->code = PPP_CONFIGURE_REJECT;
+                       nak.code = PPP_CONFIGURE_REJECT;
                } else
                        --fNakCounter;
        }
-       
+
+       bufferheader.Sync();
+
        return Send(packet) == B_OK;
 }
 
@@ -1295,85 +1504,82 @@ bool
 IPCP::SendTerminateRequest()
 {
        TRACE("IPCP: SendTerminateRequest() state=%d\n", State());
-       
+
        --fTerminateCounter;
        fNextTimeout = system_time() + kIPCPStateMachineTimeout;
-       
-       struct mbuf *packet = m_gethdr(MT_DATA);
-       if(!packet)
+
+       net_buffer *packet = gBufferModule->create(256);
+       if (!packet)
+               return false;
+
+       ppp_lcp_packet *request;
+       status_t status = gBufferModule->append_size(packet, 1492, (void 
**)(&request));
+       if (status != B_OK)
                return false;
-       
-       packet->m_pkthdr.len = packet->m_len = 4;
-       
-       // reserve some space for other protocols
-       packet->m_data += Interface().PacketOverhead();
-       
-       ppp_lcp_packet *request = mtod(packet, ppp_lcp_packet*);
+
        request->code = PPP_TERMINATE_REQUEST;
        request->id = fTerminateID = NextID();
        request->length = htons(4);
-       
+
+       status = gBufferModule->trim(packet, 4);
+       if (status != B_OK)
+               return false;
+
        return Send(packet) == B_OK;
 }
 
 
 bool
-IPCP::SendTerminateAck(struct mbuf *request)
+IPCP::SendTerminateAck(net_buffer *request)
 {
        TRACE("IPCP: SendTerminateAck() state=%d\n", State());
-       
-       struct mbuf *reply = request;
-       
-       ppp_lcp_packet *ack;
-       
-       if(!reply) {
-               reply = m_gethdr(MT_DATA);
-               if(!reply)
+
+       net_buffer *reply = request;
+
+       if (!reply) {
+               reply = gBufferModule->create(256);
+               ppp_lcp_packet *ack;
+               status_t status = gBufferModule->append_size(reply, 1492, (void 
**)(&ack));
+               if (status != B_OK) {
+                       gBufferModule->free(reply);
                        return false;
-               
-               reply->m_data += Interface().PacketOverhead();
-               reply->m_pkthdr.len = reply->m_len = 4;
-               
-               ack = mtod(reply, ppp_lcp_packet*);
+               }
                ack->id = NextID();
-       } else
-               ack = mtod(reply, ppp_lcp_packet*);
-       
-       ack->code = PPP_TERMINATE_ACK;
-       ack->length = htons(4);
-       
+               ack->code = PPP_TERMINATE_ACK;
+               ack->length = htons(4);
+               gBufferModule->trim(reply, 4);
+       } else {
+               NetBufferHeaderReader<ppp_lcp_packet> bufferHeader(reply);
+               if (bufferHeader.Status() < B_OK)
+                       return false;
+               ppp_lcp_packet &ack = bufferHeader.Data();
+               ack.code = PPP_TERMINATE_ACK;
+               ack.length = htons(4);
+       }
+
        return Send(reply) == B_OK;
 }
 
 
 bool
-IPCP::SendCodeReject(struct mbuf *packet)
+IPCP::SendCodeReject(net_buffer *packet)
 {
        TRACE("IPCP: SendCodeReject() state=%d\n", State());
-       
-       if(!packet)
+
+       if (!packet)
                return false;
-       
-       M_PREPEND(packet, 4);
-               // add some space for the header
-       
-       // adjust packet if too big
-       int32 adjust = Interface().MRU();
-       if(packet->m_flags & M_PKTHDR) {
-               adjust -= packet->m_pkthdr.len;
-       } else
-               adjust -= packet->m_len;
-       
-       if(adjust < 0)
-               m_adj(packet, adjust);
-       
-       ppp_lcp_packet *reject = mtod(packet, ppp_lcp_packet*);
-       reject->code = PPP_CODE_REJECT;
-       reject->id = NextID();
-       if(packet->m_flags & M_PKTHDR)
-               reject->length = htons(packet->m_pkthdr.len);
-       else
-               reject->length = htons(packet->m_len);
-       
+
+       NetBufferPrepend<ppp_lcp_packet> bufferHeader(packet);
+       if (bufferHeader.Status() != B_OK)
+               return false;
+
+       ppp_lcp_packet &reject = bufferHeader.Data();
+
+       reject.code = PPP_CODE_REJECT;
+       reject.id = NextID();
+       reject.length = htons(packet->size);
+
+       bufferHeader.Sync();
+
        return Send(packet) == B_OK;
 }
diff --git a/src/add-ons/kernel/network/ppp/ipcp/Protocol.h 
b/src/add-ons/kernel/network/ppp/ipcp/Protocol.h
index 626619b..f8dd13f 100644
--- a/src/add-ons/kernel/network/ppp/ipcp/Protocol.h
+++ b/src/add-ons/kernel/network/ppp/ipcp/Protocol.h
@@ -9,9 +9,11 @@
 #include <driver_settings.h>
 
 #include <KPPPProtocol.h>
-#include <Locker.h>
 
 #include <arpa/inet.h>
+#include <net_datalink.h>
+#include <net_datalink_protocol.h>
+#include <net/route.h>
 
 
 #define IPCP_PROTOCOL  0x8021
@@ -60,46 +62,46 @@ class IPCP : public KPPPProtocol {
        public:
                IPCP(KPPPInterface& interface, driver_parameter *settings);
                virtual ~IPCP();
-               
+
                virtual void Uninit();
-               
+
                ppp_state State() const
                        { return fState; }
-               
+
                virtual status_t StackControl(uint32 op, void *data);
-               
+
                virtual bool Up();
                virtual bool Down();
-               
-               virtual status_t Send(struct mbuf *packet,
+
+               virtual status_t Send(net_buffer *packet,
                        uint16 protocolNumber = IPCP_PROTOCOL);
-               virtual status_t Receive(struct mbuf *packet, uint16 
protocolNumber);
-               status_t ReceiveIPPacket(struct mbuf *packet, uint16 
protocolNumber);
+               virtual status_t Receive(net_buffer *packet, uint16 
protocolNumber);
+               status_t ReceiveIPPacket(net_buffer *packet, uint16 
protocolNumber);
                virtual void Pulse();
 
        private:
                bool ParseSideRequests(const driver_parameter *requests, 
ppp_side side);
                void UpdateAddresses();
                void RemoveRoutes();
-               
+
                // for state machine
                void NewState(ppp_state next);
                uint8 NextID();
                        // return the next id for IPCP packets
-               
+
                // events
                void TOGoodEvent();
                void TOBadEvent();
-               void RCREvent(struct mbuf *packet);
-               void RCRGoodEvent(struct mbuf *packet);
-               void RCRBadEvent(struct mbuf *nak, struct mbuf *reject);
-               void RCAEvent(struct mbuf *packet);
-               void RCNEvent(struct mbuf *packet);
-               void RTREvent(struct mbuf *packet);
-               void RTAEvent(struct mbuf *packet);
-               void RUCEvent(struct mbuf *packet);
-               void RXJBadEvent(struct mbuf *packet);
-               
+               void RCREvent(net_buffer *packet);
+               void RCRGoodEvent(net_buffer *packet);
+               void RCRBadEvent(net_buffer *nak, net_buffer *reject);
+               void RCAEvent(net_buffer *packet);
+               void RCNEvent(net_buffer *packet);
+               void RTREvent(net_buffer *packet);
+               void RTAEvent(net_buffer *packet);
+               void RUCEvent(net_buffer *packet);
+               void RXJBadEvent(net_buffer *packet);
+
                // actions
                void IllegalEvent(ppp_event event);
                void ReportUpFailedEvent();
@@ -108,27 +110,27 @@ class IPCP : public KPPPProtocol {
                void InitializeRestartCount();
                void ResetRestartCount();
                bool SendConfigureRequest();
-               bool SendConfigureAck(struct mbuf *packet);
-               bool SendConfigureNak(struct mbuf *packet);
+               bool SendConfigureAck(net_buffer *packet);
+               bool SendConfigureNak(net_buffer *packet);
                bool SendTerminateRequest();
-               bool SendTerminateAck(struct mbuf *request = NULL);
-               bool SendCodeReject(struct mbuf *packet);
+               bool SendTerminateAck(net_buffer *request = NULL);
+               bool SendCodeReject(net_buffer *packet);
 
        private:
                ipcp_configuration fLocalConfiguration, fPeerConfiguration;
                ipcp_requests fLocalRequests, fPeerRequests;
-               
+
                // default route
                struct sockaddr_in fGateway;
-               rtentry *fDefaultRoute;
-               
+               net_route *fDefaultRoute;
+
                // used for local requests
                bool fRequestPrimaryDNS, fRequestSecondaryDNS;
-               
+
                // for state machine
                ppp_state fState;
-               vint32 fID;
-               
+               int32 fID;
+
                // counters and timers
                int32 fMaxRequest, fMaxTerminate, fMaxNak;
                int32 fRequestCounter, fTerminateCounter, fNakCounter;
diff --git a/src/add-ons/kernel/network/ppp/ipcp/ipcp.cpp 
b/src/add-ons/kernel/network/ppp/ipcp/ipcp.cpp
index fbf4137..bfa2f42 100644
--- a/src/add-ons/kernel/network/ppp/ipcp/ipcp.cpp
+++ b/src/add-ons/kernel/network/ppp/ipcp/ipcp.cpp
@@ -5,21 +5,24 @@
 
 #include <KernelExport.h>
 #include <driver_settings.h>
-#include <core_funcs.h>
-#include <net_module.h>
 
+#include <NetBufferUtilities.h>
+#include <net_buffer.h>
+#include <net_stack.h>
+
+#include <KPPPDefs.h>
 #include <KPPPInterface.h>
 #include <KPPPModule.h>
 
 #include "Protocol.h"
 
+#define IPCP_MODULE_NAME               NETWORK_MODULES_ROOT "/ppp/ipcp"
 
-#define IPCP_MODULE_NAME               NETWORK_MODULES_ROOT "ppp/ipcp"
-
-struct protosw *gProto[IPPROTO_MAX];
-struct core_module_info *core = NULL;
 status_t std_ops(int32 op, ...);
 
+net_stack_module_info *gStackModule = NULL;
+net_buffer_module_info *gBufferModule = NULL;
+
 
 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 // TODO: Remove isascii() (needed for inet_aton()) when our kernel is finished!
@@ -28,7 +31,7 @@ extern "C"
 int
 isascii(char c)
 {
-       return c & ~0x7f == 0; // If c is a 7 bit value.
+       return ((c & (~0x7f)) == 0); // If c is a 7 bit value.
 }
 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
@@ -38,22 +41,22 @@ bool
 add_to(KPPPInterface& mainInterface, KPPPInterface *subInterface,
        driver_parameter *settings, ppp_module_key_type type)
 {
-       if(type != PPP_PROTOCOL_KEY_TYPE)
+       if (type != PPP_PROTOCOL_KEY_TYPE)
                return B_ERROR;
-       
+
        IPCP *ipcp;
        bool success;
-       if(subInterface) {
+       if (subInterface) {
                ipcp = new IPCP(*subInterface, settings);
                success = subInterface->AddProtocol(ipcp);
        } else {
                ipcp = new IPCP(mainInterface, settings);
                success = mainInterface.AddProtocol(ipcp);
        }
-       
+
        TRACE("IPCP: add_to(): %s\n",
                success && ipcp && ipcp->InitCheck() == B_OK ? "OK" : "ERROR");
-       
+
        return success && ipcp && ipcp->InitCheck() == B_OK;
 }
 
@@ -71,24 +74,30 @@ static ppp_module_info ipcp_module = {
 
 _EXPORT
 status_t
-std_ops(int32 op, ...) 
+std_ops(int32 op, ...)
 {
-       switch(op) {
+       switch (op) {
                case B_MODULE_INIT:
-                       if(get_module(NET_CORE_MODULE_NAME, (module_info**) 
&core) != B_OK)
+                       if (get_module(NET_STACK_MODULE_NAME,
+                                       (module_info**) &gStackModule) != B_OK)
+                               return B_ERROR;
+                       if (get_module(NET_BUFFER_MODULE_NAME,
+                                       (module_info **)&gBufferModule) != 
B_OK) {
+                               put_module(NET_STACK_MODULE_NAME);
                                return B_ERROR;
-                       memset(gProto, 0, sizeof(struct protosw*) * 
IPPROTO_MAX);
-                       add_protosw(gProto, NET_LAYER1);
-               return B_OK;
-               
+                       }
+                       return B_OK;
+                       break;
+
                case B_MODULE_UNINIT:
-                       put_module(NET_CORE_MODULE_NAME);
-               break;
-               
+                       put_module(NET_BUFFER_MODULE_NAME);
+                       put_module(NET_STACK_MODULE_NAME);
+                       break;
+
                default:
                        return B_ERROR;
        }
-       
+
        return B_OK;
 }
 
diff --git a/src/add-ons/kernel/network/ppp/pap/Jamfile 
b/src/add-ons/kernel/network/ppp/pap/Jamfile
index f6781b5..935a090 100644
--- a/src/add-ons/kernel/network/ppp/pap/Jamfile
+++ b/src/add-ons/kernel/network/ppp/pap/Jamfile
@@ -1,6 +1,7 @@
 SubDir HAIKU_TOP src add-ons kernel network ppp pap ;
 
 SetSubDirSupportedPlatformsBeOSCompatible ;
+SubDirC++Flags -fno-rtti ;
 
 if $(TARGET_PLATFORM) != haiku {
        UseHeaders [ FDirName $(HAIKU_TOP) headers posix ] : true ;
@@ -8,20 +9,13 @@ if $(TARGET_PLATFORM) != haiku {
                # Unfortunately we get more than we want, namely all POSIX 
headers.
 }
 
-# for kernel_cpp.h and BLocker
-UseHeaders [ FDirName $(HAIKU_TOP) headers cpp ] : true ;
+UsePrivateKernelHeaders ;
 UsePrivateHeaders net ;
 UsePrivateHeaders [ FDirName kernel ] ;
 UsePrivateHeaders [ FDirName kernel util ] ;
 UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared
        libkernelppp headers ] : true ;
 
-
-{
-       SubDirC++Flags -fno-rtti ;
-}
-
-
 KernelAddon pap :
        pap.cpp
        Protocol.cpp
@@ -31,5 +25,5 @@ LinkAgainst pap : libkernelppp.a ;
 
 # Installation
 HaikuInstall install-networking
-       : /boot/home/config/add-ons/kernel/obos_network/ppp
+       : /boot/home/config/add-ons/kernel/haiku_network/ppp
        : pap ;
diff --git a/src/add-ons/kernel/network/ppp/pap/Protocol.cpp 
b/src/add-ons/kernel/network/ppp/pap/Protocol.cpp
index 29d8760..904f49b 100644
--- a/src/add-ons/kernel/network/ppp/pap/Protocol.cpp
+++ b/src/add-ons/kernel/network/ppp/pap/Protocol.cpp
@@ -9,9 +9,9 @@
 
 #include <cstring>
 #include <netinet/in.h>
-#include <core_funcs.h>
-#include <sys/sockio.h>
 
+#include <net_buffer.h>
+#include <sys/sockio.h>
 
 static const bigtime_t kPAPTimeout = 3000000;
        // 3 seconds
@@ -35,19 +35,27 @@ PAPHandler::PAPHandler(PAP& owner, KPPPInterface& interface)
 
 
 status_t
+PAPHandler::SendingAck(const KPPPConfigurePacket& ack)
+{
+       TRACE("%s::%s: We should activate PAP Protocol here\n", __FILE__, 
__func__);
+       return KPPPOptionHandler::SendingAck(ack);
+}
+
+
+status_t
 PAPHandler::AddToRequest(KPPPConfigurePacket& request)
 {
        // only local authenticators send requests to peer
-       if(Owner().Side() != PPP_PEER_SIDE)
+       if (Owner().Side() != PPP_PEER_SIDE)
                return B_OK;
-       
+
        authentication_item item;
        item.type = kAuthenticationType;
        item.length = sizeof(item);
        item.protocolNumber = htons(PAP_PROTOCOL);
-       
+
        request.AddItem((ppp_configure_item*) &item);
-       
+
        return B_OK;
 }
 
@@ -57,15 +65,15 @@ PAPHandler::ParseRequest(const KPPPConfigurePacket& request,
        int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& reject)
 {
        // only local authenticators handle requests from peer
-       if(Owner().Side() != PPP_LOCAL_SIDE)
+       if (Owner().Side() != PPP_LOCAL_SIDE)
                return B_OK;
-       
+
        // we merely check if the values are correct
        authentication_item *item = (authentication_item*) 
request.ItemAt(index);
-       if(item->type != kAuthenticationType
+       if (item->type != kAuthenticationType
                        || item->length != 4 || ntohs(item->protocolNumber) != 
PAP_PROTOCOL)
                return B_ERROR;
-       
+
        return B_OK;
 }
 
@@ -92,9 +100,9 @@ PAP::~PAP()
 status_t
 PAP::InitCheck() const
 {
-       if(Side() != PPP_LOCAL_SIDE && Side() != PPP_PEER_SIDE)
+       if (Side() != PPP_LOCAL_SIDE && Side() != PPP_PEER_SIDE)
                return B_ERROR;
-       
+
        return KPPPProtocol::InitCheck();
 }
 
@@ -103,14 +111,14 @@ bool
 PAP::Up()
 {
        TRACE("PAP: Up() state=%d\n", State());
-       
-       switch(State()) {
+
+       switch (State()) {
                case INITIAL:
-                       if(Side() == PPP_LOCAL_SIDE) {
+                       if (Side() == PPP_LOCAL_SIDE) {
                                NewState(REQ_SENT);
                                InitializeRestartCount();
                                SendRequest();
-                       } else if(Side() == PPP_PEER_SIDE) {
+                       } else if (Side() == PPP_PEER_SIDE) {
                                NewState(WAITING_FOR_REQ);
                                InitializeRestartCount();
                                fNextTimeout = system_time() + kPAPTimeout;
@@ -119,11 +127,11 @@ PAP::Up()
                                return false;
                        }
                break;
-               
+
                default:
                        ;
        }
-       
+
        return true;
 }
 
@@ -132,8 +140,8 @@ bool
 PAP::Down()
 {
        TRACE("PAP: Down() state=%d\n", State());
-       
-       switch(Interface().Phase()) {
+
+       switch (Interface().Phase()) {
                case PPP_DOWN_PHASE:
                        // interface finished terminating
                case PPP_ESTABLISHED_PHASE:
@@ -141,82 +149,83 @@ PAP::Down()
                        NewState(INITIAL);
                        DownEvent();
                break;
-               
+
 /*             case PPP_TERMINATION_PHASE:
                        // interface is terminating
                break;
-               
+
                case PPP_ESTABLISHMENT_PHASE:
                        // interface is reconfiguring
                break;

[ *** diff truncated: 10885 lines dropped *** ]



Other related posts:

  • » [haiku-commits] haiku: hrev49969 - in src: add-ons/kernel/network/ppp/shared/libkernelppp add-ons/kernel/network/ppp/ipcp add-ons/kernel/network/ppp/pppoe bin/network/pppconfig add-ons/kernel/network/ppp/shared/libppp - waddlesplash