예제 #1
0
/*************************************************************************
 *
 * Verify that a packet has a tag containint a specific value
 *
 ************************************************************************/
static int verify_tag(struct session* ses,
		      struct pppoe_packet* p,
		      unsigned short id,
		      char* data,
		      int data_len)
{
    int len;
    struct pppoe_tag *pt = p->tags[id];

    if( !pt ){
	poe_info(ses,"Missing tag %d. Expected %s\n",
		 id,data);
	return 0;
    }
    len = ntohs(pt->tag_len);
    if(len != data_len){
	poe_info(ses,"Length mismatch on tag %d: expect: %d got: %d\n",
		 id, data_len, len);
	return 0;
    }

    if( 0!=memcmp(pt->tag_data,data,data_len)){
	poe_info(ses,"Tag data mismatch on tag %d: expect: %s vs %s\n",
		 id, data,pt->tag_data);
	return 0;
    }
    return 1;
}
예제 #2
0
/*************************************************************************
 *
 * Verify that a packet is legal
 *
 *************************************************************************/
int verify_packet( struct session *ses, struct pppoe_packet *p){
    struct session * hu_val;

    /* This code here should do all of the error checking and
       validation on the incoming packet */


    /* If we receive any error tags, abort */
#define CHECK_TAG(name, val)					\
    if((NULL==p->tags[name])== val){				\
	poe_error(ses,"Tag error: " #name );			\
	return -1;						\
    }


    /* If packet is not directed to our MAC address, forget it */
    if (ses->state == PADS_CODE) {
	    if (memcmp(p->addr.sll_addr, ses->remote.sll_addr, ETH_ALEN)) {
		poe_info(ses,"ETH_DEST mismatch: %E %E \n",p->addr.sll_addr, ses->remote.sll_addr);
		return -1;
	    }
    }

    CHECK_TAG(TAG_SRV_ERR,0);
    CHECK_TAG(TAG_SYS_ERR,0);
    CHECK_TAG(TAG_GEN_ERR,0);

    /* A HOST_UNIQ must be present */
    CHECK_TAG(TAG_HOST_UNIQ,1);

    hu_val = *TAG_DATA(struct session* ,p->tags[TAG_HOST_UNIQ]);

    if( hu_val != ses ){
	poe_info(ses,"HOST_UNIQ mismatch: %08x %i\n",(int)hu_val,getpid());
	return -1;
    }

    if(ses->filt->htag &&
       !verify_tag(ses,p,TAG_HOST_UNIQ,ses->filt->htag->tag_data,(int)ntohs(ses->filt->htag->tag_len))) {
	poe_info(ses,"HOST_UNIQ failure");
	return -1;
    }


    if(ses->filt->ntag && ses->state == PADO_CODE &&
       !verify_tag(ses,p,TAG_AC_NAME,ses->filt->ntag->tag_data,(int)ntohs(ses->filt->ntag->tag_len))){
	poe_info(ses,"AC_NAME failure");
	return -1;
    }

    if(ses->filt->stag &&
       !verify_tag(ses,p,TAG_SRV_NAME,ses->filt->stag->tag_data,(int)ntohs(ses->filt->stag->tag_len))){
	poe_info(ses,"SRV_NAME failure");
	return -1;
    }

    return 0;
}
예제 #3
0
/*************************************************************************
 *
 * Verify that a packet is legal
 *
 *************************************************************************/
int verify_packet( struct session *ses, struct pppoe_packet *p){
    struct session * hu_val;

    /* This code here should do all of the error checking and
       validation on the incoming packet */


    /* If we receive any error tags, abort */
#define CHECK_TAG(name, val)					\
    if((NULL==p->tags[name])== val){				\
	char format[sizeof("Tag error: ") + sizeof (#name) + \
		sizeof("- %.65535s")]; \
	sprintf(format, "Tag error: %s - %%.%ds", #name,\
		p->tags[name]->tag_len);\
	poe_error(ses,format,p->tags[name]->tag_data);\
	return -1;						\
    }

	/* This causes an unaligned access here */
    CHECK_TAG(TAG_SRV_ERR,0);
    CHECK_TAG(TAG_SYS_ERR,0);
    CHECK_TAG(TAG_GEN_ERR,0);

    /* A HOST_UNIQ must be present */
    CHECK_TAG(TAG_HOST_UNIQ,1);

    hu_val = *TAG_DATA(struct session* ,p->tags[TAG_HOST_UNIQ]);

    if( hu_val != ses ){
	poe_info(ses,"HOST_UNIQ mismatch: %08x %i\n",(int)hu_val,getpid());
	return -1;
    }

    if(ses->filt->htag &&
       !verify_tag(ses,p,TAG_HOST_UNIQ,ses->filt->htag->tag_data,(int)ntohs(ses->filt->htag->tag_len))) {
	poe_info(ses, "HOST_NAME failure");
	return -1;
    }

    if(ses->filt->ntag &&
       !verify_tag(ses,p,TAG_AC_NAME,ses->filt->ntag->tag_data,(int)ntohs(ses->filt->ntag->tag_len))){
	poe_info(ses,"AC_NAME failure");
	return -1;
    }

    if(ses->filt->stag &&
       !verify_tag(ses,p,TAG_SRV_NAME,ses->filt->stag->tag_data,(int)ntohs(ses->filt->stag->tag_len))){
	poe_info(ses,"SRV_NAME failure");
	return -1;
    }
	return 1;
}
예제 #4
0
static int connect_pppoe_ses(void)
{
    int i,err=-1;
    if( pppoe_server == 1 ){
	srv_init_ses(ses,devnam);
    }else{
	client_init_ses(ses,devnam);
    }
    strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));

    err= session_connect ( ses );

    if(err < 0){
	poe_fatal(ses,"Failed to negotiate PPPoE connection: %d %m",errno,errno);
    }


    poe_info(ses,"Connecting PPPoE socket: %E %04x %s %p",
	     ses->sp.sa_addr.pppoe.remote,
	     ses->sp.sa_addr.pppoe.sid,
	     ses->sp.sa_addr.pppoe.dev,ses);

    err = connect(ses->fd, (struct sockaddr*)&ses->sp,
		  sizeof(struct sockaddr_pppox));


    if( err < 0 ){
	poe_fatal(ses,"Failed to connect PPPoE socket: %d %m",errno,errno);
	return err;
    }
    /* Once the logging is fixed, print a message here indicating
       connection parameters */

    return ses->fd;
}
예제 #5
0
static void post_disconnect_pppoe_ses(void)
{
	if (access (SESSION_FILE, F_OK) == 0) {
		poe_info(ses, "Remove PPPoE Session file!");
		remove(SESSION_FILE);
	}
}
예제 #6
0
static int std_init_disc(struct session* ses,
			 struct pppoe_packet *p_in,
			 struct pppoe_packet **p_out){
    
    /* Check if already connected */
    if( ses->state != PADO_CODE ){
	return -1;
    }
    
    memset(&ses->curr_pkt,0, sizeof(struct pppoe_packet));

    ses->curr_pkt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
    ses->curr_pkt.hdr->ver  = 1;
    ses->curr_pkt.hdr->type = 1;
    ses->curr_pkt.hdr->code = PADI_CODE;
    
    
    memcpy( &ses->curr_pkt.addr, &ses->remote , sizeof(struct sockaddr_ll));
    
    poe_info (ses,"Sending PADI");
    //if (DEB_DISC)
    //	poe_dbglog (ses,"Sending PADI");
    fprintf(stderr,"Sending PADI\n");
    
    ses->retransmits = 0 ;
    
    if(ses->filt->ntag) {
	ses->curr_pkt.tags[TAG_AC_NAME]=ses->filt->ntag;
	poe_info(ses,"overriding AC name\n");
    }
    
    if(ses->filt->stag)
	ses->curr_pkt.tags[TAG_SRV_NAME]=ses->filt->stag;
    
    if(ses->filt->htag)
	ses->curr_pkt.tags[TAG_HOST_UNIQ]=ses->filt->htag;
    
    ses->retransmits = 0 ;
    
    send_disc(ses, &ses->curr_pkt);
    (*p_out)= &ses->curr_pkt;

    if (DEB_DISC)
	poe_dbglog (ses,"Sent PADI: %P", *p_out);

    return 0;
}
예제 #7
0
/*************************************************************************
 *
 * Verify that a packet is legal
 *
 *************************************************************************/
