2 * Copyright 2003-2004, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
7 #include <NetBufferUtilities.h>
8 #include <net_buffer.h>
10 #include "DiscoveryPacket.h"
12 DiscoveryPacket::DiscoveryPacket(uint8 code
, uint16 sessionID
)
14 fSessionID(sessionID
),
20 DiscoveryPacket::DiscoveryPacket(net_buffer
*packet
, uint32 start
)
23 NetBufferHeaderReader
<pppoe_header
> bufferheader(packet
);
24 if (bufferheader
.Status() != B_OK
) {
25 dprintf("NetBufferHeaderReader create fail\n");
26 fInitStatus
= B_ERROR
;
29 pppoe_header
&header
= bufferheader
.Data();
33 uint16 length
= ntohs(header
.length
);
35 if(length
> packet
->size
- PPPoE_HEADER_SIZE
) {
36 dprintf("packet size less than pppoe payload\n");
37 dprintf("pppoe payload: %d\n", length
);
38 dprintf("PPPoE_HEADER_SIZE: %d\n", PPPoE_HEADER_SIZE
);
39 dprintf("packet->size: %" B_PRIu32
"\n", packet
->size
);
40 fInitStatus
= B_ERROR
;
42 // there are no tags (or one corrupted tag)
48 while(position
<= length
- 4) {
49 tag
= (pppoe_tag
*) (header
.data
+ position
);
50 position
+= ntohs(tag
->length
) + 4;
52 AddTag(ntohs(tag
->type
), tag
->data
, ntohs(tag
->length
));
59 DiscoveryPacket::~DiscoveryPacket()
61 for(int32 index
= 0; index
< CountTags(); index
++)
67 DiscoveryPacket::AddTag(uint16 type
, const void *data
, uint16 length
, int32 index
)
69 pppoe_tag
*add
= (pppoe_tag
*) malloc(length
+ 4);
72 memcpy(add
->data
, data
, length
);
76 status
= fTags
.AddItem(add
);
78 status
= fTags
.AddItem(add
, index
);
89 DiscoveryPacket::RemoveTag(pppoe_tag
*tag
)
91 if(!fTags
.HasItem(tag
))
94 fTags
.RemoveItem(tag
);
102 DiscoveryPacket::TagAt(int32 index
) const
104 pppoe_tag
*tag
= fTags
.ItemAt(index
);
106 if(tag
== fTags
.GetDefaultItem())
114 DiscoveryPacket::TagWithType(uint16 type
) const
118 for(int32 index
= 0; index
< CountTags(); index
++) {
120 if(tag
&& tag
->type
== type
)
129 DiscoveryPacket::ToNetBuffer(uint32 MTU
)
131 net_buffer
*packet
= gBufferModule
->create(256);
132 if (packet
== NULL
) {
133 dprintf("create buffer failure\n");
137 pppoe_header
*header
;
138 status_t status
= gBufferModule
->append_size(packet
, 1492, (void **)&header
);
139 if (status
!= B_OK
) {
140 dprintf("append size failure\n");
144 header
->version
= PPPoE_VERSION
;
145 header
->type
= PPPoE_TYPE
;
146 header
->code
= Code();
147 header
->sessionID
= SessionID();
152 for(int32 index
= 0; index
< CountTags(); index
++) {
155 // make sure we have enough space left
156 if(MTU
- length
< tag
->length
) {
157 gBufferModule
->free(packet
);
161 *((uint16
*)(header
->data
+ length
)) = htons(tag
->type
);
163 *((uint16
*)(header
->data
+ length
)) = htons(tag
->length
);
165 memcpy(header
->data
+ length
, tag
->data
, tag
->length
);
166 length
+= tag
->length
;
169 header
->length
= htons(length
);
170 status
= gBufferModule
->trim(packet
, length
+ PPPoE_HEADER_SIZE
);
171 if (status
!= B_OK
) {
172 dprintf("trim buffer failure\n");