xref: /haiku/src/add-ons/kernel/network/ppp/shared/libkernelppp/_KPPPMRUHandler.cpp (revision 01b25646004ff628ecad0281a9795e5e90f71746)
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 
16 #define MRU_TYPE				0x1
17 
18 typedef struct mru_item {
19 	uint8 type;
20 	uint8 length;
21 	uint16 MRU _PACKED;
22 } mru_item;
23 
24 status_t ParseRequestedItem(mru_item *item, PPPInterface& interface);
25 
26 
27 _PPPMRUHandler::_PPPMRUHandler(PPPInterface& interface)
28 	: PPPOptionHandler("MRU Handler", MRU_TYPE, interface, NULL)
29 {
30 	Reset();
31 }
32 
33 
34 status_t
35 _PPPMRUHandler::AddToRequest(PPPConfigurePacket& 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 = MRU_TYPE;
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 _PPPMRUHandler::ParseNak(const PPPConfigurePacket& nak)
51 {
52 	mru_item *item = (mru_item*) nak.ItemWithType(MRU_TYPE);
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 _PPPMRUHandler::ParseReject(const PPPConfigurePacket& reject)
66 {
67 	if(reject.ItemWithType(MRU_TYPE))
68 		return B_ERROR;
69 
70 	return B_OK;
71 }
72 
73 
74 status_t
75 _PPPMRUHandler::ParseAck(const PPPConfigurePacket& ack)
76 {
77 	uint16 MRU = 1500;
78 	mru_item *item = (mru_item*) ack.ItemWithType(MRU_TYPE);
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 _PPPMRUHandler::ParseRequest(const PPPConfigurePacket& request,
92 	int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& 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 _PPPMRUHandler::SendingAck(const PPPConfigurePacket& ack)
105 {
106 	return ParseRequestedItem((mru_item*) ack.ItemWithType(MRU_TYPE), Interface());
107 }
108 
109 
110 // this function contains code shared by ParseRequest and SendingAck
111 status_t
112 ParseRequestedItem(mru_item *item, PPPInterface& 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 _PPPMRUHandler::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