xref: /haiku/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPMRUHandler.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 //----------------------------------------------------------------------
2 //  This software is part of the OpenBeOS distribution and is covered
3 //  by the OpenBeOS license.
4 //
5 //  Copyright (c) 2003 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 #define MRU_TYPE				0x1
16 
17 typedef struct mru_item {
18 	uint8 type;
19 	uint8 length;
20 	uint16 MRU;
21 };
22 
23 status_t ParseRequestedItem(mru_item *item, PPPInterface& interface);
24 
25 
26 _PPPMRUHandler::_PPPMRUHandler(PPPInterface& interface)
27 	: PPPOptionHandler("MRU Handler", MRU_TYPE, interface, NULL)
28 {
29 	Reset();
30 }
31 
32 
33 status_t
34 _PPPMRUHandler::AddToRequest(PPPConfigurePacket& request)
35 {
36 	if(!Interface().Device() || Interface().MRU() == 1500)
37 		return B_OK;
38 
39 	// add MRU request
40 	mru_item item;
41 	item.type = MRU_TYPE;
42 	item.length = 4;
43 	item.MRU = htons(fLocalMRU);
44 	return request.AddItem((ppp_configure_item*) &item) ? B_OK : B_ERROR;
45 }
46 
47 
48 status_t
49 _PPPMRUHandler::ParseNak(const PPPConfigurePacket& nak)
50 {
51 	mru_item *item = (mru_item*) nak.ItemWithType(MRU_TYPE);
52 	if(!item || item->length != 4)
53 		return B_OK;
54 
55 	uint16 MRU = ntohs(item->MRU);
56 	if(MRU < fLocalMRU)
57 		fLocalMRU = MRU;
58 
59 	return B_OK;
60 }
61 
62 
63 status_t
64 _PPPMRUHandler::ParseReject(const PPPConfigurePacket& reject)
65 {
66 	if(reject.ItemWithType(MRU_TYPE))
67 		return B_ERROR;
68 
69 	return B_OK;
70 }
71 
72 
73 status_t
74 _PPPMRUHandler::ParseAck(const PPPConfigurePacket& ack)
75 {
76 	uint16 MRU = 1500;
77 	mru_item *item = (mru_item*) ack.ItemWithType(MRU_TYPE);
78 
79 	if(item)
80 		MRU = ntohs(item->MRU);
81 
82 	if(MRU < Interface().MRU())
83 		fLocalMRU = MRU;
84 
85 	return B_OK;
86 }
87 
88 
89 status_t
90 _PPPMRUHandler::ParseRequest(const PPPConfigurePacket& request,
91 	int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject)
92 {
93 	if(index == reject.CountItems())
94 		return B_OK;
95 
96 	return ParseRequestedItem((mru_item*) request.ItemAt(index), Interface());
97 
98 	return B_OK;
99 }
100 
101 
102 status_t
103 _PPPMRUHandler::SendingAck(const PPPConfigurePacket& ack)
104 {
105 	return ParseRequestedItem((mru_item*) ack.ItemWithType(MRU_TYPE), Interface());
106 }
107 
108 
109 // this function contains code shared by ParseRequest and SendingAck
110 status_t
111 ParseRequestedItem(mru_item *item, PPPInterface& interface)
112 {
113 	uint16 MRU = 1500;
114 
115 	if(item) {
116 		if(item->length != 4)
117 			return B_ERROR;
118 				// the request had a corrupted item
119 
120 		MRU = ntohs(item->MRU);
121 	}
122 
123 	if(MRU < interface.MRU())
124 		interface.SetMRU(MRU);
125 
126 	return B_OK;
127 }
128 
129 
130 void
131 _PPPMRUHandler::Reset()
132 {
133 	if(Interface().Device()) {
134 		fLocalMRU = Interface().Device()->MTU() - 2;
135 		Interface().SetMRU(fLocalMRU);
136 	} else {
137 		Interface().SetMRU(1500);
138 		fLocalMRU = 1500;
139 	}
140 }
141