184b580c4SWaldemar Kornewald/*
2fc1cf1a3SAxel Dörfler * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
384b580c4SWaldemar Kornewald * Distributed under the terms of the MIT License.
484b580c4SWaldemar Kornewald */
56cfb4dcaSWaldemar Kornewald
613013331SWaldemar Kornewald/*!	\class KPPPLayer
713013331SWaldemar Kornewald	\brief An abstract layer that can encapsulate/send and receive packets.
8e3724c38Smshlyn
913013331SWaldemar Kornewald	All packet handlers should derive from this class. It does not define a protocol
1013013331SWaldemar Kornewald	number like KPPPProtocol does. It only has a header overhead and an encapsulation
1113013331SWaldemar Kornewald	level that is used to determine the order at which the packets get encapsulated
1213013331SWaldemar Kornewald	by the layers. If this layer does not encapsulate PPP packets you should use
1313013331SWaldemar Kornewald	PPP_PROTOCOL_LEVEL.
1413013331SWaldemar Kornewald*/
1513013331SWaldemar Kornewald
166cfb4dcaSWaldemar Kornewald#ifdef _KERNEL_MODE
176cfb4dcaSWaldemar Kornewald	#include <kernel_cpp.h>
186cfb4dcaSWaldemar Kornewald#endif
1992a8026eSWaldemar Kornewald
2092a8026eSWaldemar Kornewald#include <KPPPLayer.h>
2192a8026eSWaldemar Kornewald
22e3724c38Smshlyn#include <net_buffer.h>
23e3724c38Smshlyn
2492a8026eSWaldemar Kornewald#include <cstdlib>
2592a8026eSWaldemar Kornewald#include <cstring>
2692a8026eSWaldemar Kornewald
27e3724c38Smshlynextern net_buffer_module_info *gBufferModule;
2886c13ddaSWaldemar Kornewald
2913013331SWaldemar Kornewald/*!	\brief Creates a new layer.
30e3724c38Smshlyn
313f3689bbSWaldemar Kornewald	If an error occurs in the constructor you should set \c fInitStatus.
3213013331SWaldemar Kornewald*/
33f9ad2df8SWaldemar KornewaldKPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead)
3492a8026eSWaldemar Kornewald	: fInitStatus(B_OK),
354e0ad752SWaldemar Kornewald	fOverhead(overhead),
365a483e4dSWaldemar Kornewald	fName(NULL),
37abf44d1aSWaldemar Kornewald	fLevel(level),
3892a8026eSWaldemar Kornewald	fNext(NULL)
3992a8026eSWaldemar Kornewald{
40f9ad2df8SWaldemar Kornewald	SetName(name);
4192a8026eSWaldemar Kornewald}
4292a8026eSWaldemar Kornewald
4392a8026eSWaldemar Kornewald
4413013331SWaldemar Kornewald//!	Only frees the name.
45f9ad2df8SWaldemar KornewaldKPPPLayer::~KPPPLayer()
4692a8026eSWaldemar Kornewald{
4792a8026eSWaldemar Kornewald	free(fName);
4892a8026eSWaldemar Kornewald}
4992a8026eSWaldemar Kornewald
5092a8026eSWaldemar Kornewald
5113013331SWaldemar Kornewald//!	Returns \c fInitStatus. May be overridden to return status-dependend errors.
5292a8026eSWaldemar Kornewaldstatus_t
53f9ad2df8SWaldemar KornewaldKPPPLayer::InitCheck() const
5492a8026eSWaldemar Kornewald{
5592a8026eSWaldemar Kornewald	return fInitStatus;
5692a8026eSWaldemar Kornewald}
5792a8026eSWaldemar Kornewald
5892a8026eSWaldemar Kornewald
5913013331SWaldemar Kornewald//!	Sends a packet to the next layer in the chain.
6092a8026eSWaldemar Kornewaldstatus_t
61e3724c38SmshlynKPPPLayer::SendToNext(net_buffer *packet, uint16 protocolNumber) const
6292a8026eSWaldemar Kornewald{
63fc1cf1a3SAxel Dörfler	if (!packet)
648dad9b1eSWaldemar Kornewald		return B_ERROR;
65e3724c38Smshlyn
6692a8026eSWaldemar Kornewald	// Find the next possible handler for this packet.
6792a8026eSWaldemar Kornewald	// Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything.
68fc1cf1a3SAxel Dörfler	if (Next()) {
69fc1cf1a3SAxel Dörfler		if (Next()->IsAllowedToSend() && Next()->Level() < PPP_PROTOCOL_LEVEL)
7092a8026eSWaldemar Kornewald			return Next()->Send(packet, protocolNumber);
7192a8026eSWaldemar Kornewald		else
7292a8026eSWaldemar Kornewald			return Next()->SendToNext(packet, protocolNumber);
7392a8026eSWaldemar Kornewald	} else {
7484b580c4SWaldemar Kornewald		ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n");
75e3724c38Smshlyn		gBufferModule->free(packet);
7692a8026eSWaldemar Kornewald		return B_ERROR;
7792a8026eSWaldemar Kornewald	}
7892a8026eSWaldemar Kornewald}
7992a8026eSWaldemar Kornewald
8092a8026eSWaldemar Kornewald
8113013331SWaldemar Kornewald/*!	\brief You may override this for periodic tasks.
82e3724c38Smshlyn
8313013331SWaldemar Kornewald	This method gets called every \c PPP_PULSE_RATE microseconds.
8413013331SWaldemar Kornewald*/
8592a8026eSWaldemar Kornewaldvoid
86f9ad2df8SWaldemar KornewaldKPPPLayer::Pulse()
8792a8026eSWaldemar Kornewald{
8892a8026eSWaldemar Kornewald	// do nothing by default
8992a8026eSWaldemar Kornewald}
90f9ad2df8SWaldemar Kornewald
91f9ad2df8SWaldemar Kornewald
9213013331SWaldemar Kornewald//!	Allows changing the name of this layer.
93f9ad2df8SWaldemar Kornewaldvoid
94f9ad2df8SWaldemar KornewaldKPPPLayer::SetName(const char *name)
95f9ad2df8SWaldemar Kornewald{
96f9ad2df8SWaldemar Kornewald	free(fName);
97e3724c38Smshlyn
98fc1cf1a3SAxel Dörfler	if (name)
99f9ad2df8SWaldemar Kornewald		fName = strdup(name);
100f9ad2df8SWaldemar Kornewald	else
101abf44d1aSWaldemar Kornewald		fName = NULL;
102f9ad2df8SWaldemar Kornewald}
103