xref: /haiku/src/add-ons/kernel/network/ppp/shared/libkernelppp/KPPPConfigurePacket.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 //----------------------------------------------------------------------
2 //  This software is part of the OpenBeOS distribution and is covered
3 //  by the OpenBeOS license.
4 //
5 //  Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
6 //---------------------------------------------------------------------
7 
8 #include <KPPPConfigurePacket.h>
9 #include <KPPPInterface.h>
10 
11 #include <core_funcs.h>
12 
13 
14 PPPConfigurePacket::PPPConfigurePacket(uint8 code)
15 	: fCode(code)
16 {
17 }
18 
19 
20 PPPConfigurePacket::PPPConfigurePacket(struct mbuf *packet)
21 {
22 	// decode packet
23 	ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
24 
25 	if(!SetCode(header->code))
26 		return;
27 
28 	if(header->length < 4)
29 		return;
30 			// there are no items (or one corrupted item)
31 
32 	int32 position = 0;
33 	ppp_configure_item *item;
34 
35 	while(position <= header->length - 4) {
36 		item = (ppp_configure_item*) (header->data + position);
37 		position += item->length;
38 
39 		AddItem(item);
40 	}
41 }
42 
43 
44 PPPConfigurePacket::~PPPConfigurePacket()
45 {
46 	for(int32 index = 0; index < CountItems(); index++)
47 		free(ItemAt(index));
48 }
49 
50 
51 bool
52 PPPConfigurePacket::SetCode(uint8 code)
53 {
54 	// only configure codes are allowed!
55 	if(code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT)
56 		return false;
57 
58 	fCode = code;
59 
60 	return true;
61 }
62 
63 
64 bool
65 PPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index = -1)
66 {
67 	if(item->length < 2)
68 		return false;
69 
70 	ppp_configure_item *add = (ppp_configure_item*) malloc(item->length);
71 	memcpy(add, item, item->length);
72 
73 	bool status;
74 	if(index < 0)
75 		status = fItems.AddItem(add);
76 	else
77 		status = fItems.AddItem(add, index);
78 	if(!status) {
79 		free(add);
80 		return false;
81 	}
82 
83 	return true;
84 }
85 
86 
87 bool
88 PPPConfigurePacket::RemoveItem(ppp_configure_item *item)
89 {
90 	if(!fItems.HasItem(item))
91 		return false;
92 
93 	fItems.RemoveItem(item);
94 	free(item);
95 
96 	return true;
97 }
98 
99 
100 ppp_configure_item*
101 PPPConfigurePacket::ItemAt(int32 index) const
102 {
103 	ppp_configure_item *item = fItems.ItemAt(index);
104 
105 	if(item == fItems.GetDefaultItem())
106 		return NULL;
107 
108 	return item;
109 }
110 
111 
112 ppp_configure_item*
113 PPPConfigurePacket::ItemWithType(uint8 type) const
114 {
115 	ppp_configure_item *item;
116 
117 	for(int32 index = 0; index < CountItems(); index++) {
118 		item = ItemAt(index);
119 		if(item && item->type == type)
120 			return item;
121 	}
122 
123 	return NULL;
124 }
125 
126 
127 struct mbuf*
128 PPPConfigurePacket::ToMbuf(uint32 reserve = 0)
129 {
130 	struct mbuf *packet = m_gethdr(MT_DATA);
131 	packet->m_data += reserve;
132 
133 	ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*);
134 
135 	header->code = Code();
136 
137 	uint8 length = 0;
138 	ppp_configure_item *item;
139 
140 	for(int32 index = 0; index < CountItems(); index++) {
141 		item = ItemAt(index);
142 
143 		// make sure we have enough space left
144 		if(0xFF - length < item->length) {
145 			m_freem(packet);
146 			return NULL;
147 		}
148 
149 		memcpy(header->data + length, item, item->length);
150 		length += item->length;
151 	}
152 
153 	header->length = length + 2;
154 	packet->m_len = header->length;
155 
156 	return packet;
157 }
158