/* Simple program to reboot a portmaster.
   
   Decoded from etherfind packet tracing between SUN application pmconsole
   and a target portmaster.

   Known to work with PortMaster OS2.3.

   (c) Mike Park.  Version 1.0.  You are free to do with this as you want.
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <libc.h>

#define PASSWD		"rootabaga" 	/* root account password */
#define PORTMASTER	"nos1"		/* name of target portmaster */
#define PORT		1643		/* magic destination port */

int fd;					/* open port to device */

void sendCmd(int option, char *cmd)
{
    char buf[128];

    buf[0] = 0x65;
    buf[1] = option;
    buf[2] = 0x0;
    buf[3] = strlen(cmd)+1;
    bzero(&buf[4], buf[3]+5);
    bcopy(cmd, &buf[4], buf[3]);
    
    /* ensure cmd has even length */
    if (buf[3] & 1)
	buf[3]++;
    write(fd, buf, buf[3]+4);
}

int readData(void *buf, int size)
{
    return(read(fd, buf, size));
}

void openPortMaster(void)
{
    char buf[10];
    struct hostent *hp;
    struct sockaddr_in sin;

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0)
	fprintf(stderr, "create of socket: failed.\n");
    
    bzero(&sin, sizeof(sin));
    hp = gethostbyname(PORTMASTER);
    if (hp == 0)
	fprintf(stderr, "host %s not found.\n", PORTMASTER);

    bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);

    if (connect(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	fprintf(stderr, "connect failed.\n");
    
    sendCmd(2, PASSWD);
    readData(buf, 5);
}

void rebootPortMaster(void)
{
    fprintf(stderr, "Rebooting %s ...\n", PORTMASTER);
    sendCmd(4, "reboot");
}

void main()
{
    openPortMaster();
    rebootPortMaster();
}

