xref: /haiku/src/add-ons/kernel/network/ppp/shared/libppp/PPPManager.cpp (revision 9eb55bc1d104b8fda80898f8b25c94d8000c8255)
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 ppp_interface_id
59 PPPManager::CreateInterface(const driver_settings *settings,
60 	const driver_settings *profile = NULL) const
61 {
62 	ppp_interface_description_info info;
63 	info.u.settings = settings;
64 	info.profile = profile;
65 
66 	if(Control(PPPC_CREATE_INTERFACE, &info, sizeof(info)) != B_OK)
67 		return PPP_UNDEFINED_INTERFACE_ID;
68 	else
69 		return info.interface;
70 }
71 
72 
73 ppp_interface_id
74 PPPManager::CreateInterfaceWithName(const char *name,
75 	const driver_settings *profile = NULL) const
76 {
77 	ppp_interface_description_info info;
78 	info.u.name = name;
79 	info.profile = profile;
80 
81 	if(Control(PPPC_CREATE_INTERFACE_WITH_NAME, &info, sizeof(info)) != B_OK)
82 		return PPP_UNDEFINED_INTERFACE_ID;
83 	else
84 		return info.interface;
85 }
86 
87 
88 bool
89 PPPManager::DeleteInterface(ppp_interface_id ID) const
90 {
91 	if(Control(PPPC_DELETE_INTERFACE, &ID, sizeof(ID)) != B_OK)
92 		return false;
93 	else
94 		return true;
95 }
96 
97 
98 ppp_interface_id*
99 PPPManager::Interfaces(int32 *count,
100 	ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const
101 {
102 	int32 requestCount;
103 	ppp_interface_id *interfaces;
104 
105 	// loop until we get all interfaces
106 	while(true) {
107 		requestCount = *count = CountInterfaces(filter);
108 		if(*count == -1)
109 			return NULL;
110 
111 		requestCount += 10;
112 			// request some more interfaces in case some are added in the mean time
113 		interfaces = new ppp_interface_id[requestCount];
114 		*count = GetInterfaces(interfaces, requestCount, filter);
115 		if(*count == -1) {
116 			delete interfaces;
117 			return NULL;
118 		}
119 
120 		if(*count < requestCount)
121 			break;
122 
123 		delete interfaces;
124 	}
125 
126 	return interfaces;
127 }
128 
129 
130 int32
131 PPPManager::GetInterfaces(ppp_interface_id *interfaces, int32 count,
132 	ppp_interface_filter filter = PPP_REGISTERED_INTERFACES) const
133 {
134 	ppp_get_interfaces_info info;
135 	info.interfaces = interfaces;
136 	info.count = count;
137 	info.filter = filter;
138 
139 	if(Control(PPPC_GET_INTERFACES, &info, sizeof(info)) != B_OK)
140 		return -1;
141 	else
142 		return info.resultCount;
143 }
144 
145 
146 ppp_interface_id
147 PPPManager::InterfaceWithSettings(const driver_settings *settings) const
148 {
149 	ppp_interface_description_info info;
150 	info.u.settings = settings;
151 	info.interface = PPP_UNDEFINED_INTERFACE_ID;
152 
153 	Control(PPPC_FIND_INTERFACE_WITH_SETTINGS, &info, sizeof(info));
154 
155 	return info.interface;
156 }
157 
158 
159 ppp_interface_id
160 PPPManager::InterfaceWithUnit(int32 if_unit) const
161 {
162 	int32 count;
163 	ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
164 
165 	if(!interfaces)
166 		return PPP_UNDEFINED_INTERFACE_ID;
167 
168 	ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
169 	PPPInterface interface;
170 	ppp_interface_info_t info;
171 
172 	for(int32 index = 0; index < count; index++) {
173 		interface.SetTo(interfaces[index]);
174 		if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
175 				&& info.info.if_unit == if_unit) {
176 			id = interface.ID();
177 			break;
178 		}
179 	}
180 
181 	delete interfaces;
182 
183 	return id;
184 }
185 
186 
187 ppp_interface_id
188 PPPManager::InterfaceWithName(const char *name) const
189 {
190 	if(!name)
191 		return PPP_UNDEFINED_INTERFACE_ID;
192 
193 	int32 count;
194 	ppp_interface_id *interfaces = Interfaces(&count, PPP_REGISTERED_INTERFACES);
195 
196 	if(!interfaces)
197 		return PPP_UNDEFINED_INTERFACE_ID;
198 
199 	ppp_interface_id id = PPP_UNDEFINED_INTERFACE_ID;
200 	PPPInterface interface;
201 	ppp_interface_info_t info;
202 
203 	for(int32 index = 0; index < count; index++) {
204 		interface.SetTo(interfaces[index]);
205 		if(interface.InitCheck() == B_OK && interface.GetInterfaceInfo(&info)
206 				&& strlen(info.info.name) > 0 && !strcasecmp(info.info.name, name)) {
207 			id = interface.ID();
208 			break;
209 		}
210 	}
211 
212 	delete interfaces;
213 
214 	if(id != PPP_UNDEFINED_INTERFACE_ID)
215 		return id;
216 	else if(!strncmp(name, "ppp", 3) && strlen(name) > 3 && isdigit(name[3]))
217 		return InterfaceWithUnit(atoi(name + 3));
218 	else if(isdigit(name[0]))
219 		return atoi(name);
220 	else
221 		return PPP_UNDEFINED_INTERFACE_ID;
222 }
223 
224 
225 int32
226 PPPManager::CountInterfaces(ppp_interface_filter filter =
227 	PPP_REGISTERED_INTERFACES) const
228 {
229 	return Control(PPPC_COUNT_INTERFACES, &filter, sizeof(filter));
230 }
231 
232 
233 bool
234 PPPManager::EnableReports(ppp_report_type type, thread_id thread,
235 	int32 flags = PPP_NO_FLAGS) const
236 {
237 	ppp_report_request request;
238 	request.type = type;
239 	request.thread = thread;
240 	request.flags = flags;
241 
242 	return Control(PPPC_ENABLE_REPORTS, &request, sizeof(request)) == B_OK;
243 }
244 
245 
246 bool
247 PPPManager::DisableReports(ppp_report_type type, thread_id thread) const
248 {
249 	ppp_report_request request;
250 	request.type = type;
251 	request.thread = thread;
252 
253 	return Control(PPPC_DISABLE_REPORTS, &request, sizeof(request)) == B_OK;
254 }
255