xref: /plan9/sys/src/cmd/ip/wol.c (revision 14cc0f535177405a84c5b73603a98e5db6674719)
1dfda52d8SDavid du Colombier /* send wake-on-lan magic ethernet packet */
2dfda52d8SDavid du Colombier #include <u.h>
3dfda52d8SDavid du Colombier #include <libc.h>
4dfda52d8SDavid du Colombier #include <ip.h>
5dfda52d8SDavid du Colombier 
6dfda52d8SDavid du Colombier enum {
7dfda52d8SDavid du Colombier 	Eaddrlen = 6,	/* 48 bits */
8dfda52d8SDavid du Colombier };
9dfda52d8SDavid du Colombier 
10dfda52d8SDavid du Colombier typedef struct Wolpack Wolpack;
11dfda52d8SDavid du Colombier struct Wolpack{
12dfda52d8SDavid du Colombier 	uchar	magic[6];
13dfda52d8SDavid du Colombier 	uchar	macs[16][Eaddrlen];
14dfda52d8SDavid du Colombier 	char	pass[6+1];
15dfda52d8SDavid du Colombier };
16dfda52d8SDavid du Colombier 
17dfda52d8SDavid du Colombier int verbose;
18dfda52d8SDavid du Colombier 
19dfda52d8SDavid du Colombier void
usage(void)20dfda52d8SDavid du Colombier usage(void)
21dfda52d8SDavid du Colombier {
22dfda52d8SDavid du Colombier 	fprint(2, "usage: wol [-v] [-a dialstr] [-c password] macaddr\n");
23dfda52d8SDavid du Colombier 	exits("usage");
24dfda52d8SDavid du Colombier }
25dfda52d8SDavid du Colombier 
26dfda52d8SDavid du Colombier void
fillmac(Wolpack * w,uchar * mac)27dfda52d8SDavid du Colombier fillmac(Wolpack *w, uchar *mac)
28dfda52d8SDavid du Colombier {
29dfda52d8SDavid du Colombier 	int i;
30dfda52d8SDavid du Colombier 
31dfda52d8SDavid du Colombier 	for(i = 0; i < nelem(w->macs); i++)
32dfda52d8SDavid du Colombier 		memmove(w->macs[i], mac, Eaddrlen);
33dfda52d8SDavid du Colombier }
34dfda52d8SDavid du Colombier 
35dfda52d8SDavid du Colombier void
dumppack(Wolpack * w)36dfda52d8SDavid du Colombier dumppack(Wolpack *w)
37dfda52d8SDavid du Colombier {
38dfda52d8SDavid du Colombier 	int i;
39dfda52d8SDavid du Colombier 
40dfda52d8SDavid du Colombier 	print("packet: [\n");
41dfda52d8SDavid du Colombier 	print("\t%E\n", w->magic);
42dfda52d8SDavid du Colombier 	for(i = 0; i < nelem(w->macs); i++)
43dfda52d8SDavid du Colombier 		print("\t%E\n", w->macs[i]);
44dfda52d8SDavid du Colombier 	print("\t%6s\n", w->pass);
45dfda52d8SDavid du Colombier 	print("]\n");
46dfda52d8SDavid du Colombier }
47dfda52d8SDavid du Colombier 
48dfda52d8SDavid du Colombier void
main(int argc,char * argv[])49dfda52d8SDavid du Colombier main(int argc, char* argv[])
50dfda52d8SDavid du Colombier {
51dfda52d8SDavid du Colombier 	int fd, nw;
52dfda52d8SDavid du Colombier 	char *argmac, *pass, *address;
53dfda52d8SDavid du Colombier 	uchar mac[Eaddrlen];
54dfda52d8SDavid du Colombier 	static Wolpack w = {
55dfda52d8SDavid du Colombier 		.magic { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }
56dfda52d8SDavid du Colombier 	};
57dfda52d8SDavid du Colombier 
58dfda52d8SDavid du Colombier 	address = pass = nil;
59dfda52d8SDavid du Colombier 	fmtinstall('E', eipfmt);
60dfda52d8SDavid du Colombier 
61dfda52d8SDavid du Colombier 	ARGBEGIN{
62dfda52d8SDavid du Colombier 	case 'a':
63dfda52d8SDavid du Colombier 		address = EARGF(usage());
64dfda52d8SDavid du Colombier 		break;
65dfda52d8SDavid du Colombier 	case 'c':
66dfda52d8SDavid du Colombier 		pass = EARGF(usage());
67dfda52d8SDavid du Colombier 		break;
68dfda52d8SDavid du Colombier 	case 'v':
69dfda52d8SDavid du Colombier 		verbose++;
70dfda52d8SDavid du Colombier 		break;
71dfda52d8SDavid du Colombier 	default:
72dfda52d8SDavid du Colombier 		usage();
73dfda52d8SDavid du Colombier 	}ARGEND
74dfda52d8SDavid du Colombier 
75dfda52d8SDavid du Colombier 	if(argc != 1)
76dfda52d8SDavid du Colombier 		usage();
77dfda52d8SDavid du Colombier 	argmac = argv[0];
78dfda52d8SDavid du Colombier 	if(verbose)
79dfda52d8SDavid du Colombier 		print("mac is %s, pass is %s\n", argmac, pass);
80dfda52d8SDavid du Colombier 
81dfda52d8SDavid du Colombier 	parseether(mac, argmac);
82dfda52d8SDavid du Colombier 	fillmac(&w, mac);
83dfda52d8SDavid du Colombier 	if(pass){
84dfda52d8SDavid du Colombier 		if(strlen(pass) > 6)
85*14cc0f53SDavid du Colombier 			sysfatal("password greater than 6 bytes");
86dfda52d8SDavid du Colombier 		strcpy(w.pass, pass);
87dfda52d8SDavid du Colombier 	}
88dfda52d8SDavid du Colombier 	if(verbose)
89dfda52d8SDavid du Colombier 		dumppack(&w);
90dfda52d8SDavid du Colombier 
91dfda52d8SDavid du Colombier 	if(!address)
92dfda52d8SDavid du Colombier 		address = "udp!255.255.255.255!0";
93dfda52d8SDavid du Colombier 
94dfda52d8SDavid du Colombier 	fd = dial(address, nil, nil, nil);
95dfda52d8SDavid du Colombier 	if(fd < 0)
96dfda52d8SDavid du Colombier 		sysfatal("%s: %r", address);
97dfda52d8SDavid du Colombier 	nw = write(fd, &w, sizeof w);
98dfda52d8SDavid du Colombier 	if(nw != sizeof w)
99dfda52d8SDavid du Colombier 		sysfatal("error sending: %r");
100dfda52d8SDavid du Colombier 	exits(0);
101dfda52d8SDavid du Colombier }
102