int verify_packet( struct session *ses, struct pppoe_packet *p){
    struct session * hu_val;

    /* This code here should do all of the error checking and
       validation on the incoming packet */

    /* If we receive any error tags, abort */
#define CHECK_TAG(name, val)					\
    if((NULL==p->tags[name])== val){				\
	poe_error(ses,"Tag error: " #name );			\
	return -1;						\
    }

    CHECK_TAG(TAG_SRV_ERR,0);
    CHECK_TAG(TAG_SYS_ERR,0);
    CHECK_TAG(TAG_GEN_ERR,0);

    /* A HOST_UNIQ must be present */
    CHECK_TAG(TAG_HOST_UNIQ,1);

    hu_val = *TAG_DATA(struct session* ,p->tags[TAG_HOST_UNIQ]);

    if( hu_val != ses ){
	poe_info(ses,"HOST_UNIQ mismatch: %08x %i\n",(int)hu_val,getpid());
	return -1;
    }

    if(ses->filt->htag &&
       !verify_tag(ses,p,TAG_HOST_UNIQ,ses->filt->htag->tag_data,(int)ntohs(ses->filt->htag->tag_len)))
	return -1;
    else
	poe_info(ses,"HOST_UNIQ successful match\n");


    if(ses->filt->ntag &&
       !verify_tag(ses,p,TAG_AC_NAME,ses->filt->ntag->tag_data,(int)ntohs(ses->filt->ntag->tag_len))){
	poe_info(ses,"AC_NAME failure");
	return -1;
    }

    if(ses->filt->stag &&
       !verify_tag(ses,p,TAG_SRV_NAME,ses->filt->stag->tag_data,(int)ntohs(ses->filt->stag->tag_len))){
	poe_info(ses,"SRV_NAME failure");
	return -1;
    }

}
예제 #8
0
파일: pppoe.c 프로젝트: OPSF/uClinux
static int connect_pppoe_ses(void)
{
    int err=-1;
    if( pppoe_server == 1 ){
	srv_init_ses(ses,devnam);
    }else{
	client_init_ses(ses,devnam);
    }
#if 0
    ses->np=1;  /* jamal debug the discovery portion */
#endif
    strcpy(ppp_devnam, devnam);

    err= session_connect ( ses );

    if(err < 0){
	    if (!kill_link)
		poe_error(ses,"Failed to negotiate PPPoE connection: %d - %m",
				errno,errno);
		return -1;
    }

    poe_info(ses,"Connecting PPPoE socket: %E %04x %s %p",
	     ses->sp.sa_addr.pppoe.remote,
	     ses->sp.sa_addr.pppoe.sid,
	     ses->sp.sa_addr.pppoe.dev,ses);

    err = connect(ses->fd, (struct sockaddr*)&ses->sp,
		  sizeof(struct sockaddr_pppox));


    if( err < 0 ){
	poe_fatal(ses,"Failed to connect PPPoE socket: %d %m",errno,errno);
	return err;
    }
#if 0
    if (ses->np)
     	fatal("discovery complete\n");
#endif
    /* Once the logging is fixed, print a message here indicating
       connection parameters */

    return ses->fd;
}
예제 #9
0
static int std_rcv_pads(struct session* ses,
                        struct pppoe_packet *p_in,
                        struct pppoe_packet **p_out){
    if( verify_packet(ses, p_in) < 0)
        return -1;
    
    if (DEB_DISC)
        poe_dbglog (ses,"Got connection: %x",
                    ntohs(p_in->hdr->sid));
    poe_info (ses,"Got connection: %x", ntohs(p_in->hdr->sid));
    
    ses->sp.sa_family = AF_PPPOX;
    ses->sp.sa_protocol = PX_PROTO_OE;
    ses->sp.sa_addr.pppoe.sid = p_in->hdr->sid;
    memcpy(ses->sp.sa_addr.pppoe.dev,ses->name, IFNAMSIZ);
    memcpy(ses->sp.sa_addr.pppoe.remote, p_in->addr.sll_addr, ETH_ALEN);
    
    create_msg(BCM_PPPOE_CLIENT_STATE_CONFIRMED);
    syslog(LOG_CRIT,"PPP session established.\n");

    return 1;
}
예제 #10
0
static void post_connect_pppoe_ses(void)
{
	FILE* sfile;

	/**
	    Save session id here. added by [email protected]
	*/
	sfile = fopen(SESSION_FILE, "w");
	if (sfile) {
		poe_info(ses, "Save PPPoE Session ID & MAC!");
		fprintf(sfile,"%u:%02x:%02x:%02x:%02x:%02x:%02x\n",
			   ntohs(ses->sp.sa_addr.pppoe.sid),
			   ses->sp.sa_addr.pppoe.remote[0],
			   ses->sp.sa_addr.pppoe.remote[1],
			   ses->sp.sa_addr.pppoe.remote[2],
			   ses->sp.sa_addr.pppoe.remote[3],
			   ses->sp.sa_addr.pppoe.remote[4],
			   ses->sp.sa_addr.pppoe.remote[5]);
		fclose(sfile);
	}

}
예제 #11
0
파일: pppoe_relay.c 프로젝트: OPSF/uClinux
static int relay_rcv_pads(struct session* ses,
			  struct pppoe_packet *p_in,
			  struct pppoe_packet **p_out){

    struct pppoe_con *pc;
   // char tag_buf[32];
    struct pppoe_tag *tag = p_in->tags[TAG_RELAY_SID];
    struct sockaddr_pppox sp_cl= { AF_PPPOX, PX_PROTO_OE,
				   {{ p_in->hdr->sid, {0,},{0,}}}};

    struct sockaddr_pppox sp_sv= { AF_PPPOX, PX_PROTO_OE,
				   {{ p_in->hdr->sid, {0,},{0,}}}};

    int ret;


    if( !tag ) return 0;

    pc = get_con(ntohs(tag->tag_len),tag->tag_data);

    if( !pc ) return 0;


    if(!pc->connected){
	
	pc->sv_sock = socket( AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
	if( pc->sv_sock < 0){
	    poe_fatal(ses,"Cannot open PPPoE socket: %i",errno);
	}
	
	pc->cl_sock = socket( AF_PPPOX, SOCK_DGRAM, PX_PROTO_OE);
	if( pc->cl_sock < 0){
	    poe_fatal(ses,"Cannot open PPPoE socket: %i",errno);
	}
	
	memcpy( sp_sv.sa_addr.pppoe.dev, ses->fwd_name, IFNAMSIZ);
	memcpy( sp_sv.sa_addr.pppoe.remote, pc->server, ETH_ALEN);
	
	ret = connect( pc->sv_sock,
		       (struct sockaddr*)&sp_sv,
		       sizeof(struct sockaddr_pppox));
	if( ret < 0){
	    poe_fatal(ses,"Cannot connect PPPoE socket: %i",errno);
	}
	
	memcpy( sp_cl.sa_addr.pppoe.dev, ses->name, IFNAMSIZ);
	memcpy( sp_cl.sa_addr.pppoe.remote, pc->client, ETH_ALEN);
	
	ret = connect( pc->cl_sock,
		       (struct sockaddr*)&sp_cl,
		       sizeof(struct sockaddr_pppox));
	if( ret < 0){
	    poe_fatal(ses,"Cannot connect PPPoE socket: %i",errno);
	}
	
	
	ret = ioctl( pc->sv_sock, PPPOEIOCSFWD, &sp_cl);
	if( ret < 0){
	    poe_fatal(ses,"Cannot set forwarding on PPPoE socket: %i",errno);
	}
	
	ret = ioctl( pc->cl_sock, PPPOEIOCSFWD, &sp_sv);
	if( ret < 0){
	    poe_fatal(ses,"Cannot set forwarding on PPPoE socket: %i",errno);
	}
	
	pc->connected = 1;
    }

    poe_info(ses,"PPPoE relay for %E established to %E (sid=%04x)\n",
	     pc->client,pc->server, p_in->hdr->sid);

    return relay_rcv_pkt(ses,p_in,p_out);
}
예제 #12
0
/*************************************************************************
 *
 * Make a connection -- behaviour depends on callbacks specified in "ses"
 *
 *************************************************************************/
int session_connect(struct session *ses)
{

    struct pppoe_packet *p_out=NULL;
    struct pppoe_packet rcv_packet;
    int ret;


    if(ses->init_disc){
	ret = (*ses->init_disc)(ses, NULL, &p_out);
	if( ret != 0 ) return ret;
    }

    /* main discovery loop */


    while(ses->retransmits <= ses->retries || ses->retries==-1 ){

		fd_set in;
		struct timeval tv;
		FD_ZERO(&in);

		FD_SET(disc_sock,&in);

		if(ses->retransmits>=0){
			++ses->retransmits;
			tv.tv_sec = 1 << ses->retransmits;
			tv.tv_usec = 0;
			ret = select(disc_sock+1, &in, NULL, NULL, &tv);
		}else{
			ret = select(disc_sock+1, &in, NULL, NULL, NULL);
		}

		if( ret == 0 ){
			if((DEB_DISC) && (ses->retransmits <= ses->retries) ){
				poe_dbglog(ses, "Re-sending ...");
			}

			if( ses->timeout ){
				ret = (*ses->timeout)(ses, NULL, &p_out);
				if ( ret != 0 ) {
					poe_info(ses, "returning - %d", ret);
					return ret;
				}

			} else if (p_out) {
				send_disc(ses,p_out);
			}
			continue;
		} 

		ret = recv_disc(ses, &rcv_packet);

		/* Should differentiate between system errors and
		   bad packets and the like... */
		if( ret < 0 && errno != EINTR){

			poe_info(ses, "couldn't rcv packet");
			return -1;
		}

		if (DEB_DISC2)
			syslog(LOG_ERR, "Recieved packet=%x\n", rcv_packet.hdr->code);

		switch (rcv_packet.hdr->code) {

		case PADI_CODE:
		{
			if(ses->rcv_padi){
			ret = (*ses->rcv_padi)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}
			break;
		}

		case PADO_CODE:		/* wait for PADO */
		{
			if(ses->rcv_pado){
			ret = (*ses->rcv_pado)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}
			break;
		}

		case PADR_CODE:
		{
			if(ses->rcv_padr){
			ret = (*ses->rcv_padr)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}
			break;
		}

		case PADS_CODE:
		{
			if(ses->rcv_pads){
			ret = (*ses->rcv_pads)(ses,&rcv_packet,&p_out);

			if( ret != 0){


				return ret;
			}
			}
			break;
		}

		case PADT_CODE:
		{
			if( rcv_packet.hdr->sid != ses->sp.sa_addr.pppoe.sid ){
			--ses->retransmits;
			continue;
			}
			if(ses->rcv_padt){
			ret = (*ses->rcv_padt)(ses,&rcv_packet,&p_out);

			if( ret != 0){
				return ret;
			}
			}else{
			poe_error (ses,"connection terminated");
			return (-1);
			}
			break;
		}
		case 0:      /*receiving normal seesion frames*/
		{
			poe_error(ses, "Already in data stream, sending PADT %P\n",
				&rcv_packet);
			if (ses->pppoe_kill) {
				memcpy(&ses->remote,&rcv_packet.addr,
				sizeof(struct sockaddr_ll));
				ses->sp.sa_addr.pppoe.sid = rcv_packet.hdr->sid;
				session_disconnect(ses);
				continue;
			}
			return (-1);
		}
		default:
			poe_error(ses,"invalid packet %P",&rcv_packet);
			return (-1);
		}
    }

	if (ses->retransmits > ses->retries) {
	    	errno = 62;
		return -1;
	}

    return (0);
}
예제 #13
0
파일: pppoe.c 프로젝트: OPSF/uClinux
static void init_device_pppoe(void)
{
    struct filter *filt;
    unsigned int size=0;
    ses=(void *)malloc(sizeof(struct session));
    if(!ses){
	fatal("No memory for new PPPoE session");
    }
    memset(ses,0,sizeof(struct session));
    ses->log_to_fd = -1;

    if ((ses->filt=malloc(sizeof(struct filter))) == NULL) {
	poe_error (ses,"failed to malloc for Filter ");
	poe_die (-1);
    }

    filt=ses->filt;  /* makes the code more readable */
    memset(filt,0,sizeof(struct filter));

    if (pppoe_ac_name !=NULL) {
	if (strlen (pppoe_ac_name) > 255) {
	    poe_error (ses," AC name too long (maximum allowed 256 chars)");
	    poe_die(-1);
	}
	ses->filt->ntag = make_filter_tag(PTT_AC_NAME,
					  strlen(pppoe_ac_name),
					  pppoe_ac_name);

	if ( ses->filt->ntag== NULL) {
	    poe_error (ses,"failed to malloc for AC name");
	    poe_die(-1);
	}

    }


    if (pppoe_srv_name !=NULL) {
	if (strlen (pppoe_srv_name) > 255) {
	    poe_error (ses," Service name too long (maximum allowed 256 chars)");
	    poe_die(-1);
	}
	ses->filt->stag = make_filter_tag(PTT_SRV_NAME,
					  strlen(pppoe_srv_name),
					  pppoe_srv_name);
	if ( ses->filt->stag == NULL) {
	    poe_error (ses,"failed to malloc for service name");
	    poe_die(-1);
	}
    }

    if (hostuniq) {
	ses->filt->htag = make_filter_tag(PTT_HOST_UNIQ,
					  strlen(hostuniq),
					  hostuniq);
	if ( ses->filt->htag == NULL) {
	    poe_error (ses,"failed to malloc for Uniq Host Id ");
	    poe_die(-1);
	}
    }

    if (retries > 0) {
	ses->retries=retries;
	poe_info(ses, "PPPOE: Setting retries to %d", ses->retries);
    } else if (retries == 0) {
	poe_info(ses, "PPPOE: Will retry forever");
	ses->retries=-1;
    } else {
	ses->retries=CONFIG_USER_PPPD_PPPOE_RETRIES;
	poe_info(ses, "PPPOE: Setting retries to %d", ses->retries);
    }

    if (pppoe_kill) {
	ses->pppoe_kill = pppoe_kill;
	poe_info(ses, "Will send PADT if already in data stream");
    }

    memcpy( ses->name, devnam, IFNAMSIZ);
    ses->opt_debug=1;

}
예제 #14
0
/**
	add by [email protected]
	call it before do connection
*/
static void pre_connect_pppoe_ses(void)
{
	//add by [email protected]
	unsigned int mac[6];
	unsigned int sID;
	FILE* sfile;
	int n;
	
	//disconnect before. added by [email protected]
	if (access (SESSION_FILE, F_OK) != 0) {
		return;
	}
	
    client_init_ses(ses,devnam);

    strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam));
	
	sfile = fopen(SESSION_FILE, "r");
	n = fscanf(sfile, "%u:%2x:%2x:%2x:%2x:%2x:%2x",
	       &sID, &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
	fclose(sfile);
	
	if (n < 7) {
		poe_info(ses, "Read PPPoE Session error!");
		return;
	}

    struct pppoe_packet padt;

	memset(&padt, 0, sizeof(struct pppoe_packet));
		
	ses->remote.sll_addr[0] = mac[0];
	ses->remote.sll_addr[1] = mac[1];
	ses->remote.sll_addr[2] = mac[2];
	ses->remote.sll_addr[3] = mac[3];
	ses->remote.sll_addr[4] = mac[4];
	ses->remote.sll_addr[5] = mac[5];
	memcpy(&padt.addr, &ses->remote, sizeof(struct sockaddr_ll));

	padt.hdr = (struct pppoe_hdr*) ses->curr_pkt.buf;
	padt.hdr->ver  = 1;
	padt.hdr->type = 1;
	padt.hdr->code = PADT_CODE;
	padt.hdr->sid  = htons(sID);


    send_disc(ses, &padt);
    ses->sp.sa_addr.pppoe.sid = 0;
	
    connect(ses->fd, (struct sockaddr*)&ses->sp,
	sizeof(struct sockaddr_pppox));
	usleep(2000000);
/**	
    int ret;
    warn("Doing pre-disconnect");
    session_disconnect(ses);
    ses->sp.sa_addr.pppoe.sid = 0;
    ret = connect(ses->fd, (struct sockaddr*)&ses->sp,
	    sizeof(struct sockaddr_pppox));
*/
}
예제 #15
0
int main(int argc, char** argv){
    int ret;
    struct filter *filt;
    struct session *ses = (struct session *)malloc(sizeof(struct session));
    char buf[256];
    ses=(void *)malloc(sizeof(struct session));
    
    if(!ses){
	return -1;
    }
    memset(ses,0,sizeof(struct session));
    
    
    
    openlog ("pppoed", LOG_PID | LOG_NDELAY, LOG_PPPOE);
    setlogmask (LOG_UPTO (ses->opt_debug ? LOG_DEBUG : LOG_INFO));
    
    
    if ((get_args (argc,(char **) argv,ses)) <1)
        poe_die(-1);
    
    filt=ses->filt;  /* makes the code more readable */
    
    if (!ses->np) {
	poe_create_pidfile (ses);
//	signal (SIGINT, &sigproc);
//	signal (SIGTERM, &sigproc);
	signal (SIGCHLD, &sigchild);
    }
    
    if(ses->type == SESSION_CLIENT){

	poe_info(ses,"calling client_init_ses\n");
	ret = client_init_ses(ses,ses->name);
    
	if( ret < 0 ){
	    return -1;
	}

	while (ses->filt->num_restart > 0)
	{
	    poe_info(ses,"Restart number %d ",ses->filt->num_restart);
	    ppp_connect (ses);
	    ses->filt->num_restart--;
	}

    }else if( ses->type == SESSION_SERVER ){

	poe_info(ses,"calling srv_init_ses\n");
	ret = srv_init_ses(ses,ses->name);

	if( ret < 0 ){
	    return -1;
	}

	ret = 1;
	while(ret>=0)
	    ret = ppp_connect(ses);
    
    }

    
    
    
    poe_info(ses,"ppp_connect came back! %d",ret);
    
    exit(0);
    
}
예제 #16
0
int 
get_args (int argc, char **argv,struct session *sess)
{
    struct filter *filt;
    struct host_tag *tg;
    int opt;
    

    sess->opt_debug = 0;
    DEB_DISC=0;
    DEB_DISC2=0;
    sess->log_to_fd = 1;
    sess->np = 0;
    sess->opt_daemonize = 0;
    
    sess->log_to_fd = fileno (stdout);
    
/* defaults to eth0 */
    strcpy (sess->name, "eth0");
    
    
    if ((sess->filt=malloc(sizeof(struct filter))) == NULL) {
        poe_error (sess,"failed to malloc for Filter ");
        poe_die (-1);
    }
    
    filt=sess->filt;  /* makes the code more readable */
    memset(filt,0,sizeof(struct filter));
    
    filt->num_restart=1;
    
/* set default filters; move this to routine */
    /* parse options */
    
    while ((opt = getopt (argc, argv, "A:C:E:d:DR:I:F:L:V:P:SN:GH")) != -1)
	
	switch (opt) {
	case 'R':			/* sets number of retries */
	    filt->num_restart = strtol (optarg, (char **) NULL, 10);
	    filt->num_restart += 1;
	    break;
	case 'I':			/* sets interface */
	    if (strlen (optarg) >= IFNAMSIZ) {
		poe_error (sess,"interface name cannot exceed %d characters", IFNAMSIZ - 1);
		return (-1);
	    }
	    strncpy (sess->name, optarg, strlen(optarg)+1);
	    break;
	case 'C':			/* name of the file in /etc/ppp/peers */
	    if (NULL != filt->fname) {
		poe_error (sess,"-F can not be used with -C");
		return (-1);
	    }
	    if (strlen(optarg) > MAX_FNAME) {
		poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
		return (-1);
	    }
	    filt->fname=malloc(strlen(optarg));
	    strncpy (filt->fname, optarg, strlen(optarg));
	    filt->peermode=1;
	    break;
	case 'F':			/* sets the options file */
	    if (NULL != filt->fname) {
		poe_error (sess,"-F can not be used with -C");
		return (-1);
	    }
	    
	    if (strlen(optarg) > MAX_FNAME) {
		poe_error (sess,"file name cannot exceed %d characters", MAX_FNAME - 1);
		return (-1);
	    }
	    filt->fname=malloc(strlen(optarg)+1);
	    strncpy (filt->fname, optarg, strlen(optarg)+1);
	    
	    poe_info (sess,"selected %s as filename\n",filt->fname);
	    break;
	case 'D':			/* don't daemonize */
	    sess->opt_daemonize = 1;
	    detached=0;
	    break;
	case 'd':			/* debug level */
	    sess->opt_debug = strtol (optarg, (char **) NULL, 10);
	    if (sess->opt_debug & 0x0002)
		DEB_DISC=1;
	    if (sess->opt_debug & 0x0004)
		DEB_DISC2=1;
	    break;
	case 'P':			/* sets the pppd binary */
	    if (strlen(optarg) > MAX_FNAME) {
		poe_error (sess,"pppd binary cant exceed %d characters", MAX_FNAME - 1);
		return (-1);
	    }
	    filt->pppd=malloc(strlen(optarg));
	    strncpy (filt->pppd, optarg, strlen(optarg));
	    break;
	case 'H':			
	    sess->np = 2;
	    break;
	case 'G':			
	    sess->np = 1;
	    break;
	case 'V':			/* version */
	    fprintf (stdout,"pppoe version %d.%d build %d", VERSION_MAJOR,
		     VERSION_MINOR, VERSION_DATE);
	    return (0);
	case 'S':			/* server mode */
	    sess->type = SESSION_SERVER;
	    break;
	case 'A':			/* AC override */
	    poe_info (sess,"AC name override to %s", optarg);
	    if (strlen (optarg) > 255) {
		poe_error (sess," AC name too long (maximum allowed 256 chars)");
		poe_die(-1);
	    }
	    if ((sess->filt->ntag= malloc (sizeof (struct pppoe_tag) +
					   strlen (optarg)))== NULL) {
		poe_error (sess,"failed to malloc for AC name");
		poe_die(-1);
	    }
	    sess->filt->ntag->tag_len=htons(strlen(optarg));
	    sess->filt->ntag->tag_type=PTT_AC_NAME;
	    poe_error (sess," pppoe_ac_name: AC name Override %p\n",
		       sess->filt->ntag);
	    strcpy(sess->filt->ntag->tag_data,optarg);
	    break;
	case 'E':			/* AC service name override */
	    poe_info (sess,"AC service name override to %s", optarg);
	    if (strlen (optarg) > 255) {
		poe_error (sess," Service name too long (maximum allowed 256 chars)");
		poe_die(-1);
	    }
	    
	    if ((filt->stag = malloc (strlen (optarg) + sizeof (struct pppoe_tag))) == NULL) {
		poe_error (sess,"failed to malloc for service name: %m");
		return (-1);
	    }
	    
	    filt->stag->tag_len = htons (strlen (optarg));
	    filt->stag->tag_type = PTT_SRV_NAME;
	    strcpy ((char *) (filt->stag->tag_data), optarg);
	    break;
	default:
	    poe_error (sess,"Unknown option '%c'", optopt);
	    print_help ();
	    return (-1);
	}
    
    
    return (1);
    
}
예제 #17
0
파일: pppoe_client.c 프로젝트: OPSF/uClinux
int client_init_ses (struct session *ses, char* devnam)
{
    int i=0;
    int retval;
    char dev[IFNAMSIZ+1];
    int addr[ETH_ALEN];
    int sid;
    
    /* do error checks here; session name etc are valid */
//    poe_info (ses,"init_ses: creating socket");
    
    /* Make socket if necessary */
    if( disc_sock < 0 ){
	
	disc_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
	if( disc_sock < 0 ){
	    poe_fatal(ses,
		      "Cannot create PF_PACKET socket for PPPoE discovery\n");
	}
	
    }
    
    /* Create socket for session frame detection */
    if (ses_sock < 0) {
	ses_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
	if (ses_sock < 0) {
	    poe_info(ses, "Couldn't create session frame detection socket");
      } 
    }
    
    /* Check for long format */
    retval =sscanf(devnam, FMTSTRING(IFNAMSIZ),addr, addr+1, addr+2,
		   addr+3, addr+4, addr+5,&sid,dev);
    if( retval != 8 ){
	/* Verify the device name , construct ses->local */
	retval = get_sockaddr_ll(devnam,&ses->local,0);
	if (retval < 0)
	    poe_fatal(ses, "client_init_ses: "
		      "Cannot create PF_PACKET socket for PPPoE discovery\n");
	
	
	ses->state = PADO_CODE;
	memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
	
	memset( ses->remote.sll_addr, 0xff, ETH_ALEN);
    }else{
	/* long form parsed */

	/* Verify the device name , construct ses->local */
	retval = get_sockaddr_ll(dev,&ses->local,0);
	if (retval < 0)
	    poe_fatal(ses,"client_init_ses(2): "
		      "Cannot create PF_PACKET socket for PPPoE discovery\n");
	ses->state = PADS_CODE;
	ses->sp.sa_family = AF_PPPOX;
	ses->sp.sa_protocol = PX_PROTO_OE;
	ses->sp.sa_addr.pppoe.sid = sid;
	
	memcpy(&ses->remote, &ses->local, sizeof(struct sockaddr_ll) );
	
	for(; i < ETH_ALEN ; ++i ){
	    ses->sp.sa_addr.pppoe.remote[i] = addr[i];
	    ses->remote.sll_addr[i]=addr[i];
	}
	memcpy(ses->sp.sa_addr.pppoe.dev, dev, IFNAMSIZ);
	
	
	
    }
    if( retval < 0 )
	error("bad device name: %s",devnam);
    
    
    retval = bind( disc_sock ,
		   (struct sockaddr*)&ses->local,
		   sizeof(struct sockaddr_ll));
    
    
    if( retval < 0 ){
	error("bind to PF_PACKET socket failed: %m");
    }

    ses->local.sll_protocol = ntohs(ETH_P_PPP_SES);
    
    retval = bind(ses_sock,
		    (struct sockaddr *)&ses->local,
		    sizeof(struct sockaddr_ll));
    if (retval < 0) {
    	poe_info(ses, "Couldn't bind session frame detection socket");
    }

    ses->local.sll_protocol = ntohs(ETH_P_PPP_DISC);

    ses->fd = socket(AF_PPPOX,SOCK_STREAM,PX_PROTO_OE);
    if(ses->fd < 0)
    {
	poe_fatal(ses,"Failed to create PPPoE socket: %m");
    }
    
    
    ses->init_disc = std_init_disc;
    ses->rcv_pado  = std_rcv_pado;
    ses->rcv_pads  = std_rcv_pads;
    ses->rcv_padt  = std_rcv_padt;
    
    return ses->fd;
}