コード例 #1
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
void dlbindack(int fd, char *bufp)
{
        union   DL_primitives   *dlp;
        struct  strbuf  ctl;
        int     flags;

        ctl.maxlen = MAXDLBUF;
        ctl.len = 0;
        ctl.buf = bufp;

        strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack");

        dlp = (union DL_primitives *) ctl.buf;

        expecting(DL_BIND_ACK, dlp);

        if (flags != RS_HIPRI)
                rp_fatal("dlbindack:  DL_OK_ACK was not M_PCPROTO");

        if (ctl.len < sizeof (dl_bind_ack_t)) {
		char buffer[256];
		sprintf(buffer, "dlbindack:  short response ctl.len:  %d", ctl.len);
		rp_fatal(buffer); 
	}
}
コード例 #2
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
/**********************************************************************
*%FUNCTION: openInterface
*%ARGUMENTS:
* ifname -- name of interface
* type -- Ethernet frame type
* hwaddr -- if non-NULL, set to the hardware address
*%RETURNS:
* A raw socket for talking to the Ethernet card.  Exits on error.
*%DESCRIPTION:
* Opens a raw Ethernet socket
***********************************************************************/
int
openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr)
{
    int fd;
    long buf[MAXDLBUF]; 

	union   DL_primitives   *dlp;

    char base_dev[PATH_MAX]; 
    int ppa; 

    if(strlen(ifname) > PATH_MAX) {
	rp_fatal("socket: string to long"); 
    }

    ppa = atoi(&ifname[strlen(ifname)-1]);
    strncpy(base_dev, ifname, PATH_MAX); 
    base_dev[strlen(base_dev)-1] = '\0'; 

/* rearranged order of DLPI code - delphys 20010803 */
    dlp = (union DL_primitives*) buf;

    if (( fd = open(base_dev, O_RDWR)) < 0) {
	/* Give a more helpful message for the common error case */
	if (errno == EPERM) {
	    rp_fatal("Cannot create raw socket -- pppoe must be run as root.");
	}
	fatalSys("socket");
    }

/* rearranged order of DLPI code - delphys 20010803 */
    dlattachreq(fd, ppa); 
    dlokack(fd, (char *)buf);

    dlbindreq(fd, type, 0, DL_CLDLS, 0, 0);
    dlbindack(fd, (char *)buf);

    dlinforeq(fd);
    dlinfoack(fd, (char *)buf);

    dl_abssaplen = ABS(dlp->info_ack.dl_sap_length);
    dl_saplen = dlp->info_ack.dl_sap_length;
    if (ETHERADDRL != (dlp->info_ack.dl_addr_length - dl_abssaplen))
	fatalSys("invalid destination physical address length");
    dl_addrlen = dl_abssaplen + ETHERADDRL;

/* ethernet address retrieved as part of DL_INFO_ACK - delphys 20010803 */
    memcpy(hwaddr, (u_char*)((char*)(dlp) + (int)(dlp->info_ack.dl_addr_offset)), ETHERADDRL);

    if ( strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0 ) { 
	fatalSys("DLIOCRAW"); 
    }

    if (ioctl(fd, I_FLUSH, FLUSHR) < 0) fatalSys("I_FLUSH");

    return fd;
}
コード例 #3
0
/**********************************************************************
*%FUNCTION: initRelay
*%ARGUMENTS:
* nsess -- maximum allowable number of sessions
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Initializes relay hash table and session tables.
***********************************************************************/
void
initRelay(int nsess)
{
    int i;
    NumSessions = 0;
    MaxSessions = nsess;

    AllSessions = calloc(MaxSessions, sizeof(PPPoESession));
    if (!AllSessions) {
	rp_fatal("Unable to allocate memory for PPPoE session table");
    }
    AllHashes = calloc(MaxSessions*2, sizeof(SessionHash));
    if (!AllHashes) {
	rp_fatal("Unable to allocate memory for PPPoE hash table");
    }

    /* Initialize sessions in a linked list */
    AllSessions[0].prev = NULL;
    if (MaxSessions > 1) {
	AllSessions[0].next = &AllSessions[1];
    } else {
	AllSessions[0].next = NULL;
    }
    for (i=1; i<MaxSessions-1; i++) {
	AllSessions[i].prev = &AllSessions[i-1];
	AllSessions[i].next = &AllSessions[i+1];
    }
    if (MaxSessions > 1) {
	AllSessions[MaxSessions-1].prev = &AllSessions[MaxSessions-2];
	AllSessions[MaxSessions-1].next = NULL;
    }

    FreeSessions = AllSessions;
    ActiveSessions = NULL;

    /* Initialize session numbers which we hand out */
    for (i=0; i<MaxSessions; i++) {
	AllSessions[i].sesNum = htons((UINT16_t) i+1);
    }

    /* Initialize hashes in a linked list */
    AllHashes[0].prev = NULL;
    AllHashes[0].next = &AllHashes[1];
    for (i=1; i<2*MaxSessions-1; i++) {
	AllHashes[i].prev = &AllHashes[i-1];
	AllHashes[i].next = &AllHashes[i+1];
    }
    AllHashes[2*MaxSessions-1].prev = &AllHashes[2*MaxSessions-2];
    AllHashes[2*MaxSessions-1].next = NULL;

    FreeHashes = AllHashes;
}
コード例 #4
0
ファイル: if.c プロジェクト: vilpalu/GPL_2.6.31
/***********************************************************************
*%FUNCTION: sendPacket
*%ARGUMENTS:
* sock -- socket to send to
* pkt -- the packet to transmit
* size -- size of packet (in bytes)
*%RETURNS:
* 0 on success; -1 on failure
*%DESCRIPTION:
* Transmits a packet
***********************************************************************/
int
sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size)
{
#if defined(USE_BPF)
    if (write(sock, pkt, size) < 0) {
	sysErr("write (sendPacket)");
	return -1;
    }
#elif defined(HAVE_STRUCT_SOCKADDR_LL)
    if (send(sock, pkt, size, 0) < 0) {
	sysErr("send (sendPacket)");
	return -1;
    }
#else

    struct sockaddr sa;

    if (!conn) {
	rp_fatal("relay and server not supported on Linux 2.0 kernels");
    }
    strcpy(sa.sa_data, conn->ifName);
    if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) {
	sysErr("sendto (sendPacket)");
	return -1;
    }

