xref: /haiku/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPMRUHandler.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
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