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