#endif
    return 0;
}
コード例 #5
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
/**********************************************************************
*%FUNCTION: getHWaddr
*%ARGUMENTS:
* ifname -- name of interface
* hwaddr -- buffer for ehthernet address
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Locates the Ethernet hardware address for an interface.
***********************************************************************/
void
getHWaddr(int sock, char const *ifname, unsigned char *hwaddr)
{
    char inbuf[8192];
    const struct sockaddr_dl *sdl;
    struct ifconf ifc;
    struct ifreq ifreq, *ifr;
    int i;
    int found = 0;

    ifc.ifc_len = sizeof(inbuf);
    ifc.ifc_buf = inbuf;
    if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
	fatalSys("SIOCGIFCONF");
    }
    ifr = ifc.ifc_req;
    ifreq.ifr_name[0] = '\0';
    for (i = 0; i < ifc.ifc_len; ) {
	ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i);
	i += sizeof(ifr->ifr_name) +
		    (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)
		    ? ifr->ifr_addr.sa_len
		    : sizeof(struct sockaddr));
	if (ifr->ifr_addr.sa_family == AF_LINK) {
	    sdl = (const struct sockaddr_dl *) &ifr->ifr_addr;
	    if ((sdl->sdl_type == IFT_ETHER) &&
	        (sdl->sdl_alen == ETH_ALEN) &&
		!strncmp(ifname, ifr->ifr_name, sizeof(ifr->ifr_name))) {
		if (found) {
		    char buffer[256];
		    sprintf(buffer, "interface %.16s has more than one ethernet address", ifname);
		    rp_fatal(buffer);
		} else {
		    found = 1;
	            memcpy(hwaddr, LLADDR(sdl), ETH_ALEN);
		}
	    }
	}
    }
    if (!found) {
	char buffer[256];
        sprintf(buffer, "interface %.16s has no ethernet address", ifname);
	rp_fatal(buffer);
    }
    test_func();
}
コード例 #6
0
ファイル: if.c プロジェクト: qtekfun/htcDesire820Kernel
void strgetmsg(int fd, struct strbuf *ctlp, struct strbuf *datap, int *flagsp, char *caller)
{
	int     rc;
	static  char    errmsg[80];

	(void) signal(SIGALRM, sigalrm);
	if (alarm(MAXWAIT) < 0) {
		(void) sprintf(errmsg, "%s:  alarm", caller);
		fatalSys(errmsg);
	}

	*flagsp = 0;
	if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {
		(void) sprintf(errmsg, "%s:  getmsg", caller);
		fatalSys(errmsg);
	}

	if (alarm(0) < 0) {
		(void) sprintf(errmsg, "%s:  alarm", caller);
		fatalSys(errmsg);
	}

	if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) {
		char buffer[256];
		sprintf(buffer, "%s:  MORECTL|MOREDATA", caller);
		rp_fatal(buffer);
	}

	if (rc & MORECTL) {
		char buffer[256];
		sprintf(buffer, "%s:  MORECTL", caller);
		rp_fatal(buffer);
	}

	if (rc & MOREDATA) {
		char buffer[256];
		sprintf(buffer, "%s:  MOREDATA", caller);
		rp_fatal(buffer);
	}

	if (ctlp->len < sizeof (long)) {
		char buffer[256];
		sprintf(buffer, "getmsg:  control portion length < sizeof (long):  %d", ctlp->len);
		rp_fatal(buffer);
	}
}
コード例 #7
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
void expecting(int prim, union DL_primitives *dlp)
{
        if (dlp->dl_primitive != (u_long)prim) {
		char buffer[256]; 
		sprintf(buffer, "expected %s got %s", dlprim(prim), dlprim(dlp->dl_primitive));
		rp_fatal(buffer); 
		exit(1); 
	}
}
コード例 #8
0
ファイル: discovery.c プロジェクト: Einheri/wl500g
/**********************************************************************
*%FUNCTION: discovery
*%ARGUMENTS:
* conn -- PPPoE connection info structure
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Performs the PPPoE discovery phase
***********************************************************************/
void
discovery(PPPoEConnection *conn)
{
    int padiAttempts;
    int padrAttempts;
    int timeout = conn->discoveryTimeout;

    /* Skip discovery? */
    if (conn->skipDiscovery) {
	conn->discoveryState = STATE_SESSION;
	if (conn->killSession) {
	    sendPADT(conn, "RP-PPPoE: Session killed manually");
	    exit(0);
	}
	return;
    }

  SEND_PADI:
    padiAttempts = 0;
    do {
#ifdef PLUGIN
	if (got_sigterm || got_sighup) return;
#endif
	padiAttempts++;
	if (padiAttempts > MAX_PADI_ATTEMPTS) {
	    if (persist) {
		padiAttempts = 0;
		timeout = conn->discoveryTimeout;
		printErr("Timeout waiting for PADO packets");
	    } else {
#ifdef PLUGIN
		printErr("Timeout waiting for PADO packets");
		return;
#else
		rp_fatal("Timeout waiting for PADO packets");
#endif
	    }
	}
	sendPADI(conn);
	conn->discoveryState = STATE_SENT_PADI;
	waitForPADO(conn, timeout);

	/* If we're just probing for access concentrators, don't do
	   exponential backoff.  This reduces the time for an unsuccessful
	   probe to 15 seconds. */
	if (!conn->printACNames) {
	    timeout *= 2;
	}
	if (conn->printACNames && conn->numPADOs) {
	    break;
	}
    } while (conn->discoveryState == STATE_SENT_PADI);

    /* If we're only printing access concentrator names, we're done */
    if (conn->printACNames) {
	exit(0);
    }

    timeout = conn->discoveryTimeout;
    padrAttempts = 0;
    do {
#ifdef PLUGIN
	if (got_sigterm || got_sighup) return;
#endif
	padrAttempts++;
	if (padrAttempts > MAX_PADI_ATTEMPTS) {
	    if (persist) {
		padrAttempts = 0;
		timeout = conn->discoveryTimeout;
		printErr("Timeout waiting for PADS packets");
		/* Go back to sending PADI again */
		goto SEND_PADI;
	    } else {
#ifdef PLUGIN
		printErr("Timeout waiting for PADS packets");
		return;
#else
		rp_fatal("Timeout waiting for PADS packets");
#endif
	    }
	}
	sendPADR(conn);
	conn->discoveryState = STATE_SENT_PADR;
	waitForPADS(conn, timeout);
	timeout *= 2;
    } while (conn->discoveryState == STATE_SENT_PADR);

#ifdef PLUGIN
    if (!conn->seenMaxPayload) {
	/* RFC 4638: MUST limit MTU/MRU to 1492 */
	if (lcp_allowoptions[0].mru > ETH_PPPOE_MTU) lcp_allowoptions[0].mru = ETH_PPPOE_MTU;
	if (lcp_wantoptions[0].mru > ETH_PPPOE_MTU)  lcp_wantoptions[0].mru = ETH_PPPOE_MTU;
    }
#endif
    /* We're done. */
    conn->discoveryState = STATE_SESSION;
    return;
}
コード例 #9
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
void strgetmsg(int fd, struct strbuf *ctlp, struct strbuf *datap, int *flagsp, char *caller)
{
        int     rc;
        static  char    errmsg[80];

        /*
         * Start timer.
         */
        (void) signal(SIGALRM, sigalrm);
        if (alarm(MAXWAIT) < 0) {
                (void) sprintf(errmsg, "%s:  alarm", caller);
                fatalSys(errmsg);
        }

        /*
         * Set flags argument and issue getmsg().
         */
        *flagsp = 0;
        if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {
                (void) sprintf(errmsg, "%s:  getmsg", caller);
                fatalSys(errmsg);
        }

        /*
         * Stop timer.
         */
        if (alarm(0) < 0) {
                (void) sprintf(errmsg, "%s:  alarm", caller);
                fatalSys(errmsg);
        }

        /*
         * Check for MOREDATA and/or MORECTL.
         */
        if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) {
		char buffer[256]; 
		sprintf(buffer, "%s:  MORECTL|MOREDATA", caller);
		rp_fatal(buffer);
	}
                
        if (rc & MORECTL) {
		char buffer[256];
		sprintf(buffer, "%s:  MORECTL", caller);
		rp_fatal(buffer); 
	}
        
        if (rc & MOREDATA) {
		char buffer[256]; 
		sprintf(buffer, "%s:  MOREDATA", caller);
		rp_fatal(buffer);
	}

        /*
         * Check for at least sizeof (long) control data portion.
         */
        if (ctlp->len < sizeof (long)) {
		char buffer[256]; 
		sprintf(buffer, "getmsg:  control portion length < sizeof (long):  %d", ctlp->len);
		rp_fatal(buffer); 
	}
}
コード例 #10
0
ファイル: discovery.c プロジェクト: froggatt/edimax-br-6528n
/**********************************************************************
*%FUNCTION: discovery
*%ARGUMENTS:
* conn -- PPPoE connection info structure
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Performs the PPPoE discovery phase
***********************************************************************/
void
discovery(PPPoEConnection *conn)
{
    int padiAttempts = 0;
    int padrAttempts = 0;
    int timeout = PADI_TIMEOUT;

    /* Skip discovery and don't open discovery socket? */
    if (conn->skipDiscovery && conn->noDiscoverySocket) {
	conn->discoveryState = STATE_SESSION;
	return;
    }

    conn->discoverySocket =
	openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth);

    /* Skip discovery? */
    if (conn->skipDiscovery) {
	conn->discoveryState = STATE_SESSION;
	if (conn->killSession) {
	    sendPADT(conn, "RP-PPPoE: Session killed manually");
	    exit(0);
	}
	return;
    }

    do {
	padiAttempts++;
	if (padiAttempts > MAX_PADI_ATTEMPTS) {
		system("rm /etc/ppp/connectfile");
	    rp_fatal("Timeout waiting for PADO packets0");
	}
	sendPADI(conn);
	conn->discoveryState = STATE_SENT_PADI;
	waitForPADO(conn, timeout);


#if 0 // RexHua to Reduce connect time
        /* If we're just probing for access concentrators, don't do
           exponential backoff.  This reduces the time for an unsuccessful
           probe to 15 seconds. */
        if (!conn->printACNames) {
            timeout *= 2;
        }
#endif


	if (conn->printACNames && conn->numPADOs) {
	    break;
	}
    } while (conn->discoveryState == STATE_SENT_PADI);

    /* If we're only printing access concentrator names, we're done */
    if (conn->printACNames) {
	printf("--------------------------------------------------\n");
	exit(0);
    }

    timeout = PADI_TIMEOUT;
    do {
	padrAttempts++;
	if (padrAttempts > MAX_PADI_ATTEMPTS) {
	    rp_fatal("Timeout waiting for PADS packets");
	}
	sendPADR(conn);
	conn->discoveryState = STATE_SENT_PADR;
	waitForPADS(conn, timeout);
#if 0 // RexHua to Reduce connect time
        timeout *= 2;
#endif
    } while (conn->discoveryState == STATE_SENT_PADR);

    /* We're done. */
    conn->discoveryState = STATE_SESSION;
    return;
}
コード例 #11
0
ファイル: if.c プロジェクト: qtekfun/htcDesire820Kernel
int
openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr)
{
    static int fd = -1;
    char bpfName[32];
    u_int optval;
    struct bpf_version bpf_ver;
    struct ifreq ifr;
    int sock;
    int i;

    
    if (fd >= 0) {
	return fd;
    }

    
    for (i = 0; i < 256; i++) {
	sprintf(bpfName, "/dev/bpf%d", i);
	if (((fd = open(bpfName, O_RDWR, 0)) >= 0) ||
	    (errno != EBUSY)) {
	    break;
	}
    }
    if (fd < 0) {
	switch (errno) {
	case EACCES:		
	    {
		char buffer[256];
		sprintf(buffer, "Cannot open %.32s -- pppoe must be run as root.", bpfName);
		rp_fatal(buffer);
	    }
	    break;
	case EBUSY:
	case ENOENT:		
	    if (i == 0) {
		rp_fatal("No /dev/bpf* devices (check your kernel configuration for BPF support)");
	    } else {
		rp_fatal("All /dev/bpf* devices are in use");
	    }
	    break;
	}
	fatalSys(bpfName);
    }

    if ((sock = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) {
	fatalSys("socket");
    }

    
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
	fatalSys("ioctl(SIOCGIFFLAGS)");
    }
    if ((ifr.ifr_flags & IFF_UP) == 0) {
	char buffer[256];
	sprintf(buffer, "Interface %.16s is not up", ifname);
	rp_fatal(buffer);
    }

    
    if (hwaddr == NULL) {
	rp_fatal("openInterface: no hwaddr arg.");
    }
    getHWaddr(sock, ifname, hwaddr);
    initFilter(fd, type, hwaddr);

    
#if !defined(__OpenBSD__)
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
	fatalSys("ioctl(SIOCGIFMTU)");
    }
    if (ifr.ifr_mtu < ETH_DATA_LEN) {
	char buffer[256];
	sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d.  You may have serious connection problems.",
		ifname, ifr.ifr_mtu, ETH_DATA_LEN);
	printErr(buffer);
    }
