1/*
2 * Copyright 2003-2004, Waldemar Kornewald <wkornew@gmx.net>
3 * Copyright 2006-2017, Haiku, Inc. All rights Reserved.
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 *   Alexander von Gluck IV <kallisti5@unixzen.com>
8 */
9
10#include <cstdio>
11#include <String.h>
12#include <driver_settings.h>
13
14#include <PPPInterface.h>
15#include <PPPManager.h>
16
17
18static const char sVersion[] = "0.12 pre-alpha";
19static const char sPPPInterfaceModuleName[] = PPP_INTERFACE_MODULE_NAME;
20
21
22static
23status_t
24print_help()
25{
26	fprintf(stderr, "Haiku Network Team: pppconfig: sVersion %s\n", sVersion);
27	fprintf(stderr, "With pppconfig you can create and manage PPP connections.\n");
28	fprintf(stderr, "Usage:\n");
29	fprintf(stderr, "pppconfig show | -a\n");
30	fprintf(stderr, "pppconfig init <name>\n");
31	fprintf(stderr, "pppconfig create <name>\n");
32	fprintf(stderr, "pppconfig connect <name|interface|id>\n");
33	fprintf(stderr, "pppconfig disconnect <name|interface|id>\n");
34	fprintf(stderr, "pppconfig delete <name|interface|id>\n");
35	fprintf(stderr, "pppconfig details <name|interface|id>\n");
36	fprintf(stderr, "\t<name> must be an interface description file\n");
37
38	return -1;
39}
40
41
42static
43status_t
44show(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES)
45{
46	PPPManager manager;
47	if (manager.InitCheck() != B_OK) {
48		fprintf(stderr, "Error: Could not load interface manager!\n");
49		return -1;
50	}
51
52	int32 count = 0;
53	ppp_interface_id *interfaces = manager.Interfaces(&count, filter);
54
55	if (!interfaces || count <= 0) {
56		fprintf(stderr, "Error: Could not get interfaces information!\n");
57		return -1;
58	}
59
60	fprintf(stderr, "Get %" B_PRId32 " ppp interfaces, first is %" B_PRIu32 "!\n",
61		count, interfaces[0]);
62
63	ppp_interface_info_t info;
64	PPPInterface interface;
65
66	printf("Listing PPP interfaces:\n");
67
68	// print out information for each interface
69	for (int32 index = 0; index < count; index++) {
70		interface.SetTo(interfaces[index]);
71		if (interface.InitCheck() == B_OK) {
72			interface.GetInterfaceInfo(&info);
73			printf("\n");
74
75			// type and unit (if it has one)
76			if (info.info.if_unit >= 0) {
77				printf("Type: Visible\n");
78				printf("\tInterface: ppp%" B_PRId32 "\n", info.info.if_unit);
79			} else
80				printf("Type: Hidden\n");
81
82			printf("\tName: %s\n", info.info.name);
83
84			// ID
85			printf("\tID: %" B_PRIu32 "\n", interface.ID());
86
87			// mode
88			printf("\tMode: ");
89			if (info.info.mode == PPP_CLIENT_MODE)
90				printf("Client\n");
91			else if (info.info.mode == PPP_SERVER_MODE)
92				printf("Server\n");
93			else
94				printf("Unknown\n");
95
96			// status
97			printf("\tStatus: ");
98			switch(info.info.phase) {
99				case PPP_ESTABLISHED_PHASE:
100					printf("Connected\n");
101				break;
102
103				case PPP_DOWN_PHASE:
104					printf("Disconnected\n");
105				break;
106
107				case PPP_TERMINATION_PHASE:
108					printf("Disconnecting\n");
109				break;
110
111				default:
112					printf("Connecting\n");
113			}
114		}
115	}
116
117	delete interfaces;
118
119	return 0;
120}
121
122
123static
124status_t
125create(const char *name, bool bringUp = true)
126{
127	PPPManager manager;
128	if (manager.InitCheck() != B_OK) {
129		fprintf(stderr, "Error: Could not load interface manager!\n");
130		return -1;
131	}
132
133	PPPInterface interface(manager.CreateInterfaceWithName(name));
134	if (interface.InitCheck() != B_OK) {
135		fprintf(stderr, "Error: Could not create interface: %s!\n", name);
136		return -1;
137	}
138
139	printf("Created interface with ID: %" B_PRIu32 "\n", interface.ID());
140
141	ppp_interface_info_t info;
142	interface.GetInterfaceInfo(&info);
143
144	if (info.info.if_unit >= 0)
145		printf("Interface: ppp%" B_PRId32 "\n", info.info.if_unit);
146	else
147		printf("This interface is hidden! You can delete it by typing:\n"
148			"pppconfig delete %" B_PRIu32 "\n", interface.ID());
149
150	if (bringUp) {
151		interface.Up();
152		printf("Connecting in background...\n");
153	}
154
155	return 0;
156}
157
158
159static
160status_t
161connect(const char *name)
162{
163	if (!name || strlen(name) == 0)
164		return -1;
165
166	PPPManager manager;
167	if (manager.InitCheck() != B_OK) {
168		fprintf(stderr, "Error: Could not load interface manager!\n");
169		return -1;
170	}
171
172	PPPInterface interface(manager.InterfaceWithName(name));
173	if (interface.InitCheck() != B_OK) {
174		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
175		return -1;
176	}
177
178	if (!interface.Up()) {
179		fprintf(stderr, "Error: Could not connect!\n");
180		return -1;
181	}
182
183	printf("Connecting in background...\n");
184
185	return 0;
186}
187
188
189static
190status_t
191setuser(const char *name, const char* user)
192{
193	if (!name || strlen(name) == 0)
194		return -1;
195
196	if (!user || strlen(user) == 0)
197		return -1;
198
199	PPPManager manager;
200	if (manager.InitCheck() != B_OK) {
201		fprintf(stderr, "Error: Could not load interface manager!\n");
202		return -1;
203	}
204
205	PPPInterface interface(manager.InterfaceWithName(name));
206	if (interface.InitCheck() != B_OK) {
207		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
208		return -1;
209	}
210
211	if (!interface.SetUsername(user)) {
212		fprintf(stderr, "Error: Could not SetUsername %s!\n", user);
213		return -1;
214	}
215
216	return 0;
217}
218
219
220static
221status_t
222setpass(const char *name, const char* pass)
223{
224	if (!name || strlen(name) == 0)
225		return -1;
226
227	if (!pass || strlen(pass) == 0)
228		return -1;
229
230	PPPManager manager;
231	if (manager.InitCheck() != B_OK) {
232		fprintf(stderr, "Error: Could not load interface manager!\n");
233		return -1;
234	}
235
236	PPPInterface interface(manager.InterfaceWithName(name));
237	if (interface.InitCheck() != B_OK) {
238		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
239		return -1;
240	}
241
242	if (!interface.SetPassword(pass)) {
243		fprintf(stderr, "Error: Could not SetUsername %s!\n", pass);
244		return -1;
245	}
246
247	return 0;
248}
249
250
251static
252status_t
253setaskbeforeconnect(const char *name, const char* connect)
254{
255	if (!name || strlen(name) == 0)
256		return -1;
257
258	bool askBeforeConnecting = false;
259	if (connect || !strcmp(connect, "true") || !strcmp(connect, "ask") ||
260		!strcmp(connect, "yes") || !strcmp(connect, "y"))
261		askBeforeConnecting = true;
262
263
264	PPPManager manager;
265	if (manager.InitCheck() != B_OK) {
266		fprintf(stderr, "Error: Could not load interface manager!\n");
267		return -1;
268	}
269
270	PPPInterface interface(manager.InterfaceWithName(name));
271	if (interface.InitCheck() != B_OK) {
272		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
273		return -1;
274	}
275
276	if (!interface.SetAskBeforeConnecting(askBeforeConnecting)) {
277		fprintf(stderr, "Error: Could not connect %s!\n", connect);
278		return -1;
279	}
280
281	return 0;
282}
283
284
285static
286status_t
287getstatistics(const char *name)
288{
289	if (!name || strlen(name) == 0)
290		return -1;
291
292	PPPManager manager;
293	if (manager.InitCheck() != B_OK) {
294		fprintf(stderr, "Error: Could not load interface manager!\n");
295		return -1;
296	}
297
298	PPPInterface interface(manager.InterfaceWithName(name));
299	if (interface.InitCheck() != B_OK) {
300		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
301		return -1;
302	}
303
304	ppp_statistics pppStatistics;
305	if (interface.GetStatistics(&pppStatistics) != B_OK) {
306		fprintf(stderr, "Error: Could not getstatistics: %s!\n", name);
307		return -1;
308	}
309
310	return 0;
311}
312
313
314static
315status_t
316hassettings(const char *name)
317{
318	if (!name || strlen(name) == 0)
319		return -1;
320
321	PPPManager manager;
322	if (manager.InitCheck() != B_OK) {
323		fprintf(stderr, "Error: Could not load interface manager!\n");
324		return -1;
325	}
326
327	PPPInterface interface(manager.InterfaceWithName(name));
328	if (interface.InitCheck() != B_OK) {
329		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
330		return -1;
331	}
332
333	driver_settings settings;
334	if (interface.HasSettings(&settings) != B_OK) {
335		fprintf(stderr, "Error: Could not getstatistics: %s!\n", name);
336		return -1;
337	}
338
339	return 0;
340}
341
342
343static
344status_t
345enablereports(const char *name)
346{
347	if (!name || strlen(name) == 0)
348		return -1;
349
350	PPPManager manager;
351	if (manager.InitCheck() != B_OK) {
352		fprintf(stderr, "Error: Could not load interface manager!\n");
353		return -1;
354	}
355
356	PPPInterface interface(manager.InterfaceWithName(name));
357	if (interface.InitCheck() != B_OK) {
358		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
359		return -1;
360	}
361
362	ppp_report_type type = PPP_ALL_REPORTS;
363	thread_id thread = 0;
364        int32 flags = 0;
365
366	if (interface.EnableReports(type, thread, flags) != true) {
367		fprintf(stderr, "Error: Could not EnableReports: %s!\n", name);
368		return -1;
369	}
370
371	return 0;
372}
373
374
375static
376status_t
377disablereports(const char *name)
378{
379	if (!name || strlen(name) == 0)
380		return -1;
381
382	PPPManager manager;
383	if (manager.InitCheck() != B_OK) {
384		fprintf(stderr, "Error: Could not load interface manager!\n");
385		return -1;
386	}
387
388	PPPInterface interface(manager.InterfaceWithName(name));
389	if (interface.InitCheck() != B_OK) {
390		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
391		return -1;
392	}
393
394	ppp_report_type type = PPP_ALL_REPORTS;
395	thread_id thread = 0;
396
397	if (interface.DisableReports(type, thread) != true) {
398		fprintf(stderr, "Error: Could not EnableReports: %s!\n", name);
399		return -1;
400	}
401
402	return 0;
403}
404
405
406static
407status_t
408controlchild(const char *name)
409{
410	if (!name || strlen(name) == 0)
411		return -1;
412
413	PPPManager manager;
414	if (manager.InitCheck() != B_OK) {
415		fprintf(stderr, "Error: Could not load interface manager!\n");
416		return -1;
417	}
418
419	PPPInterface interface(manager.InterfaceWithName(name));
420	if (interface.InitCheck() != B_OK) {
421		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
422		return -1;
423	}
424
425	ppp_simple_handler_info_t info;
426
427	if (interface.ControlChild(&info, 0, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
428		fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
429		return -1;
430	}
431
432	printf("LCPExtensionHandler: %s\n", info.info.name);
433	printf("isEnabled: %d\n", info.info.isEnabled);
434
435	if (interface.ControlChild(&info, 0, PPPC_ENABLE) != true) {
436		fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
437		return -1;
438	}
439	return 0;
440}
441
442
443static
444status_t
445controllcpextension(const char *name)
446{
447	if (!name || strlen(name) == 0)
448		return -1;
449
450	PPPManager manager;
451	if (manager.InitCheck() != B_OK) {
452		fprintf(stderr, "Error: Could not load interface manager!\n");
453		return -1;
454	}
455
456	PPPInterface interface(manager.InterfaceWithName(name));
457	if (interface.InitCheck() != B_OK) {
458		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
459		return -1;
460	}
461
462	ppp_simple_handler_info_t info;
463
464	if (interface.ControlLCPExtension(&info, 1, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
465		fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
466		return -1;
467	}
468
469	printf("LCPExtensionHandler: %s\n", info.info.name);
470	printf("isEnabled: %d\n", info.info.isEnabled);
471
472	if (interface.ControlLCPExtension(&info, 1, PPPC_ENABLE) != true) {
473		fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
474		return -1;
475	}
476	return 0;
477}
478
479
480static
481status_t
482controloptionhandler(const char *name)
483{
484	if (!name || strlen(name) == 0)
485		return -1;
486
487	PPPManager manager;
488	if (manager.InitCheck() != B_OK) {
489		fprintf(stderr, "Error: Could not load interface manager!\n");
490		return -1;
491	}
492
493	PPPInterface interface(manager.InterfaceWithName(name));
494	if (interface.InitCheck() != B_OK) {
495		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
496		return -1;
497	}
498
499	ppp_simple_handler_info_t info;
500
501	if (interface.ControlOptionHandler(&info, 0, PPPC_GET_SIMPLE_HANDLER_INFO) != true) {
502		fprintf(stderr, "Error: Could not PPPC_GET_SIMPLE_HANDLER_INFO: %s!\n", name);
503		return -1;
504	}
505
506	printf("protocol: %s\n", info.info.name);
507	printf("isEnabled: %d\n", info.info.isEnabled);
508
509	if (interface.ControlOptionHandler(&info, 0, PPPC_ENABLE) != true) {
510		fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
511		return -1;
512	}
513	return 0;
514}
515
516
517static
518status_t
519controlprotocol(const char *name)
520{
521	if (!name || strlen(name) == 0)
522		return -1;
523
524	PPPManager manager;
525	if (manager.InitCheck() != B_OK) {
526		fprintf(stderr, "Error: Could not load interface manager!\n");
527		return -1;
528	}
529
530	PPPInterface interface(manager.InterfaceWithName(name));
531	if (interface.InitCheck() != B_OK) {
532		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
533		return -1;
534	}
535
536	ppp_protocol_info_t info;
537
538	if (interface.ControlProtocol(&info, 0, PPPC_GET_PROTOCOL_INFO) != true) {
539		fprintf(stderr, "Error: Could not PPPC_GET_PROTOCOL_INFO: %s!\n", name);
540		return -1;
541	}
542
543	printf("protocol: %s\n", info.info.name);
544	printf("type: %s\n", info.info.type);
545	printf("activationPhase: %d\n", info.info.activationPhase);
546	printf("addressFamily: %" B_PRId32 "\n", info.info.addressFamily);
547	printf("flags: %" B_PRId32 "\n", info.info.flags);
548	printf("side: %d\n", info.info.side);
549	printf("level: %d\n", info.info.level);
550	printf("connectionPhase: %d\n", info.info.connectionPhase);
551	printf("protocolNumber: %d\n", info.info.protocolNumber);
552	printf("isEnabled: %d\n", info.info.isEnabled);
553	printf("isUpRequested: %d\n", info.info.isUpRequested);
554
555	if (interface.ControlProtocol(&info, 0, PPPC_ENABLE) != true) {
556		fprintf(stderr, "Error: Could not PPPC_ENABLE: %s!\n", name);
557		return -1;
558	}
559	return 0;
560}
561
562
563static
564status_t
565controldevice(const char *name)
566{
567	if (!name || strlen(name) == 0)
568		return -1;
569
570	PPPManager manager;
571	if (manager.InitCheck() != B_OK) {
572		fprintf(stderr, "Error: Could not load interface manager!\n");
573		return -1;
574	}
575
576	PPPInterface interface(manager.InterfaceWithName(name));
577	if (interface.InitCheck() != B_OK) {
578		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
579		return -1;
580	}
581
582	ppp_device_info_t info;
583
584	if (interface.ControlDevice(&info) != true) {
585		fprintf(stderr, "Error: Could not ControlDevice: %s!\n", name);
586		return -1;
587	}
588
589	printf("name: %s\n", info.info.name);
590	printf("MTU: %" B_PRIu32 "\n", info.info.MTU);
591	printf("inputTransferRate: %" B_PRIu32 "\n", info.info.inputTransferRate);
592	printf("outputTransferRate: %" B_PRIu32 "\n", info.info.outputTransferRate);
593	printf("outputBytesCount: %" B_PRIu32 "\n", info.info.outputBytesCount);
594	printf("isUp: %d\n", info.info.isUp);
595
596	return 0;
597}
598
599
600static
601status_t
602disconnect(const char *name)
603{
604	if (!name || strlen(name) == 0)
605		return -1;
606
607	PPPManager manager;
608	if (manager.InitCheck() != B_OK) {
609		fprintf(stderr, "Error: Could not load interface manager!\n");
610		return -1;
611	}
612
613	PPPInterface interface(manager.InterfaceWithName(name));
614	if (interface.InitCheck() != B_OK) {
615		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
616		return -1;
617	}
618
619	if (!interface.Down()) {
620		fprintf(stderr, "Error: Could not disconnect!\n");
621		return -1;
622	}
623
624	return 0;
625}
626
627
628static
629status_t
630delete_interface(const char *name)
631{
632	if (!name || strlen(name) == 0)
633		return -1;
634
635	PPPManager manager;
636	if (manager.InitCheck() != B_OK) {
637		fprintf(stderr, "Error: Could not load interface manager!\n");
638		return -1;
639	}
640
641	if (!manager.DeleteInterface(name)) {
642		fprintf(stderr, "Error: Could not delete interface!\n");
643		return -1;
644	}
645
646	return 0;
647}
648
649
650static
651status_t
652show_details(const char *name)
653{
654	if (!name || strlen(name) == 0)
655		return -1;
656
657	PPPManager manager;
658	if (manager.InitCheck() != B_OK) {
659		fprintf(stderr, "Error: Could not load interface manager!\n");
660		return -1;
661	}
662
663	ppp_interface_id ID = manager.InterfaceWithName(name);
664	if (ID <= 0) {
665		fprintf(stderr, "Error: Could not find interface: %s!\n", name);
666		return -1;
667	}
668
669	PPPInterface interface(ID);
670	if (interface.InitCheck() != B_OK) {
671		fprintf(stderr, "Error: Could not find interface ID: %" B_PRIu32 "!\n", ID);
672		return -1;
673	}
674
675	ppp_interface_info_t info;
676	// printf("ppp_interface_info_t addr:%p\n", &info);
677	interface.GetInterfaceInfo(&info);
678
679	// type and name (if it has one)
680	if (info.info.if_unit >= 0) {
681		printf("Type: Visible\n");
682		printf("Interface: ppp%" B_PRId32 "\n", info.info.if_unit);
683	} else
684		printf("Type: Hidden\n");
685
686	printf("Name: %s\n", info.info.name);
687
688	// ID
689	printf("ID: %" B_PRIu32 "\n", interface.ID());
690
691	// ConnectOnDemand
692	printf("ConnectOnDemand: %s\n", info.info.doesConnectOnDemand ?
693		"Enabled" : "Disabled");
694
695	// AutoReconnect
696	printf("AutoReconnect: %s\n", info.info.doesAutoReconnect ?
697		"Enabled" : "Disabled");
698
699	// MRU and interfaceMTU
700	printf("MRU: %" B_PRIu32 "\n", info.info.MRU);
701	printf("Interface MTU: %" B_PRIu32 "\n", info.info.interfaceMTU);
702
703	// mode
704	printf("Mode: ");
705	if (info.info.mode == PPP_CLIENT_MODE)
706		printf("Client\n");
707	else if (info.info.mode == PPP_SERVER_MODE)
708		printf("Server\n");
709	else
710		printf("Unknown\n");
711
712	// status
713	printf("\tStatus: ");
714	switch(info.info.phase) {
715		case PPP_ESTABLISHED_PHASE:
716			printf("Connected\n");
717		break;
718
719		case PPP_DOWN_PHASE:
720			printf("Disconnected\n");
721		break;
722
723		case PPP_TERMINATION_PHASE:
724			printf("Disconnecting\n");
725		break;
726
727		default:
728			printf("Connecting\n");
729	}
730
731	return 0;
732}
733
734
735int
736main(int argc, char *argv[])
737{
738	if (argc == 2) {
739		if (!strcmp(argv[1], "show") || !strcmp(argv[1], "-a"))
740			return show(PPP_ALL_INTERFACES);
741		else
742			return print_help();
743	}if (argc == 3) {
744		if (!strcmp(argv[1], "init"))
745			return create(argv[2], false);
746		else if (!strcmp(argv[1], "create"))
747			return create(argv[2], true);
748		else if (!strcmp(argv[1], "connect"))
749			return connect(argv[2]);
750		else if (!strcmp(argv[1], "disconnect"))
751			return disconnect(argv[2]);
752		else if (!strcmp(argv[1], "delete"))
753			return delete_interface(argv[2]);
754		else if (!strcmp(argv[1], "details"))
755			return show_details(argv[2]);
756		else if (!strcmp(argv[1], "getstatistics"))
757			return getstatistics(argv[2]);
758		else if (!strcmp(argv[1], "hassettings"))
759			return hassettings(argv[2]);
760		else if (!strcmp(argv[1], "enablereports"))
761			return enablereports(argv[2]);
762		else if (!strcmp(argv[1], "disablereports"))
763			return disablereports(argv[2]);
764		else if (!strcmp(argv[1], "controldevice"))
765			return controldevice(argv[2]);
766		else if (!strcmp(argv[1], "controlprotocol"))
767			return controlprotocol(argv[2]);
768		else if (!strcmp(argv[1], "controloptionhandler"))
769			return controloptionhandler(argv[2]);
770		else if (!strcmp(argv[1], "controllcpextension"))
771			return controllcpextension(argv[2]);
772		else if (!strcmp(argv[1], "controlchild"))
773			return controlchild(argv[2]);
774		else
775			return print_help();
776	} if (argc == 4) {
777		if (!strcmp(argv[1], "setuser"))
778			return setuser(argv[2], argv[3]);
779		else if (!strcmp(argv[1], "setpass"))
780			return setpass(argv[2], argv[3]);
781		else if (!strcmp(argv[1], "setaskbeforeconnect"))
782			return setaskbeforeconnect(argv[2], argv[3]);
783		else
784			return print_help();
785	} else
786		return print_help();
787}
788