/* atmtcp.c - control ATM on TCP emulation */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/atm.h>


#define PORT 8401


static void usage(const char *name)
{
#if 0
    fprintf(stderr,"%s -l {<atmaddr>} [ <lclport> ]\n",name);
    fprintf(stderr,"%s -c <host> [ <rmtport> ]\n",name);
#else
    fprintf(stderr,"%s -l [ <lclport> ]\n",name);
    fprintf(stderr,"%s -c <host> [ <rmtport> ]\n",name);
#endif
    exit(1);
}


int main(int argc,char **argv)
{
    struct sockaddr_in addr;
    int listen_mode,port;
    int s,s2;

    if (argc < 2) usage(argv[0]);
    if (listen_mode = !strcmp(argv[1],"-l")) {
	if (argc > 3) usage(argv[0]);
	port = argc == 3 ? atoi(argv[2]) : -1;
    }
    else {
	if (argc > 4 || strcmp(argv[1],"-c")) usage(argv[0]);
	port = argc == 4 ? atoi(argv[3]) : -1;
    }
    if ((s = socket(PF_INET,SOCK_STREAM,0)) < 0) {
	perror("socket");
	return 1;
    }
    if (!port) usage(argv[0]);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port == -1 ? PORT : port);
    if (listen_mode) {
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
	    perror("bind");
	    return 1;
	}
	printf("Listening on port %d ...\n",ntohs(addr.sin_port));
	if (listen(s,5) < 0) {
	    perror("listen");
	    return 1;
	}
	if ((s2 = accept(s,NULL,NULL)) < 0) {
	    perror("accept");
	    return 1;
	}
	(void) close(s);
	s = s2;
    }
    else {
	struct hostent *h;

	if (h = gethostbyname(argv[2]))
	    memcpy(&addr.sin_addr.s_addr,h->h_addr,
	      sizeof(addr.sin_addr.s_addr));
	else if ((addr.sin_addr.s_addr = inet_addr(argv[2])) == -1) {
		herror(argv[2]);
		return 1;
	    }
	if (connect(s,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
	    perror("connect");
	    return 1;
	}
    }
    if (ioctl(s,SIOCSIFATMTCP,NULL) < 0) {
	perror("ioctl SIOCSIFATMTCP");
	return 1;
    }
    printf("Connected\n");
    (void) pause();
    return 0;
}