#endif

    
    if (close(sock) < 0) {
	fatalSys("close");
    }

    
    if (ioctl(fd, BIOCVERSION, &bpf_ver) < 0) {
	fatalSys("ioctl(BIOCVERSION)");
    }
    if ((bpf_ver.bv_major != BPF_MAJOR_VERSION) ||
	(bpf_ver.bv_minor < BPF_MINOR_VERSION)) {
	char buffer[256];
	sprintf(buffer, "Unsupported BPF version: %d.%d (kernel: %d.%d)",
			BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
			bpf_ver.bv_major, bpf_ver.bv_minor);
	rp_fatal(buffer);
    }

    
    if (ioctl(fd, BIOCGBLEN, &bpfLength) < 0) {
	fatalSys("ioctl(BIOCGBLEN)");
    }
    if (!(bpfBuffer = (unsigned char *) malloc(bpfLength))) {
	rp_fatal("malloc");
    }

    
    optval = 1;
    if (ioctl(fd, BIOCIMMEDIATE, &optval) < 0) {
	fatalSys("ioctl(BIOCIMMEDIATE)");
    }

    
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(fd, BIOCSETIF, &ifr) < 0) {
	char buffer[256];
	sprintf(buffer, "ioctl(BIOCSETIF) can't select interface %.16s",
		ifname);
	rp_fatal(buffer);
    }

    syslog(LOG_INFO, "Interface=%.16s HWaddr=%02X:%02X:%02X:%02X:%02X:%02X Device=%.32s Buffer size=%d",
	   ifname,
	   hwaddr[0], hwaddr[1], hwaddr[2],
	   hwaddr[3], hwaddr[4], hwaddr[5],
	   bpfName, bpfLength);
    return fd;
}
コード例 #12
0
ファイル: discovery.c プロジェクト: 0xFA-Team/OpenKeeper
/**********************************************************************
*%FUNCTION: discovery
*%ARGUMENTS:
* conn -- PPPoE connection info structure
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Performs the PPPoE discovery phase
***********************************************************************/
void
discovery(PPPoEConnection *conn)
{
    int padiAttempts = 0;
    int padrAttempts = 0;
    int timeout = conn->discoveryTimeout;

    /* Skip discovery? */
    if (conn->skipDiscovery) {
	conn->discoveryState = STATE_SESSION;
	if (conn->killSession) {
	    sendPADT(conn, "RP-PPPoE: Session killed manually");
	    exit(0);
	}
	return;
    }

    do {
	padiAttempts++;
	if (padiAttempts > MAX_PADI_ATTEMPTS) {
	    if (persist) {
		padiAttempts = 0;
		timeout = conn->discoveryTimeout;
		printErr("Timeout waiting for PADO packets");
	    } else {
		rp_fatal("Timeout waiting for PADO packets");
	    }
	}
	sendPADI(conn);
	conn->discoveryState = STATE_SENT_PADI;
	waitForPADO(conn, timeout);

	/* If we're just probing for access concentrators, don't do
	   exponential backoff.  This reduces the time for an unsuccessful
	   probe to 15 seconds. */
	if (!conn->printACNames) {
	    timeout *= 2;
	}
	if (conn->printACNames && conn->numPADOs) {
	    break;
	}
    } while (conn->discoveryState == STATE_SENT_PADI);

    /* If we're only printing access concentrator names, we're done */
    if (conn->printACNames) {
	exit(0);
    }

    timeout = conn->discoveryTimeout;
    do {
	padrAttempts++;
	if (padrAttempts > MAX_PADI_ATTEMPTS) {
	    if (persist) {
		padrAttempts = 0;
		timeout = conn->discoveryTimeout;
		printErr("Timeout waiting for PADS packets");
	    } else {
		rp_fatal("Timeout waiting for PADS packets");
	    }
	}
	sendPADR(conn);
	conn->discoveryState = STATE_SENT_PADR;
	waitForPADS(conn, timeout);
	timeout *= 2;
    } while (conn->discoveryState == STATE_SENT_PADR);

    /* We're done. */
    conn->discoveryState = STATE_SESSION;
    return;
}
コード例 #13
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
/**********************************************************************
*%FUNCTION: openInterface
*%ARGUMENTS:
* ifname -- name of interface
* type -- Ethernet frame type
* hwaddr -- if non-NULL, set to the hardware address
*%RETURNS:
* A raw socket for talking to the Ethernet card.  Exits on error.
*%DESCRIPTION:
* Opens a raw Ethernet socket
***********************************************************************/
int
openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr)
{
    int optval=1;
    int fd;
    struct ifreq ifr;
    int domain, stype;

#ifdef HAVE_STRUCT_SOCKADDR_LL
    struct sockaddr_ll sa;
#else
    struct sockaddr sa;
#endif

    memset(&sa, 0, sizeof(sa));

#ifdef HAVE_STRUCT_SOCKADDR_LL
    domain = PF_PACKET;
    stype = SOCK_RAW;
#else
    domain = PF_INET;
    stype = SOCK_PACKET;
#endif

    if ((fd = socket(domain, stype, htons(type))) < 0) {
	/* Give a more helpful message for the common error case */
	if (errno == EPERM) {
	    rp_fatal("Cannot create raw socket -- pppoe must be run as root.");
	}
	fatalSys("socket");
    }

    if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) {
	fatalSys("setsockopt");
    }

    /* Fill in hardware address */
    if (hwaddr) {
	strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
	if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
	    fatalSys("ioctl(SIOCGIFHWADDR)");
	}
	memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
