/*
 * Fire a legal PPP configure request packet at 0.0.101. Expect some kind
 * of response (the Speedstream 3010 doesn't give me anything, but it is
 * still uncertain whether this is a driver problem or something else).
 *
 * Please try this over other ATM NIC's and report what happens when you
 * run the program.
 *
 * gcc -Wall -o pppoa pppoa.c
 *
 * Jens Axboe <axboe@image.dk>
 */

#define ATM_ITF	0
#define ATM_VCI 101

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <atm.h>

void dump_it(unsigned char *buf, int len)
{
	int i;

	for (i = 0; i < len; i++)
		printf("%02x ", buf[i]);

	printf("\n");
}

int main(int argc,char **argv)
{
    struct sockaddr_atmpvc addr;
    struct atm_qos qos;
    int s, size;
    char buf[128];

    /* identical to what Windows throws at the ADSL box initially */
    char config[] = { 0xc0, 0x21, 0x01, 0x01, 0x00, 0x11, 0x05, 0x06, 0x00,
		      0xcd, 0x3c, 0xa2, 0x07, 0x02, 0x08, 0x02, 0x0d, 0x03,
		      0x06, 0x00, 0x00, 0x00, 0x00, 0x00 };

    if ((s = socket(PF_ATMPVC, SOCK_DGRAM, 0)) < 0) {
	perror("socket");
	return 1;
    }

    bzero(&addr, sizeof(addr));
    addr.sap_family = PF_ATMPVC;
    addr.sap_addr.itf = ATM_ITF;
    addr.sap_addr.vpi = 0;
    addr.sap_addr.vci = ATM_VCI;

    bzero(&qos, sizeof(qos));
    qos.aal = ATM_AAL5;
    qos.txtp.traffic_class = ATM_UBR;
    qos.txtp.max_sdu = 1500;
    qos.rxtp = qos.txtp;
    printf("setting socket options\n");
    if (setsockopt(s, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) {
	perror("setsockopt SO_ATMQOS");
	return 1;
    }

    printf("connection on vci %d\n", addr.sap_addr.vci);
    if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
	perror("connect");
	return 1;
    }

    printf("writing stuff\n");
    size = write(s, config, 0x18);
    printf("sent %d\n", size);
    dump_it(config, 0x18);

    printf("reading stuff\n");
    size = read(s, buf, 100);
    printf("revcd %d\n", size);
    dump_it(buf, size);
    return 0;
}
