xref: /haiku/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp (revision 84b580c425e26370792255dbb5e1879250434372)
1 /*
2  * Copyright 2003-2004, Waldemar Kornewald <Waldemar.Kornewald@web.de>
3  * Distributed under the terms of the MIT License.
4  */
5 
6 /*!	\class KPPPConfigurePacket
7 	\brief Helper class for LCP configure packets.
8 
9 	This class allows iterating over configure items and adding/removing items.
10 */
11 
12 #include <KPPPConfigurePacket.h>
13 #include <KPPPInterface.h>
14 
15 #include <core_funcs.h>
16 
17 
18 /*!	\brief Constructor.
19 
20 	\param code The code value (e.g.: PPP_CONFIGURE_REQUEST) of this packet.
21 */
22 KPPPConfigurePacket::KPPPConfigurePacket(uint8 code)
23 	: fCode(code),
24 	fID(0)
25 {
26 }
27 
28 
29 //!	Decodes a packet and adds its items to this object.
30 KPPPConfigurePacket::KPPPConfigurePacket(struct mbuf *packet)
31 {
32 	// decode packet
33 	ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
34 
35 	SetID(header->id);
36 	if(!SetCode(header->code))
37 		return;
38 
39 	uint16 length = ntohs(header->length);
40 
41 	if(length < 6 || length > packet->m_len)
42 		return;
43 			// there are no items (or one corrupted item)
44 
45 	int32 position = 0;
46 	ppp_configure_item *item;
47 
48 	while(position < length - 4) {
49 		item = (ppp_configure_item*) (header->data + position);
50 		if(item->length < 2)
51 			return;
52 				// found a corrupted item
53 
54 		position += item->length;
55 		AddItem(item);
56 	}
57 }
58 
59 
60 //!	Frees all items.
61 KPPPConfigurePacket::~KPPPConfigurePacket()
62 {
63 	for(int32 index = 0; index < CountItems(); index++)
64 		free(ItemAt(index));
65 }
66 
67 
68 //!	Sets the packet's code value (e.g.: PPP_CONFIGURE_REQUEST).
69 bool
70 KPPPConfigurePacket::SetCode(uint8 code)
71 {
72 	// only configure codes are allowed!
73 	if(code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT)
74 		return false;
75 
76 	fCode = code;
77 
78 	return true;
79 }
80 
81 
82 /*!	\brief Adds a new configure item to this packet.
83 
84 	Make sure all values are correct because the item will be copied. If the item's
85 	length field is incorrect you will get bad results.
86 
87 	\param item The item.
88 	\param index Item's index. Adds after the last item if not specified or negative.
89 
90 	\return \c true if successful, \c false otherwise.
91 
92 	\sa ppp_configure_item
93 */
94 bool
95 KPPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index = -1)
96 {
97 	if(!item || item->length < 2)
98 		return false;
99 
100 	ppp_configure_item *add = (ppp_configure_item*) malloc(item->length);
101 	memcpy(add, item, item->length);
102 
103 	bool status;
104 	if(index < 0)
105 		status = fItems.AddItem(add);
106 	else
107 		status = fItems.AddItem(add, index);
108 	if(!status) {
109 		free(add);
110 		return false;
111 	}
112 
113 	return true;
114 }
115 
116 
117 //!	Removes an item. The item \e must belong to this packet.
118 bool
119 KPPPConfigurePacket::RemoveItem(ppp_configure_item *item)
120 {
121 	if(!fItems.HasItem(item))
122 		return false;
123 
124 	fItems.RemoveItem(item);
125 	free(item);
126 
127 	return true;
128 }
129 
130 
131 //!	Returns the item at \a index or \c NULL.
132 ppp_configure_item*
133 KPPPConfigurePacket::ItemAt(int32 index) const
134 {
135 	ppp_configure_item *item = fItems.ItemAt(index);
136 
137 	if(item == fItems.GetDefaultItem())
138 		return NULL;
139 
140 	return item;
141 }
142 
143 
144 //!	Returns the item of a special \a type or \c NULL.
145 ppp_configure_item*
146 KPPPConfigurePacket::ItemWithType(uint8 type) const
147 {
148 	ppp_configure_item *item;
149 
150 	for(int32 index = 0; index < CountItems(); index++) {
151 		item = ItemAt(index);
152 		if(item && item->type == type)
153 			return item;
154 	}
155 
156 	return NULL;
157 }
158 
159 
160 /*!	\brief Converts this packet into an mbuf structure.
161 
162 	ATTENTION: You are responsible for freeing this packet by calling \c m_freem()!
163 
164 	\param MRU The interface's maximum receive unit (MRU).
165 	\param reserve Number of bytes to reserve at the beginning of the packet.
166 
167 	\return The mbuf structure or \c NULL on error (e.g.: too big for given MRU).
168 */
169 struct mbuf*
170 KPPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve = 0)
171 {
172 	struct mbuf *packet = m_gethdr(MT_DATA);
173 	packet->m_data += reserve;
174 
175 	ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
176 
177 	header->code = Code();
178 	header->id = ID();
179 
180 	uint16 length = 0;
181 	ppp_configure_item *item;
182 
183 	for(int32 index = 0; index < CountItems(); index++) {
184 		item = ItemAt(index);
185 
186 		// make sure we have enough space left
187 		if(MRU - length < item->length) {
188 			m_freem(packet);
189 			return NULL;
190 		}
191 
192 		memcpy(header->data + length, item, item->length);
193 		length += item->length;
194 	}
195 
196 	length += 4;
197 	header->length = htons(length);
198 	packet->m_pkthdr.len = packet->m_len = length;
199 
200 	return packet;
201 }
202