From a602502a7e98b8fddfab7af9cafe06af78a9d2ae Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Sat, 6 Sep 2003 01:00:12 +0000 Subject: [PATCH] Finished first set of needed features (tests will follow as soon as the needed kernel modules are available). Next step will be to add: - Protocol-Field-Compression support (including PFC handler) - MRU option handler - ?simple authentication option handler (helper class)? git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4513 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../net/ppp/headers/KPPPConfigurePacket.h | 2 + src/tests/kits/net/ppp/headers/KPPPDefs.h | 5 +- src/tests/kits/net/ppp/headers/KPPPDevice.h | 10 +- .../kits/net/ppp/headers/KPPPEncapsulator.h | 11 +- .../kits/net/ppp/headers/KPPPInterface.h | 20 +- src/tests/kits/net/ppp/headers/KPPPManager.h | 1 + src/tests/kits/net/ppp/headers/KPPPModule.h | 9 +- .../kits/net/ppp/headers/KPPPOptionHandler.h | 20 +- src/tests/kits/net/ppp/headers/KPPPProtocol.h | 11 +- src/tests/kits/net/ppp/headers/KPPPUtils.h | 23 + src/tests/kits/net/ppp/headers/LockerHelper.h | 2 +- src/tests/kits/net/ppp/headers/PPPControl.h | 132 +++-- src/tests/kits/net/ppp/headers/PPPDefs.h | 10 +- .../kits/net/ppp/headers/PPPReportDefs.h | 6 +- .../kits/net/ppp/src/KPPPConfigurePacket.cpp | 30 ++ src/tests/kits/net/ppp/src/KPPPDevice.cpp | 86 ++- .../kits/net/ppp/src/KPPPEncapsulator.cpp | 87 +-- src/tests/kits/net/ppp/src/KPPPInterface.cpp | 505 +++++++++++++----- src/tests/kits/net/ppp/src/KPPPLCP.cpp | 10 +- .../kits/net/ppp/src/KPPPOptionHandler.cpp | 44 +- src/tests/kits/net/ppp/src/KPPPProtocol.cpp | 66 +-- .../kits/net/ppp/src/KPPPStateMachine.cpp | 32 +- 22 files changed, 757 insertions(+), 365 deletions(-) diff --git a/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h b/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h index 212330baba..584ea15960 100644 --- a/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h +++ b/src/tests/kits/net/ppp/headers/KPPPConfigurePacket.h @@ -45,6 +45,8 @@ class PPPConfigurePacket { int32 CountItems() const { return fItems.CountItems(); } ppp_configure_item *ItemAt(int32 index) const; + bool HasItemWithType(uint8 type) const; + ppp_configure_item *ItemWithType(uint8 type) const; struct mbuf *ToMbuf(uint32 reserve = 0); // the user is responsible for freeing the mbuf diff --git a/src/tests/kits/net/ppp/headers/KPPPDefs.h b/src/tests/kits/net/ppp/headers/KPPPDefs.h index 3057421c67..32998072e3 100644 --- a/src/tests/kits/net/ppp/headers/KPPPDefs.h +++ b/src/tests/kits/net/ppp/headers/KPPPDefs.h @@ -18,8 +18,9 @@ typedef uint32 interface_id; // module key types (used when loading a module) -enum { - PPP_LOAD_MODULE_TYPE, +enum PPP_MODULE_KEY_TYPE { + PPP_UNDEFINED_KEY_TYPE = -1, + PPP_LOAD_MODULE_TYPE = 0, PPP_DEVICE_TYPE, PPP_PROTOCOL_TYPE, PPP_AUTHENTICATOR_TYPE, diff --git a/src/tests/kits/net/ppp/headers/KPPPDevice.h b/src/tests/kits/net/ppp/headers/KPPPDevice.h index a9c9c44d7d..71fb8bf23b 100644 --- a/src/tests/kits/net/ppp/headers/KPPPDevice.h +++ b/src/tests/kits/net/ppp/headers/KPPPDevice.h @@ -19,7 +19,7 @@ class PPPDevice { public: - PPPDevice(const char *name, uint32 overhead, PPPInterface *interface, + PPPDevice(const char *name, PPPInterface& interface, driver_parameter *settings); virtual ~PPPDevice(); @@ -28,10 +28,7 @@ class PPPDevice { const char *Name() const { return fName; } - uint32 Overhead() const - { return fOverhead; } - - PPPInterface *Interface() const + PPPInterface& Interface() const { return fInterface; } driver_parameter *Settings() const { return fSettings; } @@ -85,8 +82,7 @@ class PPPDevice { private: char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; - uint32 fOverhead; - PPPInterface *fInterface; + PPPInterface& fInterface; driver_parameter *fSettings; uint32 fMTU; diff --git a/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h b/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h index 99d65ea7d9..c71ddfd1a6 100644 --- a/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h +++ b/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h @@ -24,7 +24,7 @@ class PPPEncapsulator { PPPEncapsulator(const char *name, PPP_PHASE phase, PPP_ENCAPSULATION_LEVEL level, uint16 protocol, int32 addressFamily, uint32 overhead, - PPPInterface *interface, driver_parameter *settings, + PPPInterface& interface, driver_parameter *settings, int32 flags = PPP_NO_FLAGS); virtual ~PPPEncapsulator(); @@ -41,7 +41,7 @@ class PPPEncapsulator { uint32 Overhead() const { return fOverhead; } - PPPInterface *Interface() const + PPPInterface& Interface() const { return fInterface; } driver_parameter *Settings() const { return fSettings; } @@ -58,8 +58,6 @@ class PPPEncapsulator { bool IsEnabled() const { return fEnabled; } - void SetUpRequested(bool requested = true) - { fUpRequested = requested; } bool IsUpRequested() const { return fUpRequested; } @@ -92,6 +90,9 @@ class PPPEncapsulator { virtual void Pulse(); protected: + void SetUpRequested(bool requested = true) + { fUpRequested = requested; } + void UpStarted(); void DownStarted(); @@ -109,7 +110,7 @@ class PPPEncapsulator { PPP_ENCAPSULATION_LEVEL fLevel; uint16 fProtocol; int32 fAddressFamily; - PPPInterface *fInterface; + PPPInterface& fInterface; driver_parameter *fSettings; int32 fFlags; diff --git a/src/tests/kits/net/ppp/headers/KPPPInterface.h b/src/tests/kits/net/ppp/headers/KPPPInterface.h index 9c6aebeb56..df58f3cfba 100644 --- a/src/tests/kits/net/ppp/headers/KPPPInterface.h +++ b/src/tests/kits/net/ppp/headers/KPPPInterface.h @@ -74,12 +74,13 @@ class PPPInterface { bigtime_t DisconnectAfterIdleSince() const { return fDisconnectAfterIdleSince; } - void SetLinkMTU(uint32 linkMTU); - uint32 LinkMTU() const - { return fLinkMTU; } - // this is the smallest MTU that we and the peer have + void SetMRU(uint32 MRU); uint32 MRU() const { return fMRU; } + // this is the smallest MRU that we and the peer have + uint32 InterfaceMTU() const + { return fInterfaceMTU; } + // this is the MRU including encapsulator overhead status_t Control(uint32 op, void *data, size_t length); @@ -92,12 +93,14 @@ class PPPInterface { int32 CountProtocols() const { return fProtocols.CountItems(); } PPPProtocol *ProtocolAt(int32 index) const; - PPPProtocol *ProtocolFor(uint16 protocol, int32 start = 0) const; + PPPProtocol *ProtocolFor(uint16 protocol, int32 *start = NULL) const; int32 IndexOfProtocol(PPPProtocol *protocol) const { return fProtocols.IndexOf(protocol); } bool AddEncapsulator(PPPEncapsulator *encapsulator); bool RemoveEncapsulator(PPPEncapsulator *encapsulator); + int32 CountEncapsulators() const; + PPPEncapsulator *EncapsulatorAt(int32 index) const; PPPEncapsulator *FirstEncapsulator() const { return fFirstEncapsulator; } PPPEncapsulator *EncapsulatorFor(uint16 protocol, @@ -144,7 +147,7 @@ class PPPInterface { bool LoadModules(driver_settings *settings, int32 start, int32 count); bool LoadModule(const char *name, driver_parameter *parameter, - int32 type); + PPP_MODULE_KEY_TYPE type); status_t Send(struct mbuf *packet, uint16 protocol); status_t Receive(struct mbuf *packet, uint16 protocol); @@ -164,7 +167,7 @@ class PPPInterface { // saves the returned ifnet structure bool UnregisterInterface(); - void CalculateMRU(); + void CalculateInterfaceMTU(); void CalculateBaudRate(); void Redial(); @@ -191,7 +194,7 @@ class PPPInterface { ppp_manager_info *fManager; bigtime_t fIdleSince, fDisconnectAfterIdleSince; - uint32 fLinkMTU, fMRU, fHeaderLength; + uint32 fMRU, fInterfaceMTU, fHeaderLength; PPPInterface *fParent; List fChildren; @@ -211,6 +214,7 @@ class PPPInterface { BLocker& fLock; status_t fInitStatus; + int32 fDeleteCounter; }; diff --git a/src/tests/kits/net/ppp/headers/KPPPManager.h b/src/tests/kits/net/ppp/headers/KPPPManager.h index fa3d361134..35216ac5d2 100644 --- a/src/tests/kits/net/ppp/headers/KPPPManager.h +++ b/src/tests/kits/net/ppp/headers/KPPPManager.h @@ -28,6 +28,7 @@ typedef struct ppp_manager_info { // you should always create interfaces using this function void (*delete_interface)(interface_id ID); // this marks the interface for deletion + void (*remove_interface)(interface_id ID); ifnet* (*register_interface)(interface_id ID); bool (*unregister_interface)(interface_id ID); diff --git a/src/tests/kits/net/ppp/headers/KPPPModule.h b/src/tests/kits/net/ppp/headers/KPPPModule.h index 018dce74fb..0a43784016 100644 --- a/src/tests/kits/net/ppp/headers/KPPPModule.h +++ b/src/tests/kits/net/ppp/headers/KPPPModule.h @@ -16,11 +16,12 @@ class PPPInterface; typedef struct ppp_module_info { module_info minfo; status_t (*control)(uint32 op, void *data, size_t length); - status_t (*add_to)(PPPInterface *mainInterface, PPPInterface *subInterface, - driver_parameter *settings, int32 type); + status_t (*add_to)(PPPInterface& mainInterface, PPPInterface *subInterface, + driver_parameter *settings, PPP_MODULE_KEY_TYPE type); // multilink: handlers that must run on a real device - // should be added to subInterface while mainInterface - // handlers are used for the bundle of interfaces + // should be added to subInterface (may be NULL) + // while mainInterface handlers are used for the + // bundle of interfaces } ppp_module_info; diff --git a/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h b/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h index 1548cfd1fc..cea3b2dcac 100644 --- a/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h +++ b/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h @@ -21,23 +21,25 @@ class PPPConfigurePacket; class PPPOptionHandler { public: - PPPOptionHandler(const char *name, PPPInterface *interface, + PPPOptionHandler(const char *name, PPPInterface& interface, driver_parameter *settings); virtual ~PPPOptionHandler(); virtual status_t InitCheck() const; + const char *Name() const + { return fName; } + + PPPInterface& Interface() const + { return fInterface; } + driver_parameter *Settings() const + { return fSettings; } + void SetEnabled(bool enabled = true); bool IsEnabled() const { return fEnabled; } - const char *Name() const - { return fName; } - - PPPInterface *Interface() const - { return fInterface; } - driver_parameter *Settings() const - { return fSettings; } + virtual status_t Control(uint32 op, void *data, size_t length); virtual void Reset() = 0; // e.g.: remove list of rejected values @@ -61,7 +63,7 @@ class PPPOptionHandler { private: char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; - PPPInterface *fInterface; + PPPInterface& fInterface; driver_parameter *fSettings; bool fEnabled; diff --git a/src/tests/kits/net/ppp/headers/KPPPProtocol.h b/src/tests/kits/net/ppp/headers/KPPPProtocol.h index 9992e77579..9cbdea0e34 100644 --- a/src/tests/kits/net/ppp/headers/KPPPProtocol.h +++ b/src/tests/kits/net/ppp/headers/KPPPProtocol.h @@ -18,7 +18,7 @@ class PPPInterface; class PPPProtocol { public: PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol, - int32 addressFamily, PPPInterface *interface, + int32 addressFamily, PPPInterface& interface, driver_parameter *settings, int32 flags = PPP_NO_FLAGS); virtual ~PPPProtocol(); @@ -30,7 +30,7 @@ class PPPProtocol { PPP_PHASE Phase() const { return fPhase; } - PPPInterface *Interface() const + PPPInterface& Interface() const { return fInterface; } driver_parameter *Settings() const { return fSettings; } @@ -47,8 +47,6 @@ class PPPProtocol { bool IsEnabled() const { return fEnabled; } - void SetUpRequested(bool requested = true) - { fUpRequested = requested; } bool IsUpRequested() const { return fUpRequested; } @@ -71,6 +69,9 @@ class PPPProtocol { virtual void Pulse(); protected: + void SetUpRequested(bool requested = true) + { fUpRequested = requested; } + void UpStarted(); void DownStarted(); @@ -84,7 +85,7 @@ class PPPProtocol { PPP_PHASE fPhase; uint16 fProtocol; int32 fAddressFamily; - PPPInterface *fInterface; + PPPInterface& fInterface; driver_parameter *fSettings; int32 fFlags; diff --git a/src/tests/kits/net/ppp/headers/KPPPUtils.h b/src/tests/kits/net/ppp/headers/KPPPUtils.h index e9cbae81bf..617bc33117 100644 --- a/src/tests/kits/net/ppp/headers/KPPPUtils.h +++ b/src/tests/kits/net/ppp/headers/KPPPUtils.h @@ -8,6 +8,29 @@ #ifndef _K_PPP_UTILS__H #define _K_PPP_UTILS__H +#ifndef _K_PPP_DEFS__H +#include +#endif + + +// helper functions +template +inline +bool +is_handler_allowed(T& handler, PPP_STATE state, PPP_PHASE phase) +{ + if(handler.Protocol() == PPP_LCP_PROTOCOL) + return true; + else if(state != PPP_OPENED_STATE) + return false; + else if(phase > PPP_AUTHENTICATION_PHASE + || (phase >= PPP_ESTABLISHMENT_PHASE + && handler.Flags() & PPP_ALWAYS_ALLOWED)) + return true; + else + return false; +} + // These are very simple send/receive_data functions with a timeout // and there is a race condition beween has_data() and send/receive_data(). diff --git a/src/tests/kits/net/ppp/headers/LockerHelper.h b/src/tests/kits/net/ppp/headers/LockerHelper.h index 9e4af94d92..132ce8275b 100644 --- a/src/tests/kits/net/ppp/headers/LockerHelper.h +++ b/src/tests/kits/net/ppp/headers/LockerHelper.h @@ -31,7 +31,7 @@ class LockerHelper { public: LockerHelper(BLocker& lock) : fLock(&lock) { - if(fLock->Lock() != B_OK) + if(!fLock->Lock()) fLock = NULL; } diff --git a/src/tests/kits/net/ppp/headers/PPPControl.h b/src/tests/kits/net/ppp/headers/PPPControl.h index 4940ab017a..dfdb06d4f2 100644 --- a/src/tests/kits/net/ppp/headers/PPPControl.h +++ b/src/tests/kits/net/ppp/headers/PPPControl.h @@ -15,32 +15,27 @@ // starting values and other values for control ops #define PPP_RESERVE_OPS_COUNT 0xFFFF #define PPP_OPS_START B_DEVICE_OP_CODES_END + 1 +#define PPP_INTERFACE_OPS_START PPP_OPS_START + PPP_RESERVE_OPS_COUNT #define PPP_DEVICE_OPS_START PPP_OPS_START + 2 * PPP_RESERVE_OPS_COUNT #define PPP_PROTOCOL_OPS_START PPP_OPS_START + 3 * PPP_RESERVE_OPS_COUNT #define PPP_ENCAPSULATOR_OPS_START PPP_OPS_START + 4 * PPP_RESERVE_OPS_COUNT #define PPP_OPTION_HANDLER_OPS_START PPP_OPS_START + 5 * PPP_RESERVE_OPS_COUNT #define PPP_LCP_EXTENSION_OPS_START PPP_OPS_START + 6 * PPP_RESERVE_OPS_COUNT -#define PPP_COMMON_PROTO_ENCAPS_OPS_START PPP_OPS_START + 10 * PPP_RESERVE_OPS_COUNT +#define PPP_COMMON_OPS_START PPP_OPS_START + 10 * PPP_RESERVE_OPS_COUNT +#define PPP_COMMON_PROTO_ENCAPS_OPS_START PPP_OPS_START + 11 * PPP_RESERVE_OPS_COUNT #define PPP_USER_OPS_START PPP_OPS_START + 32 * PPP_RESERVE_OPS_COUNT enum PPP_CONTROL_OPS { // ----------------------------------------------------- // PPPInterface - PPPC_GET_STATUS = PPP_OPS_START, - PPPC_GET_MRU, + PPPC_GET_INTERFACE_INFO = PPP_INTERFACE_OPS_START, PPPC_SET_MRU, - PPPC_GET_LINK_MTU, - PPPC_SET_LINK_MTU, - PPPC_GET_DIAL_ON_DEMAND, PPPC_SET_DIAL_ON_DEMAND, - PPPC_GET_AUTO_REDIAL, PPPC_SET_AUTO_REDIAL, - PPPC_GET_PROTOCOLS_COUNT, - PPPC_GET_ENCAPSULATORS_COUNT, - PPPC_GET_OPTION_HANDLERS_COUNT, - PPPC_GET_LCP_EXTENSIONS_COUNT, - PPPC_GET_CHILDREN_COUNT, + + // handler access + PPPC_CONTROL_DEVICE, PPPC_CONTROL_PROTOCOL, PPPC_CONTROL_ENCAPSULATOR, PPPC_CONTROL_OPTION_HANDLER, @@ -50,9 +45,8 @@ enum PPP_CONTROL_OPS { // ----------------------------------------------------- // PPPDevice - PPPC_GET_MTU = PPP_DEVICE_OPS_START, + PPPC_GET_DEVICE_INFO = PPP_DEVICE_OPS_START, PPPC_SET_MTU, - PPPC_GET_PREFERRED_MTU, // ----------------------------------------------------- // ----------------------------------------------------- @@ -65,6 +59,7 @@ enum PPP_CONTROL_OPS { // ----------------------------------------------------- // PPPOptionHandler + PPPC_GET_OPTION_HANDLER_INFO = PPP_OPTION_HANDLER_OPS_START, // ----------------------------------------------------- // ----------------------------------------------------- @@ -72,45 +67,116 @@ enum PPP_CONTROL_OPS { // ----------------------------------------------------- // ----------------------------------------------------- - // PPPProtocol and PPPEncapsulator - PPPC_GET_NAME, - PPPC_GET_ENABLED = PPP_COMMON_PROTO_ENCAPS_OPS_START, + // Common/mixed ops + PPPC_GET_HANDLER_INFO = PPP_COMMON_OPS_START, PPPC_SET_ENABLED, // ----------------------------------------------------- + // ----------------------------------------------------- + // PPPProtocol and PPPEncapsulator + // ----------------------------------------------------- + PPP_CONTROL_OPS_END = B_DEVICE_OP_CODES_END + 0xFFFF }; -typedef struct ppp_control_structure { +typedef struct ppp_control_info { uint32 index; // index of interface/protocol/encapsulator/etc. uint32 op; // the Control()/ioctl() opcode - - union { - void *data; - ppp_control_struct *subcontrol; - } pointer; - // either a pointer to the data or a pointer to a control structure for - // accessing protocols/encapsulators/etc. - + void *data; size_t length; - // not always needed -} ppp_control_structure; + // should always be set +} ppp_control_info; -typedef struct ppp_status_structure { +// ----------------------------------------------------------- +// structures for storing information about interface/handlers +// use the xxx_info_t structures when allocating memory (they +// reserve memory for future implementations) +// ----------------------------------------------------------- +#define _PPP_INFO_T_SIZE_ 256 + +typedef struct ppp_interface_info { + const driver_settings *settings; + PPP_MODE mode; PPP_STATE state; PPP_PHASE phase; PPP_AUTHENTICATION_STATUS authenticationStatus, peerAuthenticationStatus; - bigtime_t idle_since; + uint32 protocolsCount, encapsulatorsCount, optionHandlersCount, + LCPExtensionsCount, childrenCount; + uint32 MRU, interfaceMTU; - uint8 _reserved_[64 - (sizeof(PPP_MODE) + sizeof(PPP_STATE) + sizeof(PPP_PHASE) - + 2 * sizeof(PPP_AUTHENTICATION_STATUS) + sizeof(bigtime_t))]; -} ppp_status_structure; + bigtime_t idleSince, disconnectAfterIdleSince; + + bool doesDialOnDemand, doesAutoRedial, hasDevice, isMultilink, hasParent; +} ppp_interface_info; +typedef struct ppp_interface_info_t { + ppp_interface_info info; + uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_interface_info)]; +} ppp_interface_info_t; + + +// devices are special handlers, so they have their own structure +typedef struct ppp_device_info { + char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; + + const driver_parameter *settings; + + uint32 MTU, preferredMTU; + uint32 inputTransferRate, outputTransferRate, outputBytesCount; +} ppp_device_info; +typedef struct ppp_device_info_t { + ppp_device_info info; + uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_device_info)]; +} ppp_device_info_t; + + +typedef struct ppp_handler_info { + char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; + + // general + const driver_parameter *settings; + + PPP_PHASE phase; + int32 addressFamily, flags; + uint16 protocol; + + bool isEnabled; + + // only protocol and encapsulator + bool isUpRequested; + PPP_PHASE connectionStatus; + // there are four possible states: + // PPP_ESTABLISHED_PHASE - IsUp() == true + // PPP_DOWN_PHASE - IsDown() == true + // PPP_ESTABLISHMENT_PHASE - IsGoingUp() == true + // PPP_TERMINATION_PHASE - IsGoingDown() == true + + // only encapsulator + PPP_ENCAPSULATION_LEVEL level; + uint32 overhead; +} ppp_handler_info; +typedef struct ppp_handler_info_t { + ppp_handler_info info; + uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_handler_info)]; +} ppp_handler_info_t; + + +typedef struct ppp_option_handler_info { + char name[PPP_HANDLER_NAME_LENGTH_LIMIT + 1]; + + const driver_parameter *settings; + + bool isEnabled; +} ppp_option_handler_info; +typedef struct ppp_option_handler_info_t { + ppp_option_handler_info info; + uint8 _reserved_[_PPP_INFO_T_SIZE_ - sizeof(ppp_option_handler_info)]; +} ppp_option_handler_info_t; #endif diff --git a/src/tests/kits/net/ppp/headers/PPPDefs.h b/src/tests/kits/net/ppp/headers/PPPDefs.h index 0e95f5f44f..6984e41819 100644 --- a/src/tests/kits/net/ppp/headers/PPPDefs.h +++ b/src/tests/kits/net/ppp/headers/PPPDefs.h @@ -12,7 +12,7 @@ // various constants -#define PPP_HANDLER_NAME_LENGTH_LIMIT 255 +#define PPP_HANDLER_NAME_LENGTH_LIMIT 63 // if the name is longer than this value it will be truncated // settings keys @@ -66,13 +66,17 @@ enum { enum { PPP_NO_FLAGS = 0x00, PPP_ALWAYS_ALLOWED = 0x01, - // protocol may send/receive in PPP_ESTABLISHMENT_PHASE + // protocol may send/receive in Phase() >= PPP_ESTABLISHMENT_PHASE, + // but only LCP is allowed in State() != PPP_OPENED_STATE! PPP_NEEDS_DOWN = 0x02, // protocol needs a Down() in addition to a Reset() to // terminate the connection properly (losing the connection // still results in a Reset() only) - PPP_NOT_IMPORTANT = 0x03 + PPP_NOT_IMPORTANT = 0x04, // if this protocol fails to go up we do not disconnect + PPP_INCLUDES_NCP = 0x08 + // This protocol includes the corresponding NCP protocol (e.g.: IPCP + IP). + // All protocol values will also be checked against Protocol() & 0x7FFF. }; // phase when the protocol is brought up diff --git a/src/tests/kits/net/ppp/headers/PPPReportDefs.h b/src/tests/kits/net/ppp/headers/PPPReportDefs.h index 332ddc83ad..1f4cc7dec2 100644 --- a/src/tests/kits/net/ppp/headers/PPPReportDefs.h +++ b/src/tests/kits/net/ppp/headers/PPPReportDefs.h @@ -25,11 +25,11 @@ enum PPP_REPORT_FLAGS { }; // report types +// the first 16 report types are reserved for the interface manager enum PPP_REPORT_TYPE { - PPP_DESTRUCTION_REPORT = 0, + PPP_DESTRUCTION_REPORT = 16, // the interface is being destroyed (no code is needed) - PPP_CONNECTION_REPORT = 1, - PPP_AUTHENTICATION_REPORT = 2 + PPP_CONNECTION_REPORT = 17 }; // report codes (type-specific) diff --git a/src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp b/src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp index 549a6aa536..1f5ab1f06f 100644 --- a/src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp +++ b/src/tests/kits/net/ppp/src/KPPPConfigurePacket.cpp @@ -107,6 +107,36 @@ PPPConfigurePacket::ItemAt(int32 index) const } +bool +PPPConfigurePacket::HasItemWithType(uint8 type) const +{ + ppp_configure_item *item; + + for(int32 index; index < CountItems(); index++) { + item = ItemAt(index); + if(item && item->type == type) + return true; + } + + return false; +} + + +ppp_configure_item* +PPPConfigurePacket::ItemWithType(uint8 type) const +{ + ppp_configure_item *item; + + for(int32 index; index < CountItems(); index++) { + item = ItemAt(index); + if(item && item->type == type) + return item; + } + + return NULL; +} + + struct mbuf* PPPConfigurePacket::ToMbuf(uint32 reserve = 0) { diff --git a/src/tests/kits/net/ppp/src/KPPPDevice.cpp b/src/tests/kits/net/ppp/src/KPPPDevice.cpp index 4c06783b0a..83b44cf545 100644 --- a/src/tests/kits/net/ppp/src/KPPPDevice.cpp +++ b/src/tests/kits/net/ppp/src/KPPPDevice.cpp @@ -10,36 +10,33 @@ #include #include +#include -PPPDevice::PPPDevice(const char *name, uint32 overhead, PPPInterface *interface, + +PPPDevice::PPPDevice(const char *name, PPPInterface& interface, driver_parameter *settings) - : fOverhead(overhead), fInterface(interface), - fSettings(settings) + : fInterface(interface), fSettings(settings), fMTU(1500) { if(name) { strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT); fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0; } else - strcpy(fName, ""); + strcpy(fName, "???"); - SetMTU(1500); - - if(interface) - interface->SetDevice(this); + interface.SetDevice(this); } PPPDevice::~PPPDevice() { - if(Interface()) - Interface()->SetDevice(NULL); + Interface().SetDevice(NULL); } status_t PPPDevice::InitCheck() const { - if(!Interface() || !Settings()) + if(!Settings()) return B_ERROR; return B_OK; @@ -50,37 +47,43 @@ status_t PPPDevice::Control(uint32 op, void *data, size_t length) { switch(op) { - // TODO: - // get: - // - name - // - mtu (+ preferred) - // - status - // - transfer rates + case PPPC_GET_DEVICE_INFO: { + if(length < sizeof(ppp_device_info_t) || !data) + return B_NO_MEMORY; + + ppp_device_info *info = (ppp_device_info*) data; + memset(info, 0, sizeof(ppp_device_info_t)); + strcpy(info->name, Name()); + info->settings = Settings(); + info->MTU = MTU(); + info->preferredMTU = PreferredMTU(); + info->inputTransferRate = InputTransferRate(); + info->outputTransferRate = OutputTransferRate(); + info->outputBytesCount = CountOutputBytes(); + } break; + + case PPPC_SET_MTU: + if(length < sizeof(uint32) || !data) + return B_ERROR; + + return SetMTU(*((uint32*)data)) ? B_OK : B_ERROR; + break; default: - return B_ERROR; + return PPP_UNHANDLED; } return B_OK; } -bool -PPPDevice::SetMTU(uint32 MTU) -{ - fMTU = MTU; - - return true; -} - - status_t PPPDevice::PassToInterface(struct mbuf *packet) { - if(!Interface() || !Interface()->InQueue()) + if(!Interface().InQueue()) return B_ERROR; - IFQ_ENQUEUE(Interface()->InQueue(), packet); + IFQ_ENQUEUE(Interface().InQueue(), packet); return B_OK; } @@ -96,20 +99,14 @@ PPPDevice::Pulse() bool PPPDevice::UpStarted() const { - if(!Interface()) - return false; - - return Interface()->StateMachine().TLSNotify(); + return Interface().StateMachine().TLSNotify(); } bool PPPDevice::DownStarted() const { - if(!Interface()) - return false; - - return Interface()->StateMachine().TLFNotify(); + return Interface().StateMachine().TLFNotify(); } @@ -118,10 +115,7 @@ PPPDevice::UpFailedEvent() { fIsUp = false; - if(!Interface()) - return; - - Interface()->StateMachine().UpFailedEvent(); + Interface().StateMachine().UpFailedEvent(); } @@ -130,10 +124,7 @@ PPPDevice::UpEvent() { fIsUp = true; - if(!Interface()) - return; - - Interface()->StateMachine().UpEvent(); + Interface().StateMachine().UpEvent(); } @@ -142,8 +133,5 @@ PPPDevice::DownEvent() { fIsUp = false; - if(!Interface()) - return; - - Interface()->StateMachine().DownEvent(); + Interface().StateMachine().DownEvent(); } diff --git a/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp index 87abb3732a..d0a948ec05 100644 --- a/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp +++ b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp @@ -6,12 +6,15 @@ //--------------------------------------------------------------------- #include +#include + +#include PPPEncapsulator::PPPEncapsulator(const char *name, PPP_PHASE phase, PPP_ENCAPSULATION_LEVEL level, uint16 protocol, int32 addressFamily, uint32 overhead, - PPPInterface *interface, driver_parameter *settings, + PPPInterface& interface, driver_parameter *settings, int32 flags = PPP_NO_FLAGS) : fOverhead(overhead), fPhase(phase), fLevel(level), fProtocol(protocol), fAddressFamily(addressFamily), fInterface(interface), @@ -22,24 +25,22 @@ PPPEncapsulator::PPPEncapsulator(const char *name, PPP_PHASE phase, strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT); fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0; } else - strcpy(fName, ""); + strcpy(fName, "???"); - if(interface) - interface->AddEncapsulator(this); + interface.AddEncapsulator(this); } PPPEncapsulator::~PPPEncapsulator() { - if(Interface()) - Interface()->RemoveEncapsulator(this); + Interface().RemoveEncapsulator(this); } status_t PPPEncapsulator::InitCheck() const { - if(!Interface() || !Settings()) + if(!Settings()) return B_ERROR; return B_OK; @@ -51,13 +52,10 @@ PPPEncapsulator::SetEnabled(bool enabled = true) { fEnabled = enabled; - if(!Interface()) - return; - if(!enabled) { if(IsUp() || IsGoingUp()) Down(); - } else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface()->IsUp()) + } else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface().IsUp()) Up(); } @@ -66,16 +64,34 @@ status_t PPPEncapsulator::Control(uint32 op, void *data, size_t length) { switch(op) { - // TODO: - // get: - // - name - // - level, protocol, address family, overhead - // - status (Is(Going)Up/Down/UpRequested/Enabled) - // set: - // - enabled + case PPPC_GET_HANDLER_INFO: { + if(length < sizeof(ppp_handler_info_t) || !data) + return B_ERROR; + + ppp_handler_info *info = (ppp_handler_info*) data; + memset(info, 0, sizeof(ppp_handler_info_t)); + strcpy(info->name, Name()); + info->settings = Settings(); + info->phase = Phase(); + info->addressFamily = AddressFamily(); + info->flags = Flags(); + info->protocol = Protocol(); + info->isEnabled = IsEnabled(); + info->isUpRequested = IsUpRequested(); + info->connectionStatus = fConnectionStatus; + info->level = Level(); + info->overhead = Overhead(); + } break; + + case PPPC_SET_ENABLED: + if(length < sizeof(uint32) || !data) + return B_ERROR; + + SetEnabled(*((uint32*)data)); + break; default: - return B_ERROR; + return PPP_UNHANDLED; } return B_OK; @@ -85,12 +101,18 @@ PPPEncapsulator::Control(uint32 op, void *data, size_t length) status_t PPPEncapsulator::SendToNext(struct mbuf *packet, uint16 protocol) const { - if(Next()) - return Next()->Send(packet, protocol); - else if(Interface()) - return Interface()->SendToDevice(packet, protocol); - else - return B_ERROR; + // Find the next possible handler for this packet. + // This handler should be: + // - enabled + // - allowed to send + if(Next()) { + if(Next()->IsEnabled() + && is_handler_allowed(*Next(), Interface().State(), Interface().Phase())) + return Next()->Send(packet, protocol); + else + return Next()->SendToNext(packet, protocol); + } else + return Interface().SendToDevice(packet, protocol); } @@ -120,10 +142,7 @@ PPPEncapsulator::UpFailedEvent() { fConnectionStatus = PPP_DOWN_PHASE; - if(!Interface()) - return; - - Interface()->StateMachine().UpFailedEvent(this); + Interface().StateMachine().UpFailedEvent(this); } @@ -132,10 +151,7 @@ PPPEncapsulator::UpEvent() { fConnectionStatus = PPP_ESTABLISHED_PHASE; - if(!Interface()) - return; - - Interface()->StateMachine().UpEvent(this); + Interface().StateMachine().UpEvent(this); } @@ -144,8 +160,5 @@ PPPEncapsulator::DownEvent() { fConnectionStatus = PPP_DOWN_PHASE; - if(!Interface()) - return; - - Interface()->StateMachine().DownEvent(this); + Interface().StateMachine().DownEvent(this); } diff --git a/src/tests/kits/net/ppp/src/KPPPInterface.cpp b/src/tests/kits/net/ppp/src/KPPPInterface.cpp index 319273f099..8336f0637e 100644 --- a/src/tests/kits/net/ppp/src/KPPPInterface.cpp +++ b/src/tests/kits/net/ppp/src/KPPPInterface.cpp @@ -5,7 +5,7 @@ // Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de //--------------------------------------------------------------------- -// Stdio.h must be included before PPPModule.h/PPPManager.h because +// stdio.h must be included before PPPModule.h/PPPManager.h because // dprintf is defined twice with different return values, once with // void (KernelExport.h) and once with int (stdio.h). #include @@ -16,8 +16,10 @@ #include // our other classes +#include #include #include +#include #include #include #include @@ -40,10 +42,11 @@ typedef struct redial_info { thread_id *thread; } redial_info; -status_t redial_func(void *data); +status_t redial_thread(void *data); // other functions status_t in_queue_thread(void *data); +status_t interface_deleter_thread(void *data); PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, @@ -51,12 +54,12 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, : fID(ID), fSettings(dup_driver_settings(settings)), fStateMachine(*this), fLCP(*this), fReportManager(StateMachine().Locker()), fIfnet(NULL), fUpThread(-1), fRedialThread(-1), fDialRetry(0), - fDialRetriesLimit(0), fIdleSince(0), fLinkMTU(1500), fDevice(NULL), - fFirstEncapsulator(NULL), fLock(StateMachine().Locker()) + fDialRetriesLimit(0), fIdleSince(0), fMRU(1500), fDevice(NULL), + fFirstEncapsulator(NULL), fLock(StateMachine().Locker()), fDeleteCounter(0) { // set up queue fInQueue = start_ifq(); - fInQueueThread = spawn_thread(in_queue_thread, "PPPInterface: Input", + fInQueueThread = spawn_thread(in_queue_thread, "PPPInterface: in_queue_thread", B_NORMAL_PRIORITY, this); resume_thread(fInQueueThread); @@ -124,9 +127,23 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings, PPPInterface::~PPPInterface() { - if(fLock.Lock() != B_OK) - return;; - // make sure no thread wants to call Unlock() on fLock after it is deleted + ++fDeleteCounter; + + // make sure we are not accessible by any thread before we continue + UnregisterInterface(); + + if(fManager) + fManager->remove_interface(ID()); + + // Call Down() until we get a lock on an interface that is down. + // This lock is not released until we are actually deleted. + while(true) { + Down(); + fLock.Lock(); + if(State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE) + break; + fLock.Unlock(); + } Report(PPP_DESTRUCTION_REPORT, 0, NULL, 0); // tell all listeners that we are being destroyed @@ -135,13 +152,10 @@ PPPInterface::~PPPInterface() stop_ifq(InQueue()); wait_for_thread(fInQueueThread, &tmp); - Down(); - UnregisterInterface(); - wait_for_thread(fRedialThread, &tmp); while(CountChildren()) - ChildAt(0)->Delete(); + delete ChildAt(0); delete Device(); @@ -156,16 +170,34 @@ PPPInterface::~PPPInterface() free(fModules.ItemAt(index)); } - put_module(PPP_MANAGER_MODULE_NAME); - free_driver_settings(fSettings); + + if(Parent()) + Parent()->RemoveChild(this); + + if(fManager) + put_module(PPP_MANAGER_MODULE_NAME); } void PPPInterface::Delete() { - fManager->delete_interface(ID()); + if(atomic_add(&fDeleteCounter, 1) > 0) + return; + // only one thread should delete us! + + if(fManager) + fManager->delete_interface(ID()); + // This will mark us for deletion. + // Any subsequent calls to delete_interface() will do nothing. + else { + // We were not created by the manager. + // Spawn a thread that will delete us. + thread_id interfaceDeleterThread = spawn_thread(interface_deleter_thread, + "PPPInterface: interface_deleter_thread", B_NORMAL_PRIORITY, this); + resume_thread(interfaceDeleterThread); + } } @@ -187,13 +219,13 @@ PPPInterface::InitCheck() const void -PPPInterface::SetLinkMTU(uint32 linkMTU) +PPPInterface::SetMRU(uint32 MRU) { LockerHelper locker(fLock); - fLinkMTU = linkMTU; + fMRU = MRU; - CalculateMRU(); + CalculateInterfaceMTU(); } @@ -201,16 +233,124 @@ status_t PPPInterface::Control(uint32 op, void *data, size_t length) { switch(op) { - // TODO: - // add: - // - routing Control() to encapsulators/protocols/option_handlers - // (calling their Control() method) - // - adding modules - // - setting AutoRedial and DialOnDemand + case PPPC_GET_INTERFACE_INFO: { + if(length < sizeof(ppp_interface_info_t) || !data) + return B_NO_MEMORY; + + ppp_interface_info *info = (ppp_interface_info*) data; + memset(info, 0, sizeof(ppp_interface_info_t)); + info->settings = Settings(); + info->mode = Mode(); + info->state = State(); + info->phase = Phase(); + info->authenticationStatus = StateMachine().AuthenticationStatus(); + info->peerAuthenticationStatus = + StateMachine().PeerAuthenticationStatus(); + info->protocolsCount = CountProtocols(); + info->encapsulatorsCount = CountEncapsulators(); + info->optionHandlersCount = LCP().CountOptionHandlers(); + info->LCPExtensionsCount = 0; + info->childrenCount = CountChildren(); + info->MRU = MRU(); + info->interfaceMTU = InterfaceMTU(); + info->idleSince = IdleSince(); + info->disconnectAfterIdleSince = DisconnectAfterIdleSince(); + info->doesDialOnDemand = DoesDialOnDemand(); + info->doesAutoRedial = DoesAutoRedial(); + info->hasDevice = Device(); + info->isMultilink = IsMultilink(); + info->hasParent = Parent(); + } break; + case PPPC_SET_MRU: + if(length < sizeof(uint32) || !data) + return B_ERROR; + + SetMRU(*((uint32*)data)); + break; + + case PPPC_SET_DIAL_ON_DEMAND: + if(length < sizeof(uint32) || !data) + return B_NO_MEMORY; + + SetDialOnDemand(*((uint32*)data)); + break; + + case PPPC_SET_AUTO_REDIAL: + if(length < sizeof(uint32) || !data) + return B_NO_MEMORY; + + SetAutoRedial(*((uint32*)data)); + break; + + case PPPC_CONTROL_DEVICE: { + if(length < sizeof(ppp_control_info) || !data) + return B_ERROR; + + ppp_control_info *control = (ppp_control_info*) data; + if(control->index != 0 || !Device()) + return B_BAD_INDEX; + + return Device()->Control(control->op, control->data, control->length); + } break; + + case PPPC_CONTROL_PROTOCOL: { + if(length < sizeof(ppp_control_info) || !data) + return B_ERROR; + + ppp_control_info *control = (ppp_control_info*) data; + PPPProtocol *protocol_handler = ProtocolAt(control->index); + if(!protocol_handler) + return B_BAD_INDEX; + + return protocol_handler->Control(control->op, control->data, + control->length); + } break; + + case PPPC_CONTROL_ENCAPSULATOR: { + if(length < sizeof(ppp_control_info) || !data) + return B_ERROR; + + ppp_control_info *control = (ppp_control_info*) data; + PPPEncapsulator *encapsulator_handler = EncapsulatorAt(control->index); + if(!encapsulator_handler) + return B_BAD_INDEX; + + return encapsulator_handler->Control(control->op, control->data, + control->length); + } break; + + case PPPC_CONTROL_OPTION_HANDLER: { + if(length < sizeof(ppp_control_info) || !data) + return B_ERROR; + + ppp_control_info *control = (ppp_control_info*) data; + PPPOptionHandler *option_handler = LCP().OptionHandlerAt(control->index); + if(!option_handler) + return B_BAD_INDEX; + + return option_handler->Control(control->op, control->data, + control->length); + } break; + + case PPPC_CONTROL_LCP_EXTENSION: { + return PPP_UNHANDLED; + } break; + + case PPPC_CONTROL_CHILD: { + if(length < sizeof(ppp_control_info) || !data) + return B_ERROR; + + ppp_control_info *control = (ppp_control_info*) data; + PPPInterface *child = ChildAt(control->index); + if(!child) + return B_BAD_INDEX; + + return child->Control(control->op, control->data, control->length); + } break; default: - return B_ERROR; + return PPP_UNHANDLED; } return B_OK; @@ -238,9 +378,9 @@ PPPInterface::SetDevice(PPPDevice *device) fDevice = device; - fLinkMTU = fDevice->MTU(); + fMRU = fDevice->MTU(); - CalculateMRU(); + CalculateInterfaceMTU(); CalculateBaudRate(); return true; @@ -300,14 +440,28 @@ PPPInterface::ProtocolAt(int32 index) const PPPProtocol* -PPPInterface::ProtocolFor(uint16 protocol, int32 start = 0) const +PPPInterface::ProtocolFor(uint16 protocol, int32 *start = NULL) const { - if(start < 0) + // The iteration style in this method is strange C/C++. + // Explanation: I use this style because it makes extending ProtocolFor + // and EncapsulatorFor simpler as that they look very similar, now. + + int32 index = start ? *start : 0; + + if(index < 0) return NULL; - for(int32 i = start; i < fProtocols.CountItems(); i++) - if(fProtocols.ItemAt(i)->Protocol() == protocol) - return fProtocols.ItemAt(i); + PPPProtocol *current = ProtocolAt(index); + + for(; current; current = ProtocolAt(++index)) { + if(current->Protocol() == protocol + || (current->Flags() & PPP_INCLUDES_NCP + && current->Protocol() & 0x7FFF == protocol & 0x7FFF)) { + if(start) + *start = index; + return current; + } + } return NULL; } @@ -354,7 +508,7 @@ PPPInterface::AddEncapsulator(PPPEncapsulator *encapsulator) previous->SetNext(encapsulator); } - CalculateMRU(); + CalculateInterfaceMTU(); if(IsUp()) encapsulator->Up(); @@ -386,7 +540,7 @@ PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator) current->SetNext(NULL); - CalculateMRU(); + CalculateInterfaceMTU(); return true; } @@ -399,15 +553,42 @@ PPPInterface::RemoveEncapsulator(PPPEncapsulator *encapsulator) } +int32 +PPPInterface::CountEncapsulators() const +{ + PPPEncapsulator *encapsulator = FirstEncapsulator(); + int32 count = 0; + for(; encapsulator; encapsulator = encapsulator->Next()) + ++count; + + return count; +} + + PPPEncapsulator* -PPPInterface::EncapsulatorFor(uint16 protocol, - PPPEncapsulator *start = NULL) const +PPPInterface::EncapsulatorAt(int32 index) const +{ + PPPEncapsulator *encapsulator = FirstEncapsulator(); + int32 currentIndex = 0; + for(; encapsulator; encapsulator = encapsulator->Next(), ++currentIndex) + if(currentIndex == index) + return encapsulator; + + return NULL; +} + + +PPPEncapsulator* +PPPInterface::EncapsulatorFor(uint16 protocol, PPPEncapsulator *start = NULL) const { PPPEncapsulator *current = start ? start : fFirstEncapsulator; - for(; current; current = current->Next()) - if(current->Protocol() == protocol) + for(; current; current = current->Next()) { + if(current->Protocol() == protocol + || (current->Flags() & PPP_INCLUDES_NCP + && current->Protocol() & 0x7FFF == protocol & 0x7FFF)) return current; + } return current; } @@ -442,7 +623,7 @@ PPPInterface::RemoveChild(PPPInterface *child) // parents cannot exist without their children if(CountChildren() == 0 && fManager && Ifnet()) - fManager->delete_interface(ID()); + Delete(); return true; } @@ -495,7 +676,7 @@ PPPInterface::SetDialOnDemand(bool dialondemand = true) bool PPPInterface::Up() { - if(!InitCheck() || Phase() == PPP_TERMINATION_PHASE) + if(InitCheck() != B_OK || Phase() == PPP_TERMINATION_PHASE) return false; if(IsUp()) @@ -504,8 +685,11 @@ PPPInterface::Up() ppp_report_packet report; thread_id me = find_thread(NULL), sender; - // one thread has to do the real task while all other threads are observers - fLock.Lock(); + // One thread has to do the real task while all other threads are observers. + // Lock needs timeout because destructor could have locked the interface. + while(!fLock.LockWithTimeout(100000) != B_NO_ERROR) + if(fDeleteCounter > 0) + return false; if(fUpThread == -1) fUpThread = me; @@ -518,15 +702,19 @@ PPPInterface::Up() while(true) { if(IsUp()) { - ReportManager().DisableReports(PPP_CONNECTION_REPORT, me); + // lock needs timeout because destructor could have locked the interface + while(!fLock.LockWithTimeout(100000) != B_NO_ERROR) + if(fDeleteCounter > 0) + return true; if(me == fUpThread) { - fLock.Lock(); fDialRetry = 0; fUpThread = -1; - fLock.Unlock(); } + ReportManager().DisableReports(PPP_CONNECTION_REPORT, me); + fLock.Unlock(); + return true; } @@ -578,7 +766,7 @@ PPPInterface::Up() fUpThread = -1; if(!DoesDialOnDemand() && report.code != PPP_REPORT_DOWN_SUCCESSFUL) - fManager->delete_interface(ID()); + Delete(); } PPP_REPLY(sender, B_OK); @@ -616,7 +804,7 @@ PPPInterface::Up() if(!DoesDialOnDemand() && report.code != PPP_REPORT_DOWN_SUCCESSFUL) - fManager->delete_interface(ID()); + Delete(); PPP_REPLY(sender, B_OK); ReportManager().DisableReports(PPP_CONNECTION_REPORT, me); @@ -643,7 +831,7 @@ PPPInterface::Up() if(!DoesDialOnDemand() && report.code != PPP_REPORT_DOWN_SUCCESSFUL) - fManager->delete_interface(ID()); + Delete(); return false; } @@ -661,7 +849,7 @@ PPPInterface::Up() bool PPPInterface::Down() { - if(!InitCheck()) + if(InitCheck() != B_OK) return false; // this locked section guarantees that there are no state changes before we @@ -682,6 +870,12 @@ PPPInterface::Down() if(receive_data(&sender, &report, sizeof(report)) != PPP_REPORT_CODE) continue; + if(report.type == PPP_DESTRUCTION_REPORT) + return true; + + if(report.type != PPP_CONNECTION_REPORT) + continue; + if(report.code == PPP_REPORT_DOWN_SUCCESSFUL || report.code == PPP_REPORT_UP_ABORTED || (State() == PPP_INITIAL_STATE && Phase() == PPP_DOWN_PHASE)) { @@ -691,7 +885,7 @@ PPPInterface::Down() } if(!DoesDialOnDemand()) - fManager->delete_interface(ID()); + Delete(); return true; } @@ -713,18 +907,18 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) return false; // a running connection may not change - int32 type; + PPP_MODULE_KEY_TYPE type; // which type key was used for loading this module? const char *name = NULL; // multilink handling - for(int32 i = start; - i < settings->parameter_count && i < start + count; i++) { - if(!strcasecmp(settings->parameters[i].name, PPP_MULTILINK_KEY) - && settings->parameters[i].value_count > 0) { - if(!LoadModule(settings->parameters[i].values[0], - settings->parameters[i].parameters, PPP_MULTILINK_TYPE)) + for(int32 index = start; + index < settings->parameter_count && index < start + count; index++) { + if(!strcasecmp(settings->parameters[index].name, PPP_MULTILINK_KEY) + && settings->parameters[index].value_count > 0) { + if(!LoadModule(settings->parameters[index].values[0], + settings->parameters[index].parameters, PPP_MULTILINK_TYPE)) return false; break; } @@ -739,11 +933,11 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) return true; } - for(int32 i = start; - i < settings->parameter_count && i < start + count; i++) { - type = -1; + for(int32 index = start; + index < settings->parameter_count && index < start + count; index++) { + type = PPP_UNDEFINED_KEY_TYPE; - name = settings->parameters[i].name; + name = settings->parameters[index].name; if(!strcasecmp(name, PPP_LOAD_MODULE_KEY)) type = PPP_LOAD_MODULE_TYPE; @@ -757,10 +951,10 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) type = PPP_PEER_AUTHENTICATOR_TYPE; if(type >= 0) - for(int32 value_id = 0; value_id < settings->parameters[i].value_count; + for(int32 value_id = 0; value_id < settings->parameters[index].value_count; value_id++) - if(!LoadModule(settings->parameters[i].values[value_id], - settings->parameters[i].parameters, type)) + if(!LoadModule(settings->parameters[index].values[value_id], + settings->parameters[index].parameters, type)) return false; } @@ -770,7 +964,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count) bool PPPInterface::LoadModule(const char *name, driver_parameter *parameter, - int32 type) + PPP_MODULE_KEY_TYPE type) { if(Phase() != PPP_DOWN_PHASE) return false; @@ -791,7 +985,7 @@ PPPInterface::LoadModule(const char *name, driver_parameter *parameter, // for putting them on our destruction fModules.AddItem(module_name); - return module->add_to(Parent()?Parent():this, this, parameter, type); + return module->add_to(Parent()?*Parent():*this, this, parameter, type); } @@ -817,16 +1011,37 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocol) if(DoesDialOnDemand() && Phase() == PPP_DOWN_PHASE) Up(); - // If this protocol is always allowed we should send the packet. - // Note that these protocols are not passed to encapsulators! - PPPProtocol *sending_protocol = ProtocolFor(protocol); + // find the protocol handler for the current protocol number + int32 index = 0; + PPPProtocol *sending_protocol = ProtocolFor(protocol, &index); + while(sending_protocol && !sending_protocol->IsEnabled()) + sending_protocol = ProtocolFor(protocol, &(++index)); + + // Check if we must encapsulate the packet. + // We do not necessarily need a handler for 'protocol'. + // In such a case we still encapsulate the packet. + // Protocols which have the PPP_ALWAYS_ALLOWED flag set are never + // encapsulated. if(sending_protocol && sending_protocol->Flags() & PPP_ALWAYS_ALLOWED - && sending_protocol->IsEnabled() && fDevice->IsUp()) { + && is_handler_allowed(*sending_protocol, State(), Phase())) { fIdleSince = system_time(); return SendToDevice(packet, protocol); } - // never send normal protocols when we are down + // try the same for the encapsulator handler + PPPEncapsulator *sending_encapsulator = EncapsulatorFor(protocol); + while(sending_encapsulator && sending_encapsulator->Next() + && !sending_encapsulator->IsEnabled()) + sending_encapsulator = sending_encapsulator->Next() ? + EncapsulatorFor(protocol, sending_encapsulator->Next()) : NULL; + + if(sending_encapsulator && sending_encapsulator->Flags() & PPP_ALWAYS_ALLOWED + && is_handler_allowed(*sending_encapsulator, State(), Phase())) { + fIdleSince = system_time(); + return SendToDevice(packet, protocol); + } + + // never send normal protocols when we are not up if(!IsUp()) { m_freem(packet); return B_ERROR; @@ -841,7 +1056,11 @@ PPPInterface::Send(struct mbuf *packet, uint16 protocol) if(!fFirstEncapsulator->IsEnabled()) return fFirstEncapsulator->SendToNext(packet, protocol); - return fFirstEncapsulator->Send(packet, protocol); + if(is_handler_allowed(*fFirstEncapsulator, State(), Phase())) + return fFirstEncapsulator->Send(packet, protocol); + + m_freem(packet); + return B_ERROR; } @@ -854,43 +1073,42 @@ PPPInterface::Receive(struct mbuf *packet, uint16 protocol) int32 result = PPP_REJECTED; // assume we have no handler + // Set our interface as the receiver. + // The real netstack protocols (IP, IPX, etc.) might get confused if our + // interface is a main interface and at the same time is not registered + // because then there is no receiver interface. + // PPP NCPs should be aware of that! + if(packet->m_flags & M_PKTHDR && Ifnet() != NULL) + packet->m_pkthdr.rcvif = Ifnet(); + // Find handler and let it parse the packet. // The handler does need not be up because if we are a server // the handler might be upped by this packet. PPPEncapsulator *encapsulator_handler = EncapsulatorFor(protocol); for(; encapsulator_handler; - encapsulator_handler = EncapsulatorFor(protocol, encapsulator_handler->Next())) { - if(!encapsulator_handler->IsEnabled()) { - if(!encapsulator_handler->Next()) - break; - + encapsulator_handler = + encapsulator_handler->Next() ? + EncapsulatorFor(protocol, encapsulator_handler->Next()) : NULL) { + if(!encapsulator_handler->IsEnabled() + || !is_handler_allowed(*encapsulator_handler, State(), Phase())) continue; - // disabled handlers should not be used - } + // skip handler if disabled or not allowed result = encapsulator_handler->Receive(packet, protocol); - if(result == PPP_UNHANDLED) { - if(!encapsulator_handler->Next()) - break; - + if(result == PPP_UNHANDLED) continue; - } return result; } // no encapsulator handler could be found; try a protocol handler - PPPProtocol *protocol_handler; - for(int32 index = 0; index < CountProtocols(); index++) { - protocol_handler = ProtocolAt(index); - if(protocol != protocol_handler->Protocol()) + int32 index = 0; + PPPProtocol *protocol_handler = ProtocolFor(protocol, &index); + for(; protocol_handler; protocol_handler = ProtocolFor(protocol, &(++index))) { + if(!protocol_handler->IsEnabled() + || !is_handler_allowed(*protocol_handler, State(), Phase())) continue; - - if(!protocol_handler->IsEnabled()) { - // disabled handlers should not be used - result = PPP_REJECTED; - continue; - } + // skip handler if disabled or not allowed result = protocol_handler->Receive(packet, protocol); if(result == PPP_UNHANDLED) @@ -899,7 +1117,7 @@ PPPInterface::Receive(struct mbuf *packet, uint16 protocol) return result; } - // maybe the parent interface can handle it + // maybe the parent interface can handle the packet if(Parent()) return Parent()->Receive(packet, protocol); @@ -920,9 +1138,9 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol) return B_ERROR; // we must pass the basic tests like: - // do we have a device (as main interface)? + // do we have a device? // did we load all modules? - if(InitCheck() != B_OK) { + if(InitCheck() != B_OK || !Device()) { m_freem(packet); return B_ERROR; } @@ -934,21 +1152,23 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol) } // go up if DialOnDemand enabled and we are down - if(DoesDialOnDemand() && (Phase() == PPP_DOWN_PHASE - || Phase() == PPP_ESTABLISHMENT_PHASE)) - Up(); - // Up() waits until it is done + if(DoesDialOnDemand() + && (Phase() == PPP_DOWN_PHASE + || Phase() == PPP_ESTABLISHMENT_PHASE) + && !Up()) { + m_freem(packet); + return B_ERROR; + } - // check if protocol is allowed and everything is up - PPPProtocol *sending_protocol = ProtocolFor(protocol); - if(!fDevice->IsUp() - || (!IsUp() && protocol != PPP_LCP_PROTOCOL - && (!sending_protocol - || sending_protocol->Flags() & PPP_ALWAYS_ALLOWED == 0 - || !sending_protocol->IsEnabled() - ) - ) - ) { + // find the protocol handler for the current protocol number + int32 index = 0; + PPPProtocol *sending_protocol = ProtocolFor(protocol, &index); + while(sending_protocol && !sending_protocol->IsEnabled()) + sending_protocol = ProtocolFor(protocol, &(++index)); + + // make sure that protocol is allowed to send and everything is up + if(!Device()->IsUp() || !sending_protocol || !sending_protocol->IsEnabled() + || !is_handler_allowed(*sending_protocol, State(), Phase())){ m_freem(packet); return B_ERROR; } @@ -969,8 +1189,8 @@ PPPInterface::SendToDevice(struct mbuf *packet, uint16 protocol) // pass to device/children if(!IsMultilink() || Parent()) { // check if packet is too big for device - if((packet->m_flags & M_PKTHDR && (uint32) packet->m_pkthdr.len > LinkMTU()) - || packet->m_len > LinkMTU()) { + if((packet->m_flags & M_PKTHDR && (uint32) packet->m_pkthdr.len > MRU()) + || packet->m_len > MRU()) { m_freem(packet); return B_ERROR; } @@ -990,7 +1210,7 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet) if(!packet) return B_ERROR; - if(!InitCheck()) { + if(InitCheck() != B_OK) { m_freem(packet); return B_ERROR; } @@ -999,14 +1219,7 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet) uint16 *protocol = mtod(packet, uint16*); *protocol = ntohs(*protocol); - m_adj(packet, sizeof(uint16)); - - // Set our interface as the receiver. - // This might be NULL, so protocols that belong to the network stack (IP, etc.) - // will probably be confused (as there is no interface from which the packet came). - // Protocols that live only in the PPP interface should have no problems with this. - if(packet->m_flags & M_PKTHDR) - packet->m_pkthdr.rcvif = Ifnet(); + m_adj(packet, 2); return Receive(packet, *protocol); } @@ -1015,6 +1228,10 @@ PPPInterface::ReceiveFromDevice(struct mbuf *packet) void PPPInterface::Pulse() { + if(fDeleteCounter > 0) + return; + // we have no pulse when we are dead ;) + // check our idle time and disconnect if needed if(fDisconnectAfterIdleSince > 0 && fIdleSince != 0 && fIdleSince - system_time() >= fDisconnectAfterIdleSince) { @@ -1041,7 +1258,7 @@ PPPInterface::RegisterInterface() return true; // we are already registered - if(!InitCheck()) + if(InitCheck() != B_OK) return false; // we cannot register if something is wrong @@ -1085,9 +1302,9 @@ PPPInterface::UnregisterInterface() void -PPPInterface::CalculateMRU() +PPPInterface::CalculateInterfaceMTU() { - fMRU = fLinkMTU; + fInterfaceMTU = fMRU; // sum all headers fHeaderLength = sizeof(uint16); @@ -1096,15 +1313,15 @@ PPPInterface::CalculateMRU() for(; encapsulator; encapsulator = encapsulator->Next()) fHeaderLength += encapsulator->Overhead(); - fMRU -= fHeaderLength; + fInterfaceMTU -= fHeaderLength; if(Ifnet()) { - Ifnet()->if_mtu = fMRU; + Ifnet()->if_mtu = fInterfaceMTU; Ifnet()->if_hdrlen = fHeaderLength; } if(Parent()) - Parent()->CalculateMRU(); + Parent()->CalculateInterfaceMTU(); } @@ -1133,26 +1350,29 @@ PPPInterface::Redial() return; // start a new thread that calls our Up() method - redial_info *info = new redial_info; - info->interface = this; - info->thread = &fRedialThread; + redial_info info; + info.interface = this; + info.thread = &fRedialThread; - fRedialThread = spawn_thread(redial_func, "PPPInterface: redial_thread", - B_NORMAL_PRIORITY, info); + fRedialThread = spawn_thread(redial_thread, "PPPInterface: redial_thread", + B_NORMAL_PRIORITY, NULL); resume_thread(fRedialThread); + + send_data(fRedialThread, 0, &info, sizeof(redial_info)); } status_t -redial_func(void *data) +redial_thread(void *data) { - redial_info *info = (redial_info*) data; + redial_info info; + thread_id sender; - info->interface->Up(); - *info->thread = -1; + receive_data(&sender, &info, sizeof(redial_info)); - delete info; + info.interface->Up(); + *info.thread = -1; return B_OK; } @@ -1182,3 +1402,12 @@ in_queue_thread(void *data) return B_ERROR; } + + +status_t +interface_deleter_thread(void *data) +{ + delete (PPPInterface*) data; + + return B_OK; +} diff --git a/src/tests/kits/net/ppp/src/KPPPLCP.cpp b/src/tests/kits/net/ppp/src/KPPPLCP.cpp index 21f8ece531..0d642fb259 100644 --- a/src/tests/kits/net/ppp/src/KPPPLCP.cpp +++ b/src/tests/kits/net/ppp/src/KPPPLCP.cpp @@ -25,7 +25,7 @@ PPPLCP::PPPLCP(PPPInterface& interface) : PPPProtocol("LCP", PPP_ESTABLISHMENT_PHASE, PPP_LCP_PROTOCOL, - AF_UNSPEC, &interface, NULL, PPP_ALWAYS_ALLOWED), + AF_UNSPEC, interface, NULL, PPP_ALWAYS_ALLOWED), fStateMachine(interface.StateMachine()), fTarget(NULL) { SetUpRequested(false); @@ -87,8 +87,6 @@ PPPLCP::AdditionalOverhead() const if(Target()) overhead += Target()->Overhead(); - if(Interface()->Device()) - overhead += Interface()->Device()->Overhead(); return overhead; } @@ -113,10 +111,8 @@ PPPLCP::Send(struct mbuf *packet) { if(Target()) return Target()->Send(packet, PPP_LCP_PROTOCOL); - else if(Interface()) - return Interface()->Send(packet, PPP_LCP_PROTOCOL); else - return B_ERROR; + return Interface().Send(packet, PPP_LCP_PROTOCOL); } @@ -171,7 +167,7 @@ PPPLCP::Receive(struct mbuf *packet, uint16 protocol) break; default: - return B_ERROR; + StateMachine().RUCEvent(packet, PPP_LCP_PROTOCOL, PPP_CODE_REJECT); } return B_OK; diff --git a/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp index ccdf0845a0..f93111b181 100644 --- a/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp +++ b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp @@ -7,8 +7,10 @@ #include +#include -PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface *interface, + +PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface& interface, driver_parameter *settings) : fInterface(interface), fSettings(settings) { @@ -16,25 +18,53 @@ PPPOptionHandler::PPPOptionHandler(const char *name, PPPInterface *interface, strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT); fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0; } else - strcpy(fName, ""); + strcpy(fName, "???"); - if(interface) - interface->LCP().AddOptionHandler(this); + interface.LCP().AddOptionHandler(this); } PPPOptionHandler::~PPPOptionHandler() { - if(Interface()) - Interface()->LCP().RemoveOptionHandler(this); + Interface().LCP().RemoveOptionHandler(this); } status_t PPPOptionHandler::InitCheck() const { - if(!Interface() || !Settings()) + if(!Settings()) return B_ERROR; return B_OK; } + + +status_t +PPPOptionHandler::Control(uint32 op, void *data, size_t length) +{ + switch(op) { + case PPPC_GET_OPTION_HANDLER_INFO: { + if(length < sizeof(ppp_option_handler_info) || !data) + return B_ERROR; + + ppp_option_handler_info *info = (ppp_option_handler_info*) data; + memset(info, 0, sizeof(ppp_option_handler_info)); + strcpy(info->name, Name()); + info->settings = Settings(); + info->isEnabled = IsEnabled(); + } break; + + case PPPC_SET_ENABLED: + if(length < sizeof(uint32) || !data) + return B_ERROR; + + SetEnabled(*((uint32*)data)); + break; + + default: + return PPP_UNHANDLED; + } + + return B_OK; +} diff --git a/src/tests/kits/net/ppp/src/KPPPProtocol.cpp b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp index 2ec76d8246..7a039d00c1 100644 --- a/src/tests/kits/net/ppp/src/KPPPProtocol.cpp +++ b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp @@ -7,11 +7,13 @@ #include +#include + #include PPPProtocol::PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol, - int32 addressFamily, PPPInterface *interface, + int32 addressFamily, PPPInterface& interface, driver_parameter *settings, int32 flags = PPP_NO_FLAGS) : fPhase(phase), fProtocol(protocol), fAddressFamily(addressFamily), fInterface(interface), fSettings(settings), fFlags(flags), @@ -21,24 +23,22 @@ PPPProtocol::PPPProtocol(const char *name, PPP_PHASE phase, uint16 protocol, strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT); fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0; } else - strcpy(fName, ""); + strcpy(fName, "???"); - if(interface) - interface->AddProtocol(this); + interface.AddProtocol(this); } PPPProtocol::~PPPProtocol() { - if(Interface()) - Interface()->RemoveProtocol(this); + Interface().RemoveProtocol(this); } status_t PPPProtocol::InitCheck() const { - if(!Interface() || !Settings()) + if(!Settings()) return B_ERROR; return B_OK; @@ -50,13 +50,10 @@ PPPProtocol::SetEnabled(bool enabled = true) { fEnabled = enabled; - if(!Interface()) - return; - if(!enabled) { if(IsUp() || IsGoingUp()) Down(); - } else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface()->IsUp()) + } else if(!IsUp() && !IsGoingUp() && IsUpRequested() && Interface().IsUp()) Up(); } @@ -65,16 +62,32 @@ status_t PPPProtocol::Control(uint32 op, void *data, size_t length) { switch(op) { - // TODO: - // get: - // - name - // - protocol, address family - // - status (Is(Going)Up/Down/UpRequested/Enabled) - // set: - // - enabled + case PPPC_GET_HANDLER_INFO: { + if(length < sizeof(ppp_handler_info_t) || !data) + return B_ERROR; + + ppp_handler_info *info = (ppp_handler_info*) data; + memset(info, 0, sizeof(ppp_handler_info_t)); + strcpy(info->name, Name()); + info->settings = Settings(); + info->phase = Phase(); + info->addressFamily = AddressFamily(); + info->flags = Flags(); + info->protocol = Protocol(); + info->isEnabled = IsEnabled(); + info->isUpRequested = IsUpRequested(); + info->connectionStatus = fConnectionStatus; + } break; + + case PPPC_SET_ENABLED: + if(length < sizeof(uint32) || !data) + return B_ERROR; + + SetEnabled(*((uint32*)data)); + break; default: - return B_ERROR; + return PPP_UNHANDLED; } return B_OK; @@ -107,10 +120,7 @@ PPPProtocol::UpFailedEvent() { fConnectionStatus = PPP_DOWN_PHASE; - if(!Interface()) - return; - - Interface()->StateMachine().UpFailedEvent(this); + Interface().StateMachine().UpFailedEvent(this); } @@ -119,10 +129,7 @@ PPPProtocol::UpEvent() { fConnectionStatus = PPP_ESTABLISHED_PHASE; - if(!Interface()) - return; - - Interface()->StateMachine().UpEvent(this); + Interface().StateMachine().UpEvent(this); } @@ -131,8 +138,5 @@ PPPProtocol::DownEvent() { fConnectionStatus = PPP_DOWN_PHASE; - if(!Interface()) - return; - - Interface()->StateMachine().DownEvent(this); + Interface().StateMachine().DownEvent(this); } diff --git a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp index 434cfb4b8c..0bd44d1459 100644 --- a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp +++ b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp @@ -185,12 +185,12 @@ PPPStateMachine::UpEvent(PPPInterface *interface) if(Phase() == PPP_ESTABLISHMENT_PHASE) { // this is the first interface that went up - Interface()->SetLinkMTU(interface->LinkMTU()); + Interface()->SetMRU(interface->MRU()); locker.UnlockNow(); ThisLayerUp(); - } else if(Interface()->LinkMTU() > interface->LinkMTU()) - Interface()->SetLinkMTU(interface->LinkMTU()); - // linkMTU should always be the smallest value of all children + } else if(Interface()->MRU() > interface->MRU()) + Interface()->SetMRU(interface->MRU()); + // MRU should always be the smallest value of all children NewState(PPP_OPENED_STATE); } @@ -201,8 +201,8 @@ PPPStateMachine::DownEvent(PPPInterface *interface) { LockerHelper locker(fLock); - uint32 linkMTU = 0; - // the new linkMTU + uint32 MRU = 0; + // the new MRU Interface()->CalculateBaudRate(); @@ -214,17 +214,17 @@ PPPStateMachine::DownEvent(PPPInterface *interface) child = Interface()->ChildAt(index); if(child && child->IsUp()) { - // set linkMTU to the smallest value of all children - if(linkMTU == 0) - linkMTU = child->LinkMTU(); - else if(linkMTU > child->LinkMTU()) - linkMTU = child->LinkMTU(); + // set MRU to the smallest value of all children + if(MRU == 0) + MRU = child->MRU(); + else if(MRU > child->MRU()) + MRU = child->MRU(); ++count; } } - Interface()->SetLinkMTU(linkMTU); + Interface()->SetMRU(MRU); if(count == 0) { locker.UnlockNow(); @@ -1463,10 +1463,10 @@ PPPStateMachine::SendCodeReject(struct mbuf *packet, uint16 protocol, uint8 type int32 adjust = 0; // adjust packet size by this value if packet is too big if(packet->m_flags & M_PKTHDR) { - if((uint32) packet->m_pkthdr.len > Interface()->LinkMTU()) - adjust = Interface()->LinkMTU() - packet->m_pkthdr.len; - } else if(packet->m_len > Interface()->LinkMTU()) - adjust = Interface()->LinkMTU() - packet->m_len; + if((uint32) packet->m_pkthdr.len > Interface()->MRU()) + adjust = Interface()->MRU() - packet->m_pkthdr.len; + } else if(packet->m_len > Interface()->MRU()) + adjust = Interface()->MRU() - packet->m_len; if(adjust != 0) m_adj(packet, adjust);