xref: /haiku/src/add-ons/kernel/network/ppp/shared/libppp/PPPManager.cpp (revision 5c9e6a3953923a7c60c3d9c69c4f935492f26997)
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 "PPPManager.h"
9 #include "PPPInterface.h"
10 
11 #include <net_stack_driver.h>
12 #include <settings_tools.h>
13 #include <unistd.h>
14 
15 
16 PPPManager::PPPManager()
17 {
18 	fFD = open("/dev/net/stack", O_RDWR);
19 }
20 
21 
22 PPPManager::~PPPManager()
23 {
24 	if(fFD >= 0)
25 		close(fFD);
26 }
27 
28 
29 status_t
30 PPPManager::InitCheck() const
31 {
32 	if(fFD < 0)
33 		return B_ERROR;
34 	else
35 		return B_OK;
36 }
37 
38 
39 status_t
40 PPPManager::Control(uint32 op, void *data, size_t length) const
41 {
42 	if(InitCheck() != B_OK)
43 		return B_ERROR;
44 
45 	control_net_module_args args;
46 	args.name = PPP_INTERFACE_MODULE_NAME;
47 	args.op = op;
48 	args.data = data;
49 	args.length = length;
50 
51 	return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
52 }
53 
54 interface_id
55 PPPManager::CreateInterface(const driver_settings *settings) const
56 {
57 	ppp_interface_settings_info info;
58 	info.settings = settings;
59 
60 	if(Control(PPPC_CREATE_INTERFACE, &info, sizeof(info)) != B_OK)
61 		return PPP_UNDEFINED_INTERFACE_ID;
62 	else
63 		return info.interface;
64 }
65 
66 
67 bool
68 PPPManager::DeleteInterface(interface_id ID) const
69 {
70 	if(Control(PPPC_DELETE_INTERFACE, &ID, sizeof(ID)) != B_OK)
71 		return false;
72 	else
73 		return true;
74 }
75 
76 
77 interface_id*
78 PPPManager::Interfaces(int32 *count,
79 	ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const
80 {
81 	int32 requestCount;
82 	interface_id *interfaces;
83 
84 	// loop until we get all interfaces
85 	while(true) {
86 		requestCount = *count = CountInterfaces(filter);
87 		if(*count == -1)
88 			return NULL;
89 
90 		requestCount += 10;
91 			// request some more interfaces in case some are added in the mean time
92 		interfaces = new interface_id[requestCount];
93 		*count = GetInterfaces(interfaces, requestCount, filter);
94 		if(*count == -1) {
95 			delete interfaces;
96 			return NULL;
97 		}
98 
99 		if(*count < requestCount)
100 			break;
101 
102 		delete interfaces;
103 	}
104 
105 	return interfaces;
106 }
107 
108 
109 int32
110 PPPManager::GetInterfaces(interface_id *interfaces, int32 count,
111 	ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const
112 {
113 	ppp_get_interfaces_info info;
114 	info.interfaces = interfaces;
115 	info.count = count;
116 	info.filter = filter;
117 
118 	if(Control(PPPC_GET_INTERFACES, &info, sizeof(info)) != B_OK)
119 		return -1;
120 	else
121 		return info.resultCount;
122 }
123 
124 
125 interface_id
126 PPPManager::InterfaceWithSettings(const driver_settings *settings) const
127 {
128 	int32 count;
129 	interface_id *interfaces = Interfaces(&count, PPP_ALL_INTERFACES);
130 
131 	if(!interfaces)
132 		return PPP_UNDEFINED_INTERFACE_ID;
133 
134 	interface_id id = PPP_UNDEFINED_INTERFACE_ID;
135 	PPPInterface interface;
136 	ppp_interface_info_t info;
137 
138 	for(int32 index = 0; index < count; index++) {
139 		interface.SetTo(interfaces[index]);
140 		if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
141 				&& equal_driver_settings(settings, info.info.settings)) {
142 			id = interface.ID();
143 			break;
144 		}
145 	}
146 
147 	delete interfaces;
148 
149 	return id;
150 }
151 
152 
153 interface_id
154 PPPManager::InterfaceWithUnit(int32 if_unit)
155 {
156 	int32 count;
157 	interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
158 
159 	if(!interfaces)
160 		return PPP_UNDEFINED_INTERFACE_ID;
161 
162 	interface_id id = PPP_UNDEFINED_INTERFACE_ID;
163 	PPPInterface interface;
164 	ppp_interface_info_t info;
165 
166 	for(int32 index = 0; index < count; index++) {
167 		interface.SetTo(interfaces[index]);
168 		if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
169 				&& info.info.if_unit == if_unit) {
170 			id = interface.ID();
171 			break;
172 		}
173 	}
174 
175 	delete interfaces;
176 
177 	return id;
178 }
179 
180 
181 int32
182 PPPManager::CountInterfaces(ppp_interface_filter filter =
183 	PPP_REGISTERED_INTERFACES) const
184 {
185 	return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
186 }
187 
188 
189 bool
190 PPPManager::EnableReports(ppp_report_type type, thread_id thread,
191 	int32 flags = PPP_NO_FLAGS) const
192 {
193 	ppp_report_request request;
194 	request.type = type;
195 	request.thread = thread;
196 	request.flags = flags;
197 
198 	return Control(PPPC_ENABLE_REPORTS, &request, sizeof(request)) == B_OK;
199 }
200 
201 
202 bool
203 PPPManager::DisableReports(ppp_report_type type, thread_id thread) const
204 {
205 	ppp_report_request request;
206 	request.type = type;
207 	request.thread = thread;
208 
209 	return Control(PPPC_DISABLE_REPORTS, &request, sizeof(request)) == B_OK;
210 }
211