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