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