Пример #1
0
int
bind (int s, struct sockaddr *name, int namelen)
{
	int error;
	int ret = -1;
	struct socket *so;
	struct mbuf *nam;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
		error = sockargstombuf (&nam, name, namelen, MT_SONAME);
		if (error == 0) {
			error = sobind (so, nam);
			if (error == 0)
				ret = 0;
			else
				errno = error;
			m_freem (nam);
		}
		else {
			errno = error;
		}
	}
	rtems_bsdnet_semaphore_release ();
	return ret;
}
Пример #2
0
int
setsockopt (int s, int level, int name, const void *val, int len)
{
	struct socket *so;
	struct mbuf *m = NULL;
	int error;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	if (len > MLEN) {
		errno = EINVAL;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	if (val) {
		error = sockargstombuf (&m, val, len, MT_SOOPTS);
		if (error) {
			errno = error;
			rtems_bsdnet_semaphore_release ();
			return -1;
		}
	}
	error = sosetopt(so, level, name, m);
	if (error) {
		errno = error;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	rtems_bsdnet_semaphore_release ();
	return 0;
}
/*
 * send data by simply allocating an MBUF packet
 * header and pointing it to our data region.
 *
 * Optionally, the caller may supply 'reference'
 * and 'free' procs. (The latter may call the
 * user back once the networking stack has
 * released the buffer).
 *
 * The callbacks are provided with the 'closure'
 * pointer and the 'buflen' argument.
 */
ssize_t
sendto_nocpy (
		int s,
		const void *buf, size_t buflen,
		int flags,
		const struct sockaddr *toaddr, int tolen,
		void *closure,
		void (*freeproc)(caddr_t, u_int),
		void (*refproc)(caddr_t, u_int)
)
{
	int           error;
	struct socket *so;
	struct mbuf   *to, *m;
	int           ret = -1;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}

	error = sockaddrtombuf (&to, toaddr, tolen);
	if (error) {
		errno = error;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}

	MGETHDR(m, M_WAIT, MT_DATA);
	m->m_pkthdr.len   = 0;
	m->m_pkthdr.rcvif =  (struct ifnet *) 0;

	m->m_flags       |= M_EXT;
	m->m_ext.ext_buf  = closure ? closure : (void*)buf;
	m->m_ext.ext_size = buflen;
	/* we _must_ supply non-null procs; otherwise,
	 * the kernel code assumes it's a mbuf cluster
	 */
	m->m_ext.ext_free = freeproc ? freeproc : dummyproc;
	m->m_ext.ext_ref  = refproc  ? refproc  : dummyproc;
	m->m_pkthdr.len  += buflen;
	m->m_len          = buflen;
	m->m_data		  = (void*)buf;

	error = sosend (so, to, NULL, m, NULL, flags);
	if (error) {
		if (/*auio.uio_resid != len &&*/ (error == EINTR || error == EWOULDBLOCK))
			error = 0;
	}
	if (error)
		errno = error;
	else
		ret = buflen;
	if (to)
		m_freem(to);
	rtems_bsdnet_semaphore_release ();
	return (ret);
}
/* ARGSUSED */
int
pppopen(struct rtems_termios_tty *tty)
{
    int                        i;
    register struct ppp_softc *sc;
    struct mbuf *m = (struct mbuf *)0;

    if (tty->t_line == PPPDISC) {
	sc = (struct ppp_softc *)tty->t_sc;
	if (sc != NULL && sc->sc_devp == (void *)tty) {
	    return (0);
	}
    }

    if ((sc = pppalloc(1)) == NULL) {
	return ENXIO;
    }

    if (sc->sc_relinq)
	(*sc->sc_relinq)(sc);	/* get previous owner to relinquish the unit */

    sc->sc_ilen = 0;
    sc->sc_m = NULL;
    bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
    sc->sc_asyncmap[0] = 0xffffffff;
    sc->sc_asyncmap[3] = 0x60000000;
    sc->sc_rasyncmap = 0;
    sc->sc_devp = tty;
    sc->sc_start = pppasyncstart;
    sc->sc_ctlp = pppasyncctlp;
    sc->sc_relinq = pppasyncrelinq;
    sc->sc_outm = NULL;
    sc->sc_outmc = NULL;
    
    /* preallocate mbufs for free queue */
    rtems_bsdnet_semaphore_obtain();
    for (i=0; i<NUM_MBUFQ; i++) {
      pppallocmbuf(sc, &m);
      if ( i == 0 ) {
        /* use first mbuf for rx iterrupt handling */
        sc->sc_m = m;
      }
      else {
        /* enqueue mbuf for later use */
        IF_ENQUEUE(&sc->sc_freeq, m);
      }
      m = (struct mbuf *)0;
    }
    rtems_bsdnet_semaphore_release();

    /* initialize values */
    sc->sc_if.if_flags |= IFF_RUNNING;
    sc->sc_if.if_baudrate =
	rtems_termios_baud_to_number(tty->termios.c_cflag & CBAUD);

    tty->t_sc = (void *)sc;

    return ( RTEMS_SUCCESSFUL );
}
Пример #5
0
void
mveth_stop(struct mv64340_private *mp)
{
extern void mveth_stop_hw();
	rtems_bsdnet_semaphore_obtain();
		mveth_stop_hw(mp);
	rtems_bsdnet_semaphore_release();
}
/*
 * receive data in an 'mbuf chain'.
 * The chain must be released once the
 * data has been extracted:
 *
 *   rtems_bsdnet_semaphore_obtain();
 *   	m_freem(chain);
 *   rtems_bsdnet_semaphore_release();
 */
ssize_t
recv_mbuf_from(int s, struct mbuf **ppm, long len, struct sockaddr *fromaddr, int *fromlen)
{
	int ret = -1;
	int error;
	struct uio auio;
	struct socket *so;
	struct mbuf *from = NULL;

	memset(&auio, 0, sizeof(auio));
	*ppm = 0;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
/*	auio.uio_iov = mp->msg_iov;
	auio.uio_iovcnt = mp->msg_iovlen;
	auio.uio_segflg = UIO_USERSPACE;
	auio.uio_rw = UIO_READ;
	auio.uio_offset = 0;
*/
	auio.uio_resid = len;
	error = soreceive (so, &from, &auio, (struct mbuf **) ppm,
			(struct mbuf **)NULL,
			NULL);
	if (error) {
		if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
			error = 0;
	}
	if (error) {
		errno = error;
	}
	else {
		ret = len - auio.uio_resid;
		if (fromaddr) {
			len = *fromlen;
			if ((len <= 0) || (from == NULL)) {
				len = 0;
			}
			else {
				if (len > from->m_len)
					len = from->m_len;
				memcpy (fromaddr, mtod(from, caddr_t), len);
			}
			*fromlen = len;
		}
	}
	if (from)
		m_freem (from);
	if (error && *ppm) {
		m_freem(*ppm);
		*ppm = 0;
	}
	rtems_bsdnet_semaphore_release ();
	return (ret);
}
Пример #7
0
static rtems_task ppp_rxdaemon(rtems_task_argument arg)
{
  rtems_event_set             events;
  rtems_interrupt_level       level;
  struct ppp_softc           *sc = (struct ppp_softc *)arg;
  struct mbuf                *mp = (struct mbuf      *)0;
  struct mbuf                *m;

  /* enter processing loop */
  while ( 1 ) {
    /* wait for event */
    rtems_event_receive(RX_PACKET|RX_MBUF|RX_EMPTY,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events);
    if ( events & RX_EMPTY ) {
      printf("RX: QUEUE is EMPTY\n");
      events &= ~RX_EMPTY;
    }

    if ( events ) {
      /* get the network semaphore */
      rtems_bsdnet_semaphore_obtain();

      /* check to see if new packet was received */
      if ( events & RX_PACKET ) {
        /* get received packet mbuf chain */
        rtems_interrupt_disable(level);
        IF_DEQUEUE(&sc->sc_rawq, m);
        rtems_interrupt_enable(level);

        /* ensure packet was retrieved */
        if ( m != (struct mbuf *)0 ) {
          /* process the received packet */
          mp = ppp_inproc(sc, m);
        }
      }

      /* allocate a new mbuf to replace one */
      if ( mp == NULL ) {
        pppallocmbuf(sc, &mp);
      }

      /* place mbuf on freeq */
      rtems_interrupt_disable(level);
      IF_ENQUEUE(&sc->sc_freeq, mp);
      rtems_interrupt_enable(level);
      mp = (struct mbuf *)0;

      /* release the network semaphore */
      rtems_bsdnet_semaphore_release();

      /* check to see if queue is empty */
      if ( sc->sc_rawq.ifq_head ) {
        /* queue is not empty - post another event */
        rtems_event_send(sc->sc_rxtask, RX_PACKET);
      }
    }
  }
}
Пример #8
0
int
mveth_protected(int (*p)(struct mv64340_private*), struct mv64340_private *mp)
{
int rval;
	rtems_bsdnet_semaphore_obtain();
		rval = p(mp);
	rtems_bsdnet_semaphore_release();
	return rval;
}
/*
 * Perform a BOOTP request and update "standard" files in /etc
 * with the results.
 */
void
rtems_bsdnet_do_bootp_and_rootfs (void)
{
  bool ok;
	rtems_bsdnet_semaphore_obtain ();
	ok = bootpc_init (true, true);
	rtems_bsdnet_semaphore_release ();
  if (!ok)
    panic ("rtems_bsdnet_do_bootp_and_rootfs: bootp failed");
}
Пример #10
0
/* ARGSUSED */
int
ppptioctl(struct rtems_termios_tty *tty, rtems_libio_ioctl_args_t *args)
{
/*    int                 i;	*/
    int                 error = RTEMS_SUCCESSFUL;
    ioctl_command_t     cmd   = args->command;
    caddr_t             data  = args->buffer;
    struct ppp_softc   *sc    = tty->t_sc;

    switch (cmd) {
    case RTEMS_IO_GET_ATTRIBUTES:
    case RTEMS_IO_SET_ATTRIBUTES:
    case RTEMS_IO_TCDRAIN:
    case RTEMS_IO_SNDWAKEUP:
    case RTEMS_IO_RCVWAKEUP:
    case TIOCGETD:
    case TIOCSETD:
        error = rtems_termios_ioctl(args);
	break;

    case PPPIOCSASYNCMAP:
	sc->sc_asyncmap[0] = *(u_int *)data;
	break;

    case PPPIOCGASYNCMAP:
	*(u_int *)data = sc->sc_asyncmap[0];
	break;

    case PPPIOCSRASYNCMAP:
	sc->sc_rasyncmap = *(u_int *)data;
	break;

    case PPPIOCGRASYNCMAP:
	*(u_int *)data = sc->sc_rasyncmap;
	break;

    case PPPIOCSXASYNCMAP:
	bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
	sc->sc_asyncmap[1] = 0;		    /* mustn't escape 0x20 - 0x3f */
	sc->sc_asyncmap[2] &= ~0x40000000;  /* mustn't escape 0x5e */
	sc->sc_asyncmap[3] |= 0x60000000;   /* must escape 0x7d, 0x7e */
	break;

    case PPPIOCGXASYNCMAP:
	bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
	break;

    default:
        rtems_bsdnet_semaphore_obtain();
	error = pppioctl(sc, cmd, data, 0, NULL);
        rtems_bsdnet_semaphore_release();
    }
    return error;
}
Пример #11
0
int
connect (int s, struct sockaddr *name, int namelen)
{
	int error;
	int ret = -1;
	struct socket *so;
	struct mbuf *nam;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
		errno = EALREADY;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	error = sockargstombuf (&nam, name, namelen, MT_SONAME);
	if (error) {
		errno = error;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	error = soconnect (so, nam);
	if (error)
		goto bad;
	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
		m_freem(nam);
		errno = EINPROGRESS;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
		error = soconnsleep (so);
		if (error)
			break;
	}
	if (error == 0) {
		error = so->so_error;
		so->so_error = 0;
	}
    bad:
	so->so_state &= ~SS_ISCONNECTING;
	m_freem (nam);
	if (error)
		errno = error;
	else
		ret = 0;
	rtems_bsdnet_semaphore_release ();
	return ret;
}
Пример #12
0
int
mveth_tx(struct mv64340_private *mp, char *data, int len, int nbufs)
{
int rval = -1,l;
char        *p;
struct mbuf *m;
char 	*emsg = 0;

	rtems_bsdnet_semaphore_obtain();
	MGETHDR(m, M_WAIT, MT_DATA);
	if ( !m ) {
		emsg="Unable to allocate header\n";
		goto bail;
	}
	MCLGET(m, M_WAIT);
	if ( !(m->m_flags & M_EXT) ) {
		m_freem(m);
		emsg="Unable to allocate cluster\n";
		goto bail;
	}
	p = mtod(m, char *);
	l = 0;
	switch (nbufs) {
		case 3:
		default:
			emsg="nbufs arg must be 1..3\n";
			goto bail;

		case 1:
			l += sizeof(BcHeader);
			memcpy(p, &BcHeader, sizeof(BcHeader));
			p += sizeof(BcHeader);

		case 2:
			memcpy(p,data,len);
			l += len;
			m->m_len = m->m_pkthdr.len = l;
			if ( 2 == nbufs ) {
    			M_PREPEND(m, sizeof (BcHeader), M_WAIT);
				if (!m) {
					emsg = "Unable to prepend\n";
					goto bail;
				}
				p = mtod(m, char*);
				memcpy(p,&BcHeader,sizeof(BcHeader));
				l += sizeof(BcHeader);
			}
		break;
	}
Пример #13
0
/*
 * Line specific (tty) write routine.
 */
int
pppwrite(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args)
{
    struct sockaddr               dst;
    int                           n;
    int                           len;
    int                           maximum    = rw_args->count;
    char                         *out_buffer = rw_args->buffer; 
    register struct ppp_softc    *sc         = (struct ppp_softc *)tty->t_sc;
    struct mbuf                  *m;
    struct mbuf                  *m0;
    struct mbuf                 **mp;

    rtems_bsdnet_semaphore_obtain();
    for (mp = &m0; maximum; mp = &m->m_next) {
	MGET(m, M_WAIT, MT_DATA);
	if ((*mp = m) == NULL) {
	    m_freem(m0);
	    return (ENOBUFS);
	}
	m->m_len = 0;
	if (maximum >= MCLBYTES / 2) {
	    MCLGET(m, M_DONTWAIT);
        }
	len = M_TRAILINGSPACE(m);
	if (len > maximum) {
          memcpy(mtod(m, u_char *),out_buffer,maximum);
          m->m_len = maximum;
          maximum  = 0;
        }
        else {
          memcpy(mtod(m, u_char *),out_buffer,len);
          m->m_len    = len;
          maximum    -= len;
          out_buffer += len;
        }
    }

    dst.sa_family = AF_UNSPEC;
    bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
    m0->m_data += PPP_HDRLEN;
    m0->m_len  -= PPP_HDRLEN;

    n = pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
    rtems_bsdnet_semaphore_release();

    return ( n );
}
Пример #14
0
/*
 * Line specific close routine, called from device close routine
 * and from ttioctl.
 * Detach the tty from the ppp unit.
 * Mimics part of ttyclose().
 */
int
pppclose(struct rtems_termios_tty *tty)
{
    register struct ppp_softc *sc;

    tty->t_line = 0;
    sc = (struct ppp_softc *)tty->t_sc;
    if (sc != NULL) {
	tty->t_sc = NULL;
	if (tty == (struct rtems_termios_tty *)sc->sc_devp) {
            rtems_bsdnet_semaphore_obtain();
	    pppasyncrelinq(sc);
	    pppdealloc(sc);
            rtems_bsdnet_semaphore_release();
	}
    }
    return ( RTEMS_SUCCESSFUL );
}
Пример #15
0
int
listen (int s, int backlog)
{
	int error;
	int ret = -1;
	struct socket *so;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) != NULL) {
		error = solisten (so, backlog);
		if (error == 0)
			ret = 0;
		else
			errno = error;
	}
	rtems_bsdnet_semaphore_release ();
	return ret;
}
Пример #16
0
static int
rtems_bsdnet_fcntl (rtems_libio_t *iop, int cmd)
{
	struct socket *so;

	if (cmd == F_SETFL) {
		rtems_bsdnet_semaphore_obtain ();
		if ((so = iop->data1) == NULL) {
			rtems_bsdnet_semaphore_release ();
			return EBADF;
		}
		if (iop->flags & LIBIO_FLAGS_NO_DELAY)
			so->so_state |= SS_NBIO;
		else
			so->so_state &= ~SS_NBIO;
		rtems_bsdnet_semaphore_release ();
	}
        return 0;
}
Пример #17
0
int
shutdown (int s, int how)
{
      struct socket *so;
      int error;

      rtems_bsdnet_semaphore_obtain ();
      if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
              rtems_bsdnet_semaphore_release ();
              return -1;
      }
      error = soshutdown(so, how);
      rtems_bsdnet_semaphore_release ();
      if (error) {
              errno = error;
              return -1;
      }
      return 0;
}
Пример #18
0
int
getsockopt (int s, int level, int name, void *aval, int *avalsize)
{
	struct socket *so;
	struct mbuf *m = NULL, *m0;
	char *val = aval;
	int i, op, valsize;
	int error;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	if (val)
		valsize = *avalsize;
	else
		valsize = 0;
	if (((error = sogetopt(so, level, name, &m)) == 0) && val && valsize && m) {
		op = 0;
		while (m && op < valsize) {
			i = valsize - op;
			if (i > m->m_len)
				i = m->m_len;
			memcpy (val, mtod(m, caddr_t), i);
			op += i;
			val += i;
			m0 = m;
			MFREE (m0, m);
		}
		*avalsize = op;
	}
	if (m != NULL)
		(void) m_free(m);
	if (error) {
		errno = error;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	rtems_bsdnet_semaphore_release ();
	return 0;
}
Пример #19
0
static int
rtems_bsdnet_ioctl (rtems_libio_t *iop, uint32_t   command, void *buffer)
{
	struct socket *so;
	int error;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = iop->data1) == NULL) {
		errno = EBADF;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	error = so_ioctl (iop, so, command, buffer);
	rtems_bsdnet_semaphore_release ();
	if (error) {
		errno = error;
		return -1;
	}
	return 0;
}
Пример #20
0
/*
 ************************************************************************
 *                      RTEMS I/O HANDLER ROUTINES                      *
 ************************************************************************
 */