#ifdef ARPHRD_ETHER
	if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
	    char buffer[256];
	    sprintf(buffer, "Interface %.16s is not Ethernet", ifname);
	    rp_fatal(buffer);
	}
#endif
	if (NOT_UNICAST(hwaddr)) {
	    char buffer[256];
	    sprintf(buffer,
		    "Interface %.16s has broadcast/multicast MAC address??",
		    ifname);
	    rp_fatal(buffer);
	}
    }

    /* Sanity check on MTU */
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) {
	fatalSys("ioctl(SIOCGIFMTU)");
    }
    if (ifr.ifr_mtu < ETH_DATA_LEN) {
	char buffer[256];
	sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d.  You may have serious connection problems.",
		ifname, ifr.ifr_mtu, ETH_DATA_LEN);
	printErr(buffer);
    }

#ifdef HAVE_STRUCT_SOCKADDR_LL
    /* Get interface index */
    sa.sll_family = AF_PACKET;
    sa.sll_protocol = htons(type);

    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
	fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index");
    }
    sa.sll_ifindex = ifr.ifr_ifindex;

#else
    strcpy(sa.sa_data, ifname);
#endif

    /* We're only interested in packets on specified interface */
    if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
	fatalSys("bind");
    }

    return fd;
}
コード例 #14
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
/***********************************************************************
*%FUNCTION: sendPacket
*%ARGUMENTS:
* sock -- socket to send to
* pkt -- the packet to transmit
* size -- size of packet (in bytes)
*%RETURNS:
* 0 on success; -1 on failure
*%DESCRIPTION:
* Transmits a packet
***********************************************************************/
int
sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size)
{
#if defined(USE_BPF)
    if (write(sock, pkt, size) < 0) {
	sysErr("write (sendPacket)");
	return -1;
    }
#elif defined(HAVE_STRUCT_SOCKADDR_LL)
    if (send(sock, pkt, size, 0) < 0) {
	sysErr("send (sendPacket)");
	return -1;
    }
#else
#ifdef USE_DLPI

#define ABS(x)          ((x) < 0 ? -(x) : (x))

	u_char  addr[MAXDLADDR];
	u_char  phys[MAXDLADDR];
	u_char  sap[MAXDLADDR];
	u_char    xmitbuf[MAXDLBUF];
	int	data_size;

	short	tmp_sap;

	tmp_sap = htons(pkt->ethHdr.h_proto); 
	data_size = size - sizeof(struct ethhdr); 

	memcpy((char *)phys, (char *)pkt->ethHdr.h_dest, ETHERADDRL);
	memcpy((char *)sap,  (char *)&tmp_sap, sizeof(ushort_t));
	memcpy((char *)xmitbuf, (char *)pkt + sizeof(struct ethhdr), data_size); 

	if (dl_saplen > 0) {  /* order is sap+phys */
		(void) memcpy((char*)addr, (char*)&sap, dl_abssaplen);
		(void) memcpy((char*)addr+dl_abssaplen, (char*)phys, ETHERADDRL);
	} else {        /* order is phys+sap */
		(void) memcpy((char*)addr, (char*)phys, ETHERADDRL);
		(void) memcpy((char*)addr+ETHERADDRL, (char*)&sap, dl_abssaplen);
	}

#ifdef DL_DEBUG
	printf("%02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n", 
		addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],
		addr[6],addr[7]);
