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 14static const uint8 kMRUType = 0x1; 15 16typedef struct mru_item { 17 uint8 type; 18 uint8 length; 19 uint16 MRU; 20} _PACKED mru_item; 21 22status_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 32status_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 47status_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 62status_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 72status_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 88status_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 101status_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 109status_t 110ParseRequestedItem(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 129void 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