static int
rtems_bsdnet_close (rtems_libio_t *iop)
{
	struct socket *so;
	int error;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = iop->data1) == NULL) {
		errno = EBADF;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	error = soclose (so);
	rtems_bsdnet_semaphore_release ();
	if (error) {
		errno = error;
		return -1;
	}
	return 0;
}
Пример #21
0
int
sysctl(int *name, u_int namelen, void *oldp,
       size_t *oldlenp, void *newp, size_t newlen)
{
  int    error;
	size_t j;

  rtems_bsdnet_semaphore_obtain ();
  error = userland_sysctl (0, name, namelen, oldp, oldlenp, 1, newp, newlen, &j);
  rtems_bsdnet_semaphore_release ();

  if (oldlenp)
    *oldlenp = j;

  if (error)
  {
    errno = error;
    return -1;
  }
  return 0;
}
Пример #22
0
/*
 *********************************************************************
 *                       BSD-style entry points                      *
 *********************************************************************
 */
int
socket (int domain, int type, int protocol)
{
	int fd;
	int error;
	struct socket *so;

	rtems_bsdnet_semaphore_obtain ();
	error = socreate(domain, &so, type, protocol, NULL);
	if (error == 0) {
		fd = rtems_bsdnet_makeFdForSocket (so);
		if (fd < 0)
			soclose (so);
	}
	else {
		errno = error;
		fd = -1;
	}
	rtems_bsdnet_semaphore_release ();
	return fd;
}
Пример #23
0
static int
getpeersockname (int s, struct sockaddr *name, int *namelen, int pflag)
{
	struct socket *so;
	struct mbuf *m;
	int len = *namelen;
	int error;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	m = m_getclr(M_WAIT, MT_SONAME);
	if (m == NULL) {
		errno = ENOBUFS;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	if (pflag)
		error = (*so->so_proto->pr_usrreqs->pru_peeraddr)(so, m);
	else
		error = (*so->so_proto->pr_usrreqs->pru_sockaddr)(so, m);
	if (error) {
		m_freem(m);
		errno = error;
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	if (len > m->m_len) {
		len = m->m_len;
		*namelen = len;
	}
	memcpy (name, mtod(m, caddr_t), len);
	m_freem (m);
	rtems_bsdnet_semaphore_release ();
	return 0;
}
/*
 * Package system call argument into mbuf.
 *
 * (unfortunately, the original is not public)
 */
static int
sockaddrtombuf (struct mbuf **mp, const struct sockaddr *buf, int buflen)
{
struct mbuf *m;
struct sockaddr *sa;

	if ((u_int)buflen > MLEN)
		return (EINVAL);

	rtems_bsdnet_semaphore_obtain();
	m = m_get(M_WAIT, MT_SONAME);
	rtems_bsdnet_semaphore_release();

	if (m == NULL)
		return (ENOBUFS);
	m->m_len = buflen;
	memcpy (mtod(m, caddr_t), buf, buflen);
	*mp = m;
	sa = mtod(m, struct sockaddr *);
	sa->sa_len = buflen;

	return 0;
}
Пример #25
0
static rtems_task ppp_txdaemon(rtems_task_argument arg)
{
  rtems_event_set             events;
  int                         iprocess = (int               )0;
  struct ppp_softc           *sc       = (struct ppp_softc *)arg;
  struct mbuf                *mp;
  struct mbuf                *mf;
  struct mbuf                *m;
  struct rtems_termios_tty   *tp;
  
  int frag;

  /* enter processing loop */
  while ( 1 ) {
    /* wait for event */
    rtems_event_receive(TX_PACKET|TX_TRANSMIT,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events);
    if ( events & TX_TRANSMIT ) {
      /* received event from interrupt handler - free current mbuf */
      rtems_bsdnet_semaphore_obtain();

      m_freem(sc->sc_outm);
      
      rtems_bsdnet_semaphore_release();

      /* chain is done - clear the values */
      sc->sc_outm  = (struct mbuf *)0;
      sc->sc_outmc = (struct mbuf *)0;

      /* now set flag to fake receive of TX_PACKET event */
      /* this will check to see if we have any pending packets */
      events |= TX_PACKET;
    }

    /* received event from pppasyncstart */
    if ( events & TX_PACKET ) {
      /* ensure we are not busy */
      if ( sc->sc_outm == (struct mbuf *)0 ) {
        /* try dequeuing a packet */
        sc->sc_outm = ppp_dequeue(sc);
        if ( sc->sc_outm == NULL ) {
          /* clear output flags */
          sc->sc_outflag      = 0;
          sc->sc_if.if_flags &= ~IFF_OACTIVE;
        }
        else {
          /* set flag to start process */
          iprocess            = 1;
          sc->sc_outflag      = SC_TX_BUSY;
          sc->sc_if.if_flags |= IFF_OACTIVE;
        }
      }
    }

    /* check to see if there is any processing required */
    if ( iprocess ) {
      /* clear process flag */
      iprocess = (int)0;
      frag=0;

      /* initialize output values */
      sc->sc_outfcs    = PPP_INITFCS;
      sc->sc_outbuf    = (u_char *)0;
      sc->sc_outlen    = (short   )0;
      sc->sc_outoff    = (short   )0;
      sc->sc_outfcslen = (short   )0;

/*	  printf("Start Transmit Packet..\n"); */

      /* loop over all mbufs in chain */
      mf     = NULL;
      mp     = NULL;
      m      = sc->sc_outm;

      sc->sc_outmc  = m;
      sc->sc_outlen = m->m_len;
      sc->sc_outbuf = mtod(m, u_char *);

      while (( m != (struct mbuf *)0 ) && ( m->m_len > 0 )) {
      	frag++;

        /* update the FCS value and then check next packet length */
        if(m->m_len){
       	 sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
       	}

        if(( m->m_next != NULL ) && ( m->m_next->m_len == 0 )) {
			if(mf){
				printf(" if_ppp.c : MBUF Error !!!!\n");
			}
			else{
            	mf = m->m_next;
	        	m->m_next = NULL;
			}
		}

#ifdef LALL_X
        /* check next packet to see if it is empty */
        while (( m->m_next != NULL ) && ( m->m_next->m_len == 0 )) {
          /* next mbuf is zero length */
          /* add empty mbuf to free chain */
          if ( mp == NULL ) {
            /* item is head of free list */
            mf = m->m_next;
            mp = mf;
          }
          else {
            /* add item to end of the free list */
            mp->m_next = m->m_next;
            mp         = m->m_next;
          }

          /* remove empty item from process chain */
          m->m_next  = m->m_next->m_next;
          mp->m_next = NULL;
        }
#endif
        /* move to next packet */
        m = m->m_next;
      }

      /* ensure there is data to be sent out */
      tp = (struct rtems_termios_tty *)sc->sc_devp;
      if (( tp != NULL ) && ( sc->sc_outmc != (struct mbuf *)0 )) {
        /* place FCS value into buffer */
        sc->sc_outfcsbuf[sc->sc_outfcslen++] = ~sc->sc_outfcs & 0xff;
        sc->sc_outfcsbuf[sc->sc_outfcslen++] = (~sc->sc_outfcs >> 8) & 0xff;
        microtime(&sc->sc_if.if_lastchange);
  
        /* write out frame byte to start the transmission */
		sc->sc_outchar = (u_char)PPP_FLAG;
        (*tp->device.write)(tp->minor, (char *)&sc->sc_outchar, 1);
      }

      /* check to see if we need to free some empty mbufs */
      if ( mf != (struct mbuf *)0 ) {
        /* free empty mbufs */
        rtems_bsdnet_semaphore_obtain();
        m_freem(mf);
        rtems_bsdnet_semaphore_release();
      }
    }
Пример #26
0
/*
 * All `transmit' operations end up calling this routine.
 */
ssize_t
sendmsg (int s, const struct msghdr *mp, int flags)
{
	int ret = -1;
	int error;
	struct uio auio;
	struct iovec *iov;
	struct socket *so;
	struct mbuf *to;
	struct mbuf *control = NULL;
	int i;
	int len;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	auio.uio_iov = mp->msg_iov;
	auio.uio_iovcnt = mp->msg_iovlen;
	auio.uio_segflg = UIO_USERSPACE;
	auio.uio_rw = UIO_WRITE;
	auio.uio_offset = 0;
	auio.uio_resid = 0;
	iov = mp->msg_iov;
	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
		if ((auio.uio_resid += iov->iov_len) < 0) {
			errno = EINVAL;
			rtems_bsdnet_semaphore_release ();
			return -1;
		}
	}
	if (mp->msg_name) {
		error = sockargstombuf (&to, mp->msg_name, mp->msg_namelen, MT_SONAME);
		if (error) {
			errno = error;
			rtems_bsdnet_semaphore_release ();
			return -1;
		}
	}
	else {
		to = NULL;
	}
	if (mp->msg_control) {
		if (mp->msg_controllen < sizeof (struct cmsghdr)) {
			errno = EINVAL;
			if (to)
				m_freem(to);
			rtems_bsdnet_semaphore_release ();
			return -1;
		}
		sockargstombuf (&control, mp->msg_control, mp->msg_controllen, MT_CONTROL);
	}
	else {
		control = NULL;
	}
	len = auio.uio_resid;
	error = sosend (so, to, &auio, (struct mbuf *)0, control, flags);
	if (error) {
		if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
			error = 0;
	}
	if (error)
		errno = error;
	else
		ret = len - auio.uio_resid;
	if (to)
		m_freem(to);
	rtems_bsdnet_semaphore_release ();
	return (ret);
}
Пример #27
0
/*
 * All `receive' operations end up calling this routine.
 */
ssize_t
recvmsg (int s, struct msghdr *mp, int flags)
{
	int ret = -1;
	int error;
	struct uio auio;
	struct iovec *iov;
	struct socket *so;
	struct mbuf *from = NULL, *control = NULL;
	int i;
	int len;

	rtems_bsdnet_semaphore_obtain ();
	if ((so = rtems_bsdnet_fdToSocket (s)) == NULL) {
		rtems_bsdnet_semaphore_release ();
		return -1;
	}
	auio.uio_iov = mp->msg_iov;
	auio.uio_iovcnt = mp->msg_iovlen;
	auio.uio_segflg = UIO_USERSPACE;
	auio.uio_rw = UIO_READ;
	auio.uio_offset = 0;
	auio.uio_resid = 0;
	iov = mp->msg_iov;
	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
		if ((auio.uio_resid += iov->iov_len) < 0) {
			errno = EINVAL;
			rtems_bsdnet_semaphore_release ();
			return -1;
		}
	}
	len = auio.uio_resid;
	mp->msg_flags = flags;
	error = soreceive (so, &from, &auio, (struct mbuf **)NULL,
			mp->msg_control ? &control : (struct mbuf **)NULL,
			&mp->msg_flags);
	if (error) {
		if (auio.uio_resid != len && (error == EINTR || error == EWOULDBLOCK))
			error = 0;
	}
	if (error) {
		errno = error;
	}
	else {
		ret = len - auio.uio_resid;
		if (mp->msg_name) {
			len = mp->msg_namelen;
			if ((len <= 0) || (from == NULL)) {
				len = 0;
			}
			else {
				if (len > from->m_len)
					len = from->m_len;
				memcpy (mp->msg_name, mtod(from, caddr_t), len);
			}
			mp->msg_namelen = len;
		}
		if (mp->msg_control) {
			struct mbuf *m;
			void *ctlbuf;

			len = mp->msg_controllen;
			m = control;
			mp->msg_controllen = 0;
			ctlbuf = mp->msg_control;

			while (m && (len > 0)) {
				unsigned int tocopy;

				if (len >= m->m_len)
					tocopy = m->m_len;
				else {
					mp->msg_flags |= MSG_CTRUNC;
					tocopy = len;
				}
				memcpy(ctlbuf, mtod(m, caddr_t), tocopy);
				ctlbuf += tocopy;
				len -= tocopy;
				m = m->m_next;
			}
			mp->msg_controllen = ctlbuf - mp->msg_control;
		}
	}
	if (from)
		m_freem (from);
	if (control)
		m_freem (control);
	rtems_bsdnet_semaphore_release ();
	return (ret);
}
Пример #28
0
/*
 * Line specific (tty) read routine.
 */
int
pppread(struct rtems_termios_tty *tty, rtems_libio_rw_args_t *rw_args)
{
    rtems_status_code            status  = RTEMS_UNSATISFIED;
    int                          count   = 0;
    int                          maximum = rw_args->count;
    char                        *buffer  = rw_args->buffer;
    register struct ppp_softc   *sc      = (struct ppp_softc *)tty->t_sc;
    struct mbuf                 *m;
    struct mbuf                 *m0;
    u_char                      *p;

    if (sc == NULL)
        return 0;

    /*
     * Loop waiting for input, checking that nothing disasterous
     * happens in the meantime.
     */
    if (tty != (struct rtems_termios_tty *)sc->sc_devp || tty->t_line != PPPDISC) {
        return ( status );
    }
    if (sc->sc_inq.ifq_head == NULL) {
      return ( status );
    }

    /* Get the packet from the input queue */
    rtems_bsdnet_semaphore_obtain();
    IF_DEQUEUE(&sc->sc_inq, m0);

    /* loop over mbuf chain */
    m = m0;
    while (( m != NULL ) && ( m->m_len > 0 ) && ( count+m->m_len < maximum )) {
      /* copy data into buffer */
      p = mtod(m, u_char *);
      memcpy(buffer, p, m->m_len);
      memset(p, 0, m->m_len);
      count  += m->m_len;
      buffer += m->m_len;

      /* increment loop index */
      m = m->m_next;
    }

    /* free mbuf chain */
    m_freem(m0);
    rtems_bsdnet_semaphore_release();

    /* update return values */
    rw_args->bytes_moved = count;
    if ( count >= 0 ) {
      status = RTEMS_SUCCESSFUL;
    }

    /* check to see if queue is empty */
    if (sc->sc_inq.ifq_head != NULL) {
      /* queue is not empty - post another event to ourself */
      rtems_event_send(sc->sc_pppdtask, PPPD_EVENT);
    }

    return ( status );
}
Пример #29
0
void
rtems_bsdnet_show_inet_routes (void)
{
	struct radix_node_head *rnh;
	struct dinfo d;
	struct rinfo *r;
	int i, error;

	/*
	 * For now we'll handle only AF_INET
	 */
	rnh = rt_tables[AF_INET];
	if (!rnh)
		return;
	d.count = d.capacity = 0;
	d.routes = NULL;
	rtems_bsdnet_semaphore_obtain ();
	error = rnh->rnh_walktree(rnh, show_inet_route, &d);
	rtems_bsdnet_semaphore_release ();
	if (error) {
		printf ("Can't get route info: %s\n", strerror (error));
		return;
	}
	if (d.count == 0) {
		printf ("No routes!\n");
		return;
	}
	printf ("Destination     Gateway/Mask/Hw    Flags     Refs     Use Expire Interface\n");
	for (i = 0, r = d.routes ; i < d.count ; i++, r++) {
		char buf[30];
		char *cp, *fc, flagbuf[10];
		const char *addr;
		unsigned long flagbit;
		struct sockaddr_in *sin;

		sin = (struct sockaddr_in *)&r->dst;
		if (sin->sin_addr.s_addr == INADDR_ANY)
			addr = "default";
		else
			addr = inet_ntop (AF_INET, &sin->sin_addr, buf, sizeof buf);
		printf ("%-16s", addr);
		switch (r->un.sa.sa_family) {
		case AF_INET:
			addr = inet_ntop (AF_INET, &r->un.sin.sin_addr, buf, sizeof buf);
			break;

		case AF_LINK:
			addr = link_ascii (&r->un.sdl, buf, sizeof buf);
			break;

		default:
			addr = "";
			break;
		}
		printf ("%-19s", addr);
		fc = "UGHRDM   XLS";
		for (flagbit = 0x1, cp = flagbuf ; *fc ; flagbit <<= 1, fc++) {
			if ((r->flags & flagbit) && (*fc != ' '))
				*cp++ = *fc;
		}
		*cp = '\0';
		printf ("%-10s%3d%9ld%7ld %.*s%d\n", flagbuf,
					r->refcnt, r->pksent,
					r->expire,
					(int)sizeof r->ifname, r->ifname,
					r->ifunit);
	}
	free (d.routes);
}
Пример #30
0
/*
 * Display interface statistics
 */
void
rtems_bsdnet_show_if_stats (void)
{
    struct ifnet *ifp;
    struct ifaddr *ifa;
    unsigned short bit, flags;

    printf ("************ INTERFACE STATISTICS ************\n");
    for (ifp = ifnet; ifp; ifp = ifp->if_next) {
        printf ("***** %s%d *****\n", ifp->if_name, ifp->if_unit);
        for (ifa = ifp->if_addrlist ; ifa ; ifa = ifa->ifa_next) {

            if ( !ifa->ifa_addr )
                continue;

            switch ( ifa->ifa_addr->sa_family ) {
            case AF_LINK:
            {
                struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
                unsigned char *cp = (unsigned char *)LLADDR(sdl);
                int		       i;

                switch ( sdl->sdl_type ) {
                case IFT_ETHER:
                    if ( (i=sdl->sdl_alen) > 0 ) {
                        printf("Ethernet Address: ");
                        do {
                            i--;
                            printf("%02X%c", *cp++, i ? ':' : '\n');
                        } while ( i>0 );
                    }
                    break;

                default:
                    break;
                }
            }
            break;

            case AF_INET:
            {
                int printed;
                printed = showaddress ("Address", ifa->ifa_addr);
                if (ifp->if_flags & IFF_BROADCAST)
                    printed |= showaddress ("Broadcast Address", ifa->ifa_broadaddr);
                if (ifp->if_flags & IFF_POINTOPOINT)
                    printed |= showaddress ("Destination Address", ifa->ifa_dstaddr);
                printed |= showaddress ("Net mask", ifa->ifa_netmask);
                if (printed)
                    printf ("\n");
            }
            break;

            default:
                break;
            }
        }

        printf ("Flags:");
        for (bit = 1, flags = ifp->if_flags ; flags ; bit <<= 1) {
            char *cp;
            char xbuf[20];
            switch (flags & bit) {
            case 0:
                cp = NULL;
                break;
            case IFF_UP:
                cp = "Up";
                break;
            case IFF_BROADCAST:
                cp = "Broadcast";
                break;
            case IFF_DEBUG:
                cp = "Debug";
                break;
            case IFF_LOOPBACK:
                cp = "Loopback";
                break;
            case IFF_POINTOPOINT:
                cp = "Point-to-point";
                break;
            case IFF_RUNNING:
                cp = "Running";
                break;
            case IFF_NOARP:
                cp = "No-ARP";
                break;
            case IFF_PROMISC:
                cp = "Promiscuous";
                break;
            case IFF_ALLMULTI:
                cp = "All-multicast";
                break;
            case IFF_OACTIVE:
                cp = "Active";
                break;
            case IFF_SIMPLEX:
                cp = "Simplex";
                break;
            case IFF_LINK0:
                cp = "Link0";
                break;
            case IFF_LINK1:
                cp = "Link1";
                break;
            case IFF_LINK2:
                cp = "Link2";
                break;
            case IFF_MULTICAST:
                cp = "Multicast";
                break;
            default:
                sprintf (xbuf, "%#x", bit);
                cp = xbuf;
                break;
            }
            if (cp) {
                flags &= ~bit;
                printf (" %s", cp);
            }
        }
        printf ("\n");

        printf ("Send queue limit:%-4d length:%-4d Dropped:%-8d\n",
                ifp->if_snd.ifq_maxlen,
                ifp->if_snd.ifq_len,
                ifp->if_snd.ifq_drops);

        /*
         * FIXME: Could print if_data statistics here,
         *        but right now the drivers maintain their
         *        own statistics.
         */

        /*
         * Grab the network semaphore.
         * In most cases this is not necessary, but it's
         * easier to always call the driver ioctl function
         * while holding the semaphore than to try
         * and explain why some ioctl commands are invoked
         * while holding the semaphore and others are
         * invoked while not holding the semaphore.
         */
        rtems_bsdnet_semaphore_obtain ();
        (*ifp->if_ioctl)(ifp, SIO_RTEMS_SHOW_STATS, NULL);
        rtems_bsdnet_semaphore_release ();
    }
    printf ("\n");
}