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