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