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 fID(0) 17 { 18 } 19 20 21 PPPConfigurePacket::PPPConfigurePacket(struct mbuf *packet) 22 { 23 // decode packet 24 ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*); 25 26 SetID(header->id); 27 if(!SetCode(header->code)) 28 return; 29 30 uint16 length = ntohs(header->length); 31 32 if(length < 6 || length > packet->m_len) 33 return; 34 // there are no items (or one corrupted item) 35 36 int32 position = 0; 37 ppp_configure_item *item; 38 39 while(position < length - 4) { 40 item = (ppp_configure_item*) (header->data + position); 41 if(item->length < 2) 42 return; 43 // found a corrupted item 44 45 position += item->length; 46 AddItem(item); 47 } 48 } 49 50 51 PPPConfigurePacket::~PPPConfigurePacket() 52 { 53 for(int32 index = 0; index < CountItems(); index++) 54 free(ItemAt(index)); 55 } 56 57 58 bool 59 PPPConfigurePacket::SetCode(uint8 code) 60 { 61 // only configure codes are allowed! 62 if(code < PPP_CONFIGURE_REQUEST || code > PPP_CONFIGURE_REJECT) 63 return false; 64 65 fCode = code; 66 67 return true; 68 } 69 70 71 bool 72 PPPConfigurePacket::AddItem(const ppp_configure_item *item, int32 index = -1) 73 { 74 if(!item || item->length < 2) 75 return false; 76 77 ppp_configure_item *add = (ppp_configure_item*) malloc(item->length); 78 memcpy(add, item, item->length); 79 80 bool status; 81 if(index < 0) 82 status = fItems.AddItem(add); 83 else 84 status = fItems.AddItem(add, index); 85 if(!status) { 86 free(add); 87 return false; 88 } 89 90 return true; 91 } 92 93 94 bool 95 PPPConfigurePacket::RemoveItem(ppp_configure_item *item) 96 { 97 if(!fItems.HasItem(item)) 98 return false; 99 100 fItems.RemoveItem(item); 101 free(item); 102 103 return true; 104 } 105 106 107 ppp_configure_item* 108 PPPConfigurePacket::ItemAt(int32 index) const 109 { 110 ppp_configure_item *item = fItems.ItemAt(index); 111 112 if(item == fItems.GetDefaultItem()) 113 return NULL; 114 115 return item; 116 } 117 118 119 ppp_configure_item* 120 PPPConfigurePacket::ItemWithType(uint8 type) const 121 { 122 ppp_configure_item *item; 123 124 for(int32 index = 0; index < CountItems(); index++) { 125 item = ItemAt(index); 126 if(item && item->type == type) 127 return item; 128 } 129 130 return NULL; 131 } 132 133 134 struct mbuf* 135 PPPConfigurePacket::ToMbuf(uint32 MRU, uint32 reserve = 0) 136 { 137 struct mbuf *packet = m_gethdr(MT_DATA); 138 packet->m_data += reserve; 139 140 ppp_lcp_packet *header = mtod(packet, ppp_lcp_packet*); 141 142 header->code = Code(); 143 header->id = ID(); 144 145 uint16 length = 0; 146 ppp_configure_item *item; 147 148 for(int32 index = 0; index < CountItems(); index++) { 149 item = ItemAt(index); 150 151 // make sure we have enough space left 152 if(MRU - length < item->length) { 153 m_freem(packet); 154 return NULL; 155 } 156 157 memcpy(header->data + length, item, item->length); 158 length += item->length; 159 } 160 161 length += 4; 162 header->length = htons(length); 163 packet->m_pkthdr.len = packet->m_len = length; 164 165 return packet; 166 } 167