#endif

	dlunitdatareq(sock, addr, dl_addrlen, 0, 0, xmitbuf, data_size);



#else
    struct sockaddr sa;

    if (!conn) {
	rp_fatal("relay and server not supported on Linux 2.0 kernels");
    }
    strcpy(sa.sa_data, conn->ifName);
    if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) {
	sysErr("sendto (sendPacket)");
	return -1;
    }
#endif
#endif
    return 0;
}
コード例 #15
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
/**********************************************************************
*%FUNCTION: openInterface
*%ARGUMENTS:
* ifname -- name of interface
* type -- Ethernet frame type (0 for any frame type)
* hwaddr -- if non-NULL, set to the hardware address
*%RETURNS:
* A file descriptor for talking with the Ethernet card.  Exits on error.
* Note that the Linux version of this routine returns a socket instead.
*%DESCRIPTION:
* Opens a BPF on an interface for all PPPoE traffic (discovery and
* session).  If 'type' is 0, uses promiscuous mode to watch any PPPoE
* traffic on this network.
***********************************************************************/
int
openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr)
{
    static int fd = -1;
    char bpfName[32];
    u_int optval;
    struct bpf_version bpf_ver;
    struct ifreq ifr;
    int sock;
    int i;

    /* BSD only opens one socket for both Discovery and Session packets */
    if (fd >= 0) {
	return fd;
    }

    /* Find a free BPF device */
    for (i = 0; i < 256; i++) {
	sprintf(bpfName, "/dev/bpf%d", i);
	if (((fd = open(bpfName, O_RDWR, 0)) >= 0) ||
	    (errno != EBUSY)) {
	    break;
	}
    }
    if (fd < 0) {
	switch (errno) {
	case EACCES:		/* permission denied */
	    {
		char buffer[256];
		sprintf(buffer, "Cannot open %.32s -- pppoe must be run as root.", bpfName);
		rp_fatal(buffer);
	    }
	    break;
	case EBUSY:
	case ENOENT:		/* no such file */
	    if (i == 0) {
		rp_fatal("No /dev/bpf* devices (check your kernel configuration for BPF support)");
	    } else {
		rp_fatal("All /dev/bpf* devices are in use");
	    }
	    break;
	}
	fatalSys(bpfName);
    }

    if ((sock = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) {
	fatalSys("socket");
    }

    /* Check that the interface is up */
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
	fatalSys("ioctl(SIOCGIFFLAGS)");
    }
    if ((ifr.ifr_flags & IFF_UP) == 0) {
	char buffer[256];
	sprintf(buffer, "Interface %.16s is not up\n", ifname);
	rp_fatal(buffer);
    }

    /* Fill in hardware address and initialize the packet filter rules */
    if (hwaddr == NULL) {
	rp_fatal("openInterface: no hwaddr arg.");
    }
    getHWaddr(sock, ifname, hwaddr);
    initFilter(fd, type, hwaddr);

    /* Sanity check on MTU -- apparently does not work on OpenBSD */
#if !defined(__OpenBSD__)
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) {
	fatalSys("ioctl(SIOCGIFMTU)");
    }
    if (ifr.ifr_mtu < ETH_DATA_LEN) {
	char buffer[256];
	sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d.  You may have serious connection problems.",
		ifname, ifr.ifr_mtu, ETH_DATA_LEN);
	printErr(buffer);
    }
