xref: /haiku/src/add-ons/kernel/network/ppp/shared/libppp/PPPManager.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 "PPPManager.h"
9 #include "PPPInterface.h"
10 
11 #include <cstring>
12 #include <cstdlib>
13 #include <cctype>
14 #include <settings_tools.h>
15 #include <unistd.h>
16 #include "_libppputils.h"
17 
18 
19 PPPManager::PPPManager()
20 {
21 	fFD = open(get_stack_driver_path(), O_RDWR);
22 }
23 
24 
25 PPPManager::~PPPManager()
26 {
27 	if(fFD >= 0)
28 		close(fFD);
29 }
30 
31 
32 status_t
33 PPPManager::InitCheck() const
34 {
35 	if(fFD < 0)
36 		return B_ERROR;
37 	else
38 		return B_OK;
39 }
40 
41 
42 status_t
43 PPPManager::Control(uint32 op, void *data, size_t length) const
44 {
45 	if(InitCheck() != B_OK)
46 		return B_ERROR;
47 
48 	control_net_module_args args;
49 	args.name = PPP_INTERFACE_MODULE_NAME;
50 	args.op = op;
51 	args.data = data;
52 	args.length = length;
53 
54 	return ioctl(fFD, NET_STACK_CONTROL_NET_MODULE, &args);
55 }
56 
57 
58 status_t
59 PPPManager::ControlModule(const char *name, uint32 op, void *data,
60 	size_t length) const
61 {
62 	if(!name)
63 		return B_ERROR;
64 
65 	control_net_module_args args;
66 	args.name = name;
67 	args.op = op;
68 	args.data = data;
69 	args.length = length;
70 	return Control(PPPC_CONTROL_MODULE, &args, sizeof(args));
71 }
72 
73 
74 ppp_interface_id
75 PPPManager::CreateInterface(const driver_settings *settings,
76 	const driver_settings *profile = NULL) const
77 {
78 	ppp_interface_description_info info;
79 	info.u.settings = settings;
80 	info.profile = profile;
81 
82 	if(Control(PPPC_CREATE_INTERFACE, &info, sizeof(info)) != B_OK)
83 		return PPP_UNDEFINED_INTERFACE_ID;
84 	else
85 		return info.interface;
86 }
87 
88 
89 ppp_interface_id
90 PPPManager::CreateInterfaceWithName(const char *name,
91 	const driver_settings *profile = NULL) const
92 {
93 	ppp_interface_description_info info;
94 	info.u.name = name;
95 	info.profile = profile;
96 
97 	if(Control(PPPC_CREATE_INTERFACE_WITH_NAME, &info, sizeof(info)) != B_OK)
98 		return PPP_UNDEFINED_INTERFACE_ID;
99 	else
100 		return info.interface;
101 }
102 
103 
104 bool
105 PPPManager::DeleteInterface(ppp_interface_id ID) const
106 {
107 	if(Control(PPPC_DELETE_INTERFACE, &ID, sizeof(ID)) != B_OK)
108 		return false;
109 	else
110 		return true;
111 }
112 
113 
114 ppp_interface_id*
115 PPPManager::Interfaces(int32 *count,
116 	ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const
117 {
118 	int32 requestCount;
119 	ppp_interface_id *interfaces;
120 
121 	// loop until we get all interfaces
122 	while(true) {
123 		requestCount = *count = CountInterfaces(filter);
124 		if(*count == -1)
125 			return NULL;
126 
127 		requestCount += 10;
128 			// request some more interfaces in case some are added in the mean time
129 		interfaces = new ppp_interface_id[requestCount];
130 		*count = GetInterfaces(interfaces, requestCount, filter);
131 		if(*count == -1) {
132 			delete interfaces;
133 			return NULL;
134 		}
135 
136 		if(*count < requestCount)
137 			break;
138 
139 		delete interfaces;
140 	}
141 
142 	return interfaces;
143 }
144 
145 
146 int32
147 PPPManager::GetInterfaces(ppp_interface_id *interfaces, int32 count,
148 	ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const
149 {
150 	ppp_get_interfaces_info info;
151 	info.interfaces = interfaces;
152 	info.count = count;
153 	info.filter = filter;
154 
155 	if(Control(PPPC_GET_INTERFACES, &info, sizeof(info)) != B_OK)
156 		return -1;
157 	else
158 		return info.resultCount;
159 }
160 
161 
162 ppp_interface_id
163 PPPManager::InterfaceWithSettings(const driver_settings *settings) const
164 {
165 	ppp_interface_description_info info;
166 	info.u.settings = settings;
167 	info.interface = PPP_UNDEFINED_INTERFACE_ID;
168 
169 	Control(PPPC_FIND_INTERFACE_WITH_SETTINGS, &info, sizeof(info));
170 
171 	return info.interface;
172 }
173 
174 
175 ppp_interface_id
176 PPPManager::InterfaceWithUnit(int32 if_unit) const
177 {
178 	int32 count;
179 	ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
180 
181 	if(!interfaces)
182 		return PPP_UNDEFINED_INTERFACE_ID;
183 
184 	ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
185 	PPPInterface interface;
186 	ppp_interface_info_t info;
187 
188 	for(int32 index = 0; index < count; index++) {
189 		interface.SetTo(interfaces[index]);
190 		if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
191 				&& info.info.if_unit == if_unit) {
192 			id = interface.ID();
193 			break;
194 		}
195 	}
196 
197 	delete interfaces;
198 
199 	return id;
200 }
201 
202 
203 ppp_interface_id
204 PPPManager::InterfaceWithName(const char *name) const
205 {
206 	if(!name)
207 		return PPP_UNDEFINED_INTERFACE_ID;
208 
209 	int32 count;
210 	ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
211 
212 	if(!interfaces)
213 		return PPP_UNDEFINED_INTERFACE_ID;
214 
215 	ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
216 	PPPInterface interface;
217 	ppp_interface_info_t info;
218 
219 	for(int32 index = 0; index < count; index++) {
220 		interface.SetTo(interfaces[index]);
221 		if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
222 				&& strlen(info.info.name) > 0 && !strcasecmp(info.info.name, name)) {
223 			id = interface.ID();
224 			break;
225 		}
226 	}
227 
228 	delete interfaces;
229 
230 	if(id != PPP_UNDEFINED_INTERFACE_ID)
231 		return id;
232 	else if(!strncmp(name, "ppp", 3) && strlen(name) > 3 && isdigit(name[3]))
233 		return InterfaceWithUnit(atoi(name + 3));
234 	else if(isdigit(name[0]))
235 		return atoi(name);
236 	else
237 		return PPP_UNDEFINED_INTERFACE_ID;
238 }
239 
240 
241 int32
242 PPPManager::CountInterfaces(ppp_interface_filter filter =
243 	PPP_REGISTERED_INTERFACES) const
244 {
245 	return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
246 }
247 
248 
249 bool
250 PPPManager::EnableReports(ppp_report_type type, thread_id thread,
251 	int32 flags = PPP_NO_FLAGS) const
252 {
253 	ppp_report_request request;
254 	request.type = type;
255 	request.thread = thread;
256 	request.flags = flags;
257 
258 	return Control(PPPC_ENABLE_REPORTS, &request, sizeof(request)) == B_OK;
259 }
260 
261 
262 bool
263 PPPManager::DisableReports(ppp_report_type type, thread_id thread) const
264 {
265 	ppp_report_request request;
266 	request.type = type;
267 	request.thread = thread;
268 
269 	return Control(PPPC_DISABLE_REPORTS, &request, sizeof(request)) == B_OK;
270 }
271