2 * Copyright 2003-2004, Waldemar Kornewald <wkornew@gmx.net>
3 * Distributed under the terms of the MIT License.
6 #include "DiscoveryPacket.h"
8 #include <core_funcs.h>
11 DiscoveryPacket::DiscoveryPacket(uint8 code
, uint16 sessionID
)
13 fSessionID(sessionID
),
19 DiscoveryPacket::DiscoveryPacket(struct mbuf
*packet
, uint32 start
)
22 uint8
*data
= mtod(packet
, uint8
*);
24 pppoe_header
*header
= (pppoe_header
*) data
;
26 SetCode(header
->code
);
28 uint16 length
= ntohs(header
->length
);
30 if(length
> packet
->m_len
- PPPoE_HEADER_SIZE
- start
) {
31 fInitStatus
= B_ERROR
;
33 // there are no tags (or one corrupted tag)
39 while(position
<= length
- 4) {
40 tag
= (pppoe_tag
*) (header
->data
+ position
);
41 position
+= ntohs(tag
->length
) + 4;
43 AddTag(ntohs(tag
->type
), tag
->data
, ntohs(tag
->length
));
50 DiscoveryPacket::~DiscoveryPacket()
52 for(int32 index
= 0; index
< CountTags(); index
++)
58 DiscoveryPacket::AddTag(uint16 type
, const void *data
, uint16 length
, int32 index
)
60 pppoe_tag
*add
= (pppoe_tag
*) malloc(length
+ 4);
63 memcpy(add
->data
, data
, length
);
67 status
= fTags
.AddItem(add
);
69 status
= fTags
.AddItem(add
, index
);
80 DiscoveryPacket::RemoveTag(pppoe_tag
*tag
)
82 if(!fTags
.HasItem(tag
))
85 fTags
.RemoveItem(tag
);
93 DiscoveryPacket::TagAt(int32 index
) const
95 pppoe_tag
*tag
= fTags
.ItemAt(index
);
97 if(tag
== fTags
.GetDefaultItem())
105 DiscoveryPacket::TagWithType(uint16 type
) const
109 for(int32 index
= 0; index
< CountTags(); index
++) {
111 if(tag
&& tag
->type
== type
)
120 DiscoveryPacket::ToMbuf(uint32 MTU
, uint32 reserve
)
122 struct mbuf
*packet
= m_gethdr(MT_DATA
);
123 packet
->m_data
+= reserve
;
125 pppoe_header
*header
= mtod(packet
, pppoe_header
*);
127 header
->version
= PPPoE_VERSION
;
128 header
->type
= PPPoE_TYPE
;
129 header
->code
= Code();
130 header
->sessionID
= SessionID();
135 for(int32 index
= 0; index
< CountTags(); index
++) {
138 // make sure we have enough space left
139 if(MTU
- length
< tag
->length
) {
144 *((uint16
*)(header
->data
+ length
)) = htons(tag
->type
);
146 *((uint16
*)(header
->data
+ length
)) = htons(tag
->length
);
148 memcpy(header
->data
+ length
, tag
->data
, tag
->length
);
149 length
+= tag
->length
;
152 header
->length
= htons(length
);
153 packet
->m_pkthdr
.len
= packet
->m_len
= length
+ PPPoE_HEADER_SIZE
;