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 #include "_KPPPMRUHandler.h" 9 10 #include <KPPPConfigurePacket.h> 11 #include <KPPPDevice.h> 12 13 #include <netinet/in.h> 14 15 16 static const uint8 kMRUType = 0x1; 17 18 typedef struct mru_item { 19 uint8 type; 20 uint8 length; 21 uint16 MRU; 22 } _PACKED mru_item; 23 24 status_t ParseRequestedItem(mru_item *item, KPPPInterface& interface); 25 26 27 _KPPPMRUHandler::_KPPPMRUHandler(KPPPInterface& interface) 28 : KPPPOptionHandler("MRU Handler", kMRUType, interface, NULL) 29 { 30 Reset(); 31 } 32 33 34 status_t 35 _KPPPMRUHandler::AddToRequest(KPPPConfigurePacket& 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 = kMRUType; 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 _KPPPMRUHandler::ParseNak(const KPPPConfigurePacket& nak) 51 { 52 mru_item *item = (mru_item*) nak.ItemWithType(kMRUType); 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 _KPPPMRUHandler::ParseReject(const KPPPConfigurePacket& reject) 66 { 67 if(reject.ItemWithType(kMRUType)) 68 return B_ERROR; 69 70 return B_OK; 71 } 72 73 74 status_t 75 _KPPPMRUHandler::ParseAck(const KPPPConfigurePacket& ack) 76 { 77 uint16 MRU = 1500; 78 mru_item *item = (mru_item*) ack.ItemWithType(kMRUType); 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 _KPPPMRUHandler::ParseRequest(const KPPPConfigurePacket& request, 92 int32 index, KPPPConfigurePacket& nak, KPPPConfigurePacket& 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 _KPPPMRUHandler::SendingAck(const KPPPConfigurePacket& ack) 105 { 106 return ParseRequestedItem((mru_item*) ack.ItemWithType(kMRUType), Interface()); 107 } 108 109 110 // this function contains code shared by ParseRequest and SendingAck 111 status_t 112 ParseRequestedItem(mru_item *item, KPPPInterface& 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 _KPPPMRUHandler::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