#endif

    /* done with the socket */
    if (close(sock) < 0) {
	fatalSys("close");
    }

    /* Check the BPF version number */
    if (ioctl(fd, BIOCVERSION, &bpf_ver) < 0) {
	fatalSys("ioctl(BIOCVERSION)");
    }
    if ((bpf_ver.bv_major != BPF_MAJOR_VERSION) ||
        (bpf_ver.bv_minor < BPF_MINOR_VERSION)) {
	char buffer[256];
	sprintf(buffer, "Unsupported BPF version: %d.%d (kernel: %d.%d)", 
			BPF_MAJOR_VERSION, BPF_MINOR_VERSION,
			bpf_ver.bv_major, bpf_ver.bv_minor);
	rp_fatal(buffer);
    }

    /* allocate a receive packet buffer */
    if (ioctl(fd, BIOCGBLEN, &bpfLength) < 0) {
	fatalSys("ioctl(BIOCGBLEN)");
    }
    if (!(bpfBuffer = (unsigned char *) malloc(bpfLength))) {
	rp_fatal("malloc");
    }

    /* reads should return as soon as there is a packet available */
    optval = 1;
    if (ioctl(fd, BIOCIMMEDIATE, &optval) < 0) {
	fatalSys("ioctl(BIOCIMMEDIATE)");
    }

    /* Bind the interface to the filter */
    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    if (ioctl(fd, BIOCSETIF, &ifr) < 0) {
	char buffer[256];
	sprintf(buffer, "ioctl(BIOCSETIF) can't select interface %.16s",
		ifname);
	rp_fatal(buffer);
    }

    syslog(LOG_INFO, "Interface=%.16s HWaddr=%02X:%02X:%02X:%02X:%02X:%02X Device=%.32s Buffer size=%d",
	   ifname, 
	   hwaddr[0], hwaddr[1], hwaddr[2],
	   hwaddr[3], hwaddr[4], hwaddr[5],
	   bpfName, bpfLength);
    return fd;
}
コード例 #16
0
ファイル: if.c プロジェクト: qtekfun/htcDesire820Kernel
int
openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr)
{
    int fd;
    long buf[MAXDLBUF];

	union   DL_primitives   *dlp;

    char base_dev[PATH_MAX];
    int ppa;

    if(strlen(ifname) > PATH_MAX) {
	rp_fatal("socket: Interface name too long");
    }

    if (strlen(ifname) < 2) {
	rp_fatal("socket: Interface name too short");
    }

    ppa = atoi(&ifname[strlen(ifname)-1]);
    strncpy(base_dev, ifname, PATH_MAX);
    base_dev[strlen(base_dev)-1] = '\0';

    dlp = (union DL_primitives*) buf;

    if ( (fd = open(base_dev, O_RDWR)) < 0) {
	
	if (errno == EPERM) {
	    rp_fatal("Cannot create raw socket -- pppoe must be run as root.");
	}
	
	if (errno == ENOENT) {
	    char ifname[512];
	    snprintf(ifname, sizeof(ifname), "/dev/%s", base_dev);
	    if ((fd = open(ifname, O_RDWR)) < 0) {
		if (errno == EPERM) {
		    rp_fatal("Cannot create raw socket -- pppoe must be run as root.");
		}
	    }
	}
    }
    if (fd < 0) {
	fatalSys("socket");
    }

    dlattachreq(fd, ppa);
    dlokack(fd, (char *)buf);

    dlbindreq(fd, type, 0, DL_CLDLS, 0, 0);
    dlbindack(fd, (char *)buf);

    dlinforeq(fd);
    dlinfoack(fd, (char *)buf);

    dl_abssaplen = ABS(dlp->info_ack.dl_sap_length);
    dl_saplen = dlp->info_ack.dl_sap_length;
    if (ETHERADDRL != (dlp->info_ack.dl_addr_length - dl_abssaplen))
	fatalSys("invalid destination physical address length");
    dl_addrlen = dl_abssaplen + ETHERADDRL;

    memcpy(hwaddr, (u_char*)((char*)(dlp) + (int)(dlp->info_ack.dl_addr_offset)), ETHERADDRL);

    if ( strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0 ) {
	fatalSys("DLIOCRAW");
    }

    if (ioctl(fd, I_FLUSH, FLUSHR) < 0) fatalSys("I_FLUSH");

    return fd;
}
コード例 #17
0
/**********************************************************************
*%FUNCTION: discovery
*%ARGUMENTS:
* conn -- PPPoE connection info structure
*%RETURNS:
* Nothing
*%DESCRIPTION:
* Performs the PPPoE discovery phase
***********************************************************************/
void
discovery(PPPoEConnection *conn)
{
    int padiAttempts = 0;
    int padrAttempts = 0;
    int timeout = PADI_TIMEOUT;

    /* Skip discovery and don't open discovery socket? */
    if (conn->skipDiscovery && conn->noDiscoverySocket) {
	conn->discoveryState = STATE_SESSION;
	PPPD_DEBUG(printf("%s %d\n",__FILE__,__LINE__));
	return;
    }

    conn->discoverySocket =
	openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth);

    /* Skip discovery? */
    if (conn->skipDiscovery) {
	conn->discoveryState = STATE_SESSION;
	if (conn->killSession) {
	    sendPADT(conn, "RP-PPPoE: Session killed manually");
	    exit(0);
	}
	PPPD_DEBUG(printf("%s %d\n",__FILE__,__LINE__));
	return;
    }

    do {
	PPPD_DEBUG(printf("%s %d\n",__FILE__,__LINE__));
	padiAttempts++;
	if (padiAttempts > MAX_PADI_ATTEMPTS) 
	{
	    rp_fatal("Timeout waiting for PADO packets");
	}
	sendPADI(conn);
	conn->discoveryState = STATE_SENT_PADI;
	waitForPADO(conn, timeout);
	
	/* If we're just probing for access concentrators, don't do
	   exponential backoff.  This reduces the time for an unsuccessful
	   probe to 15 seconds. */
	if (!conn->printACNames) {

	    timeout *= 2;
	}
	if (conn->printACNames && conn->numPADOs) {
	    break;
	}
    } while (conn->discoveryState == STATE_SENT_PADI);

    /* If we're only printing access concentrator names, we're done */
    if (conn->printACNames) {
	printf("--------------------------------------------------\n");
	exit(0);
    }
	PPPD_DEBUG(printf("%s %d\n",__FILE__,__LINE__));
    timeout = PADI_TIMEOUT;
    do {
	PPPD_DEBUG(printf("%s %d\n",__FILE__,__LINE__));
	padrAttempts++;
	if (padrAttempts > MAX_PADI_ATTEMPTS) {
	    rp_fatal("Timeout waiting for PADS packets");
	}
	sendPADR(conn);
	conn->discoveryState = STATE_SENT_PADR;
	waitForPADS(conn, timeout);
	timeout *= 2;
    } while (conn->discoveryState == STATE_SENT_PADR);

    /* We're done. */
	free(conn->serviceName);//mcli
	conn->serviceName=NULL;//mcli
    conn->discoveryState = STATE_SESSION;
	PPPD_DEBUG(printf("%s %d\n",__FILE__,__LINE__));
    return;
}
コード例 #18
0
ファイル: if.c プロジェクト: BackupTheBerlios/wl530g-svn
void sigalrm(int sig)
{
        (void) rp_fatal("sigalrm:  TIMEOUT");
}
コード例 #19
0
ファイル: pppoe-discovery.c プロジェクト: AllardJ/Tomato
void sysErr(char const *str)
{
    rp_fatal(str);
}