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 "_KPPPMRUHandler.h" 9 10 #include <KPPPConfigurePacket.h> 11 #include <KPPPDevice.h> 12 13 #include <netinet/in.h> 14 15 #define MRU_TYPE 0x1 16 17 typedef struct mru_item { 18 uint8 type; 19 uint8 length; 20 uint16 MRU; 21 }; 22 23 status_t ParseRequestedItem(mru_item *item, PPPInterface& interface); 24 25 26 _PPPMRUHandler::_PPPMRUHandler(PPPInterface& interface) 27 : PPPOptionHandler("MRU Handler", MRU_TYPE, interface, NULL) 28 { 29 Reset(); 30 } 31 32 33 status_t 34 _PPPMRUHandler::AddToRequest(PPPConfigurePacket& request) 35 { 36 if(!Interface().Device() || Interface().MRU() == 1500) 37 return B_OK; 38 39 // add MRU request 40 mru_item item; 41 item.type = MRU_TYPE; 42 item.length = 4; 43 item.MRU = htons(fLocalMRU); 44 return request.AddItem((ppp_configure_item*) &item) ? B_OK : B_ERROR; 45 } 46 47 48 status_t 49 _PPPMRUHandler::ParseNak(const PPPConfigurePacket& nak) 50 { 51 mru_item *item = (mru_item*) nak.ItemWithType(MRU_TYPE); 52 if(!item || item->length != 4) 53 return B_OK; 54 55 uint16 MRU = ntohs(item->MRU); 56 if(MRU < fLocalMRU) 57 fLocalMRU = MRU; 58 59 return B_OK; 60 } 61 62 63 status_t 64 _PPPMRUHandler::ParseReject(const PPPConfigurePacket& reject) 65 { 66 if(reject.ItemWithType(MRU_TYPE)) 67 return B_ERROR; 68 69 return B_OK; 70 } 71 72 73 status_t 74 _PPPMRUHandler::ParseAck(const PPPConfigurePacket& ack) 75 { 76 uint16 MRU = 1500; 77 mru_item *item = (mru_item*) ack.ItemWithType(MRU_TYPE); 78 79 if(item) 80 MRU = ntohs(item->MRU); 81 82 if(MRU < Interface().MRU()) 83 fLocalMRU = MRU; 84 85 return B_OK; 86 } 87 88 89 status_t 90 _PPPMRUHandler::ParseRequest(const PPPConfigurePacket& request, 91 int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject) 92 { 93 if(index == reject.CountItems()) 94 return B_OK; 95 96 return ParseRequestedItem((mru_item*) request.ItemAt(index), Interface()); 97 98 return B_OK; 99 } 100 101 102 status_t 103 _PPPMRUHandler::SendingAck(const PPPConfigurePacket& ack) 104 { 105 return ParseRequestedItem((mru_item*) ack.ItemWithType(MRU_TYPE), Interface()); 106 } 107 108 109 // this function contains code shared by ParseRequest and SendingAck 110 status_t 111 ParseRequestedItem(mru_item *item, PPPInterface& interface) 112 { 113 uint16 MRU = 1500; 114 115 if(item) { 116 if(item->length != 4) 117 return B_ERROR; 118 // the request had a corrupted item 119 120 MRU = ntohs(item->MRU); 121 } 122 123 if(MRU < interface.MRU()) 124 interface.SetMRU(MRU); 125 126 return B_OK; 127 } 128 129 130 void 131 _PPPMRUHandler::Reset() 132 { 133 if(Interface().Device()) { 134 fLocalMRU = Interface().Device()->MTU() - 2; 135 Interface().SetMRU(fLocalMRU); 136 } else { 137 Interface().SetMRU(1500); 138 fLocalMRU = 1500; 139 } 140 } 141