xref: /haiku/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPLayer.cpp (revision 0562493379cd52eb7103531f895f10bb8e77c085)
1 /*
2  * Copyright 2003-2007, Waldemar Kornewald <wkornew@gmx.net>
3  * Distributed under the terms of the MIT License.
4  */
5 
6 /*!	\class KPPPLayer
7 	\brief An abstract layer that can encapsulate/send and receive packets.
8 
9 	All packet handlers should derive from this class. It does not define a protocol
10 	number like KPPPProtocol does. It only has a header overhead and an encapsulation
11 	level that is used to determine the order at which the packets get encapsulated
12 	by the layers. If this layer does not encapsulate PPP packets you should use
13 	PPP_PROTOCOL_LEVEL.
14 */
15 
16 #ifdef _KERNEL_MODE
17 	#include <kernel_cpp.h>
18 #endif
19 
20 #include <KPPPLayer.h>
21 
22 #include <cstdlib>
23 #include <cstring>
24 #include <core_funcs.h>
25 
26 
27 /*!	\brief Creates a new layer.
28 
29 	If an error occurs in the constructor you should set \c fInitStatus.
30 */
31 KPPPLayer::KPPPLayer(const char *name, ppp_level level, uint32 overhead)
32 	: fInitStatus(B_OK),
33 	fOverhead(overhead),
34 	fName(NULL),
35 	fLevel(level),
36 	fNext(NULL)
37 {
38 	SetName(name);
39 }
40 
41 
42 //!	Only frees the name.
43 KPPPLayer::~KPPPLayer()
44 {
45 	free(fName);
46 }
47 
48 
49 //!	Returns \c fInitStatus. May be overridden to return status-dependend errors.
50 status_t
51 KPPPLayer::InitCheck() const
52 {
53 	return fInitStatus;
54 }
55 
56 
57 //!	Sends a packet to the next layer in the chain.
58 status_t
59 KPPPLayer::SendToNext(struct mbuf *packet, uint16 protocolNumber) const
60 {
61 	if (!packet)
62 		return B_ERROR;
63 
64 	// Find the next possible handler for this packet.
65 	// Normal protocols (Level() >= PPP_PROTOCOL_LEVEL) do not encapsulate anything.
66 	if (Next()) {
67 		if (Next()->IsAllowedToSend() && Next()->Level() < PPP_PROTOCOL_LEVEL)
68 			return Next()->Send(packet, protocolNumber);
69 		else
70 			return Next()->SendToNext(packet, protocolNumber);
71 	} else {
72 		ERROR("KPPPLayer: SendToNext() failed because there is no next handler!\n");
73 		m_freem(packet);
74 		return B_ERROR;
75 	}
76 }
77 
78 
79 /*!	\brief You may override this for periodic tasks.
80 
81 	This method gets called every \c PPP_PULSE_RATE microseconds.
82 */
83 void
84 KPPPLayer::Pulse()
85 {
86 	// do nothing by default
87 }
88 
89 
90 //!	Allows changing the name of this layer.
91 void
92 KPPPLayer::SetName(const char *name)
93 {
94 	free(fName);
95 
96 	if (name)
97 		fName = strdup(name);
98 	else
99 		fName = NULL;
100 }
101