Beispiel #1
0
/**
 * Read into a buffer from the UART.
 * @param devptr UART device table entry
 * @param buf buffer to read bytes into
 * @param len size of the buffer
 * @return count of bytes read
 */
devcall uartRead(device *devptr, void *buf, uint len)
{
  int i;
  uchar * buffer = buf;
  for(i = 0; i < len; i++){
    buffer[i] = getc(SERIAL1);
  }
      return OK;
#if 0
    irqmask im;
    int count = 0;
    char c;
    struct uart *uartptr;
    uchar *buffer = buf;

    uartptr = &uarttab[devptr->minor];

    im = disable();

    /* If in non-blocking mode, ensure there is */
    /* enough input for the entire read request */
    if ((uartptr->iflags & UART_IFLAG_NOBLOCK)
        && (semcount(uartptr->isema) < len))
    {
        restore(im);
        return SYSERR;
    }

    /* Put each character into the buffer from the input buffer */
    while (count < len)
    {
        /* If in non-blocking mode, ensure there is another byte of input */
        if ((uartptr->iflags & UART_IFLAG_NOBLOCK)
            && (semcount(uartptr->isema) < 1))
        {
            break;
        }

        /* Wait for input and read character from the  */
        /* input buffer; Preserve the circular buffer  */
        wait(uartptr->isema);
        c = uartptr->in[uartptr->istart];
        *buffer++ = c;
        uartptr->icount--;
        uartptr->istart = (uartptr->istart + 1) % UART_IBLEN;
        count++;

        /* If echo is enabled, echo the character */
        if (uartptr->iflags & UART_IFLAG_ECHO)
        {
	   uartPutc(uartptr->dev, c);
        }
    }

    restore(im);
    return count;
#endif // if 0
}
Beispiel #2
0
bool8 test_checkSemCount(sid32 s, short c, bool8 verbose)
{
    char msg[50];

    if (!isbadsem(s) && c != semcount(s))
    {
        sprintf(msg, "count = %d, not %d", semcount(s), c);
        testFail(verbose, msg);
        return FALSE;
    }
    return TRUE;
}
Beispiel #3
0
/*------------------------------------------------------------------------
 * nbgetbuf - a non-blocking version of getbuf
 *------------------------------------------------------------------------
 */
char	*nbgetbuf(
          bpid32        poolid          /* index of pool in buftab       */
	)
{
	intmask	mask;
	char	*buf;

	mask = disable();

	/* Check arguments */

	if ( (poolid < 0  ||  poolid >= nbpools) ) {
		restore(mask);
		return (char *)SYSERR;

	}

	/* If the call will block, return an error */

	if (semcount(buftab[poolid].bpsem) <= 0) {
		restore(mask);
		return (char *)SYSERR;
	}
	buf = getbuf(poolid);
	restore(mask);
	return buf;
}
Beispiel #4
0
/*------------------------------------------------------------------------
 * pipread  --  Read from a pipe, blocking if empty
 *------------------------------------------------------------------------
 */
syscall	pipread(
		pipid32		pip,		/* ID of pipe to read from			*/
		char 		*buf,		/* pointer to buffer to read to		*/
		uint32		len			/* number of bytes to read 			*/
	)
{
	intmask	mask;				/* saved interrupt mask				*/

	mask = disable();

	if (isbadpip(pip)) {
		restore(mask);
		return SYSERR;
	}

	struct pentry *pipptr;		/* ptr to pipe table entry			*/
	
	pipptr = &piptab[pip];
	if (pipptr->pstate != PIPE_CONNECTED ||
		(pipptr->pend1 != getpid() && pipptr->pend2 != getpid())) {
		restore(mask);
		return SYSERR;
	}

	/* Ensure there is enough space for the entire read request */
	if (semcount(pipptr->prdsem) < len) {
		restore(mask);
		return SYSERR;
	}

	char *buffer = buf;			/* local copy of buffer				*/
	int count = 0;				/* character count for buffer		*/
	char c;						/* temporary space for characters	*/

	/* Read characters from the circular buffer */
	while (count < len)
	{
		wait(pipptr->prdsem);

		c = pipptr->pbuf[pipptr->pbufs];
		*buffer++ = c;
		pipptr->pbufc--;
		pipptr->pbufs = (pipptr->pbufs + 1) % PIPE_SIZ;
		count++;

		signal(pipptr->pwrsem);
	}

	restore(mask);
	return count;
}
Beispiel #5
0
/*------------------------------------------------------------------------
 * pipwrite  --  Write to a pipe, blocking if full
 *------------------------------------------------------------------------
 */
syscall	pipwrite(
		pipid32		pip,		/* ID of pipe to write to			*/
		char 		*buf,		/* pointer to buffer to write from	*/
		uint32		len			/* number of bytes to write			*/
	)
{
	intmask	mask;				/* saved interrupt mask				*/

	mask = disable();

	if (isbadpip(pip)) {
		restore(mask);
		return SYSERR;
	}

	struct pentry *pipptr;		/* ptr to pipe table entry			*/
	
	pipptr = &piptab[pip];
	if (pipptr->pstate != PIPE_CONNECTED ||
		(pipptr->pend1 != getpid() && pipptr->pend2 != getpid())) {
		restore(mask);
		return SYSERR;
	}

	/* Ensure there is enough space for the entire write request */
	if (semcount(pipptr->pwrsem) < len) {
		restore(mask);
		return SYSERR;
	}

	char *buffer = buf;			/* local copy of buffer				*/
	int count = 0;				/* character count for buffer		*/

	/* Write characters to the circular buffer */
	while (count < len)
	{
		wait(pipptr->pwrsem);
		
		pipptr->pbuf[(pipptr->pbufs + pipptr->pbufc) % PIPE_SIZ] = *buffer++;
		count++;
		pipptr->pbufc++;
	
		signal(pipptr->prdsem);
	}

	restore(mask);
	return count;
}
Beispiel #6
0
/**
 * HTTP server thread
 * @param host IP address of interface on which to listen
 * @param gentcpdev the allocated tcp device for general listening
 * @return OK or SYSERR
 */
thread httpServer(int netDescrp, int gentcpdev)
{
    tid_typ shelltid, killtid;
    int tcpdev, httpdev;
    char thrname[TNMLEN];
    bool noGenHTTP;
    struct netaddr *host;
    struct netif *nif;

    enable();

    noGenHTTP = FALSE;
    wait(maxhttp);              /* Make sure max HTTP threads not reached */

    /* Allocate HTTP device */
    httpdev = httpAlloc();

    /* Received bad http device, close out allocated resources */
    if (isbadhttp(httpdev))
    {
        printf("failed to allocate proper HTTP device\n");
        signal(maxhttp);
        return SYSERR;
    }

    /* Back up the general tcpdev number */
    tcpdev = gentcpdev;

    /* Look up the network descriptor */
    nif = netLookup(netDescrp);
    if (SYSERR == (int)nif)
    {
        fprintf(stderr, "%s is not associated with an active network",
                devtab[netDescrp].name);
        fprintf(stderr, " interface.\n");
        return SYSERR;
    }
    host = &(nif->ip);

    /* Open HTTP device */
    if (SYSERR == (long)open(httpdev, tcpdev))
    {
        fprintf(stderr, "httpOpen SYSERR\n");
        close(tcpdev);
        close(httpdev);
        return SYSERR;
    }

    /* Create web shell */
    sprintf(thrname, "XWebShell_%d\0", (devtab[tcpdev].minor));
    shelltid = create((void *)shell, INITSTK, INITPRIO, thrname, 3,
                      httpdev, httpdev, DEVNULL);
    if (isbadtid(shelltid))
    {
        fprintf(stderr, "shell creation bad tid\n");
        close(httpdev);
        close(tcpdev);
        return SYSERR;
    }

    /* Spawn thread that will wait for kill httpserver thread signal */
    sprintf(thrname, "XWebKillerD_%d\0", (devtab[tcpdev].minor));
    killtid = create((void *)killHttpServer, INITSTK, INITPRIO, thrname,
                     3, httpdev, shelltid, tcpdev);

    /* Ready spawned threads */
    ready(shelltid, RESCHED_NO);
    ready(killtid, RESCHED_NO);

    /* Open TCP device */
    if (SYSERR ==
        (long)open(tcpdev, host, NULL, HTTP_LOCAL_PORT, NULL,
                   TCP_PASSIVE))
    {
        int temp;
        sleep(TCP_TWOMSL + 500);
        if (SYSERR ==
            (temp = (long)open(tcpdev, host, NULL, HTTP_LOCAL_PORT, NULL,
                               TCP_PASSIVE)))
        {
            fprintf(CONSOLE, "open returns: %d\n", temp);
            fprintf(stderr, "tcpOpen SYSERR, devnum: %d\n", tcpdev);
            kill(shelltid);
            close(tcpdev);
            close(httpdev);
            return SYSERR;
        }
        fprintf(CONSOLE, "open returns: %d\n", temp);
    }

    /* Allocate TCP device */
    gentcpdev = tcpAlloc();
    if (isbadtcp(gentcpdev))
    {
        /* Wait for a free http device */
        wait(maxhttp);

        /* Acquire a TCP device through allocation */
        while ((ushort)SYSERR == (gentcpdev = tcpAlloc()))
        {
            /* Do nothing, yield processor */
            yield();
        }

        /* Everything acquired, spawn general http device listener */
        if (semcount(activeXWeb) <= 0)
        {
            sprintf(thrname, "XWeb_%d\0", (devtab[gentcpdev].minor));
            ready(create((void *)httpServer, INITSTK, INITPRIO,
                         thrname, 2, netDescrp, gentcpdev), RESCHED_NO);
        }

        /* Did not consume http device, just waited for availability */
        signal(maxhttp);
    }
    else
    {
        sprintf(thrname, "XWeb_%d\0", (devtab[gentcpdev].minor));
        ready(create((void *)httpServer, INITSTK, INITPRIO,
                     thrname, 2, netDescrp, gentcpdev), RESCHED_NO);
    }

    return OK;
}
Beispiel #7
0
/**
 * Read into a buffer from TCP.
 * @param devptr TCP device table entry
 * @param buf buffer to read octets into
 * @param len size of the buffer
 * @return count of octets read
 */
devcall tcpRead(device *devptr, void *buf, uint len)
{
    int count = 0;
    struct tcb *tcbptr;
    int check;
    char *buffer = buf;

    tcbptr = &tcptab[devptr->minor];

    wait(tcbptr->mutex);

    /* Handle states for which no data will ever be received */
    check = stateCheck(tcbptr);
    if (check != OK)
    {
        return SYSERR;
//        return check; 
    }

    signal(tcbptr->mutex);

    /* Put each octet into the buffer from the input buffer */
    while (count < len)
    {
        /* Wait for input or FIN */
        wait(tcbptr->readers);
        wait(tcbptr->mutex);

        /* Return if changed to a state where no data will ever be recvd */
        check = stateCheck(tcbptr);
        if (check != OK)
        {
            return SYSERR;
//            return check; 
        }

        /* Read as much as possible from the input buffer 
         * Preserve the circular buffer  */
        while ((tcbptr->icount > 0) && (count < len))
        {
            *buffer++ = tcbptr->in[tcbptr->istart];
            tcbptr->imark[tcbptr->istart] = FALSE;
            tcbptr->istart = (tcbptr->istart + 1) % TCP_IBLEN;
            tcbptr->icount--;
            count++;
        }

#ifdef TCP_GRACIOUSACK
        /* Send gracious acknowledgement if window has increaed */
        if (seqlte(tcbptr->rcvwnd, tcbptr->rcvnxt))
        {
            if (tcpSendWindow(tcbptr) > 0)
            {
                tcpSendAck(tcbptr);
            }
        }
#endif

        /* If data remains, another reader can read */
        if ((tcbptr->icount > 0) && (semcount(tcbptr->readers) < 1))
        {
            signal(tcbptr->readers);
        }

        signal(tcbptr->mutex);
    }

    return count;
}
Beispiel #8
0
process	rawin (void) {

	status	retval;			/* return value from function	*/
	struct	netpacket *pkt;		/* packet buffer being used now	*/
	int32	nbufs;			/* total number of buffers	*/
	struct	ifentry	*ifptr;		/* ptr to interface table entry	*/
	int32	iface;			/* index into interface table	*/

	/* Global buffer pool shared by all interfaces */

	nbufs = UDP_SLOTS * UDP_QSIZ + ICMP_SLOTS * ICMP_QSIZ
				+ NIFACES * IF_QUEUESIZE + 1;
	netbufpool = mkbufpool(PACKLEN, nbufs);

	if (netbufpool == SYSERR) {
		kprintf("Cannot allocate network buffer pool\n");
		kill(getpid());
	}

	open(ETHER0, NULL, NULL);

	pkt = (struct netpacket *)getbuf(netbufpool);
	while(1) {
	    	retval = read(ETHER0, (char *)pkt, PACKLEN);
	    	if (retval == SYSERR) {
			panic("Ethernet read error");
	    	}

		/* Demultiplex on MAC address */

		for (iface=0; iface<=NIFACES; iface++) {
		    ifptr = &if_tab[iface];
		    if (ifptr->if_state != IF_UP) {
			continue;
		    }
		    if ( (memcmp(ifptr->if_macucast, pkt->net_ethdst,
				ETH_ADDR_LEN) == 0) ||
			 (memcmp(ifptr->if_macbcast, pkt->net_ethdst,
				ETH_ADDR_LEN) == 0)) {

			/* packet goes to this interface */

			/* Check interface queue; drop packet if full	*/
									
			if (semcount(ifptr->if_sem) >= IF_QUEUESIZE) {
				kprintf("rawin: queue overflow on %d\n", iface);
				break;
			}

			/* Enqueue packet and signal semaphore */

			ifptr->if_queue[ifptr->if_tail++] = pkt;
			if (ifptr->if_tail >= IF_QUEUESIZE) {
				ifptr->if_tail = 0;
			}
			signal(ifptr->if_sem);

			/* Obtain a buffer for the next packet */

			pkt = (struct netpacket *)getbuf(netbufpool);
			break;
		    }
		}
	}
}
Beispiel #9
0
/*------------------------------------------------------------------------
 *  ttyInter_in  --  handle one arriving char (interrupts disabled)
 *------------------------------------------------------------------------
 */
void	ttyInter_in (
	  struct ttycblk *typtr,	/* ptr to ttytab entry		*/
	  struct uart_csreg *uptr	/* address of UART's CSRs	*/
	)
{
	char	ch;			/* next char from device	*/
	int32	avail;			/* chars available in buffer	*/

	ch = uptr->buffer;		/* extract char. from device	*/

	/* Compute chars available */

	avail = semcount(typtr->tyisem);
	if (avail < 0) {		/* one or more processes waiting*/
		avail = 0;
	}

	/* Handle raw mode */

	if (typtr->tyimode == TY_IMRAW) {
		if (avail >= TY_IBUFLEN) { /* no space => ignore input	*/
			return;
		}

		/* Place char in buffer with no editing */

		*typtr->tyitail++ = ch;

		/* Wrap buffer pointer	*/

		if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
			typtr->tyitail = typtr->tyibuff;
		}

		/* Signal input semaphore and return */

		signal(typtr->tyisem);
		return;
	}

	/* Handle cooked and cbreak modes (common part) */

	if ( (ch == TY_RETURN) && typtr->tyicrlf ) {
		ch = TY_NEWLINE;
	}

	/* If flow control is in effect, handle ^S and ^Q */

	if (typtr->tyoflow) {
		if (ch == typtr->tyostart) {	    /* ^Q starts output	*/
			typtr->tyoheld = FALSE;
			ttyKickOut(typtr, uptr);
			return;
		} else if (ch == typtr->tyostop) {  /* ^S stops	output	*/
			typtr->tyoheld = TRUE;
			return;
		}
	}

	typtr->tyoheld = FALSE;		/* Any other char starts output	*/

	if (typtr->tyimode == TY_IMCBREAK) {	   /* Just cbreak mode	*/

		/* If input buffer is full, send bell to user */

		if (avail >= TY_IBUFLEN) {
			eputc(typtr->tyifullc, typtr, uptr);
		} else {	/* Input buffer has space for this char */
			*typtr->tyitail++ = ch;

			/* Wrap around buffer */

			if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
				typtr->tyitail = typtr->tyibuff;
			}
			if (typtr->tyiecho) {	/* are we echoing chars?*/
				echoch(ch, typtr, uptr);
			}
		}
		return;

	} else {	/* Just cooked mode (see common code above)	*/

		/* Line kill character arrives - kill entire line */

		if (ch == typtr->tyikillc && typtr->tyikill) {
			typtr->tyitail -= typtr->tyicursor;
			if (typtr->tyitail < typtr->tyibuff) {
				typtr->tyihead += TY_IBUFLEN;
			}
			typtr->tyicursor = 0;
			eputc(TY_RETURN, typtr, uptr);
			eputc(TY_NEWLINE, typtr, uptr);
			return;
		}

		/* Erase (backspace) character */

		if ( (ch == typtr->tyierasec) && typtr->tyierase) {
			if (typtr->tyicursor > 0) {
				typtr->tyicursor--;
				erase1(typtr, uptr);
			}
			return;
		}

		/* End of line */

		if ( (ch == TY_NEWLINE) || (ch == TY_RETURN) ) {
			if (typtr->tyiecho) {
				echoch(ch, typtr, uptr);
			}
			*typtr->tyitail++ = ch;
			if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
				typtr->tyitail = typtr->tyibuff;
			}

			/*  Make entire line (plus \n or \r) available */

			signaln(typtr->tyisem, typtr->tyicursor + 1);
			typtr->tyicursor = 0; 	/* Reset for next line	*/
			return;
		}

		/* Character to be placed in buffer - send bell if	*/
		/*	buffer has overflowed				*/

		avail = semcount(typtr->tyisem);
		if (avail < 0) {
			avail = 0;
		}
		if ((avail + typtr->tyicursor) >= TY_IBUFLEN-1) {
			eputc(typtr->tyifullc, typtr, uptr);
			return;
		}

		/* EOF character: recognize at beginning of line, but	*/
		/*	print and ignore otherwise.			*/

		if (ch == typtr->tyeofch && typtr->tyeof) {
			if (typtr->tyiecho) {
				echoch(ch, typtr, uptr);
			}
			if (typtr->tyicursor != 0) {
				return;
			}
			*typtr->tyitail++ = ch;
			signal(typtr->tyisem);
			return;			
		}


		/* Echo the character */

		if (typtr->tyiecho) {
			echoch(ch, typtr, uptr);
		}

		/* Insert character in the input buffer */

		typtr->tyicursor++;
		*typtr->tyitail++ = ch;

		/* Wrap around if needed */

		if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
			typtr->tyitail = typtr->tyibuff;
		}
		return;
	}
}
Beispiel #10
0
/*------------------------------------------------------------------------
 * rdswrite  -  Write a block to a remote disk
 *------------------------------------------------------------------------
 */
devcall	rdswrite (
	  struct dentry	*devptr,	/* Entry in device switch table	*/
	  char	*buff,			/* Buffer that holds a disk blk	*/
	  int32	blk			/* Block number to write	*/
	)
{
	struct	rdscblk	*rdptr;		/* Pointer to control block	*/
	struct	rdbuff	*bptr;		/* Pointer to buffer on a list	*/
	struct	rdbuff	*pptr;		/* Ptr to previous buff on list	*/
	struct	rdbuff	*nptr;		/* Ptr to next buffer on list	*/
	bool8	found;			/* Was buff found during search?*/

	/* If device not currently in use, report an error */

	rdptr = &rdstab[devptr->dvminor];
	if (rdptr->rd_state != RD_OPEN) {
		return SYSERR;
	}

	/* Ensure rdsprocess is runnning */

	if ( ! rdptr->rd_comruns ) {
		rdptr->rd_comruns = TRUE;
		resume(rdptr->rd_comproc);
	}

	/* If request queue already contains a write request */
	/*    for the block, replace the contents	     */

	bptr = rdptr->rd_rhnext;
	while (bptr != (struct rdbuff *)&rdptr->rd_rtnext) {
		if ( (bptr->rd_blknum == blk) &&
			(bptr->rd_op == RD_OP_WRITE) ) {
			memcpy(bptr->rd_block, buff, RD_BLKSIZ);
			return OK;
		}
		bptr = bptr->rd_next;
	}

	/* Search cache for cached copy of block */

	bptr = rdptr->rd_chnext;
	found = FALSE;
	while (bptr != (struct rdbuff *)&rdptr->rd_ctnext) {
		if (bptr->rd_blknum == blk) {
			if (bptr->rd_refcnt <= 0) {
				pptr = bptr->rd_prev;
				nptr = bptr->rd_next;

				/* Unlink node from cache list and reset*/
				/*   the available semaphore accordingly*/

				pptr->rd_next = bptr->rd_next;
				nptr->rd_prev = bptr->rd_prev;
				semreset(rdptr->rd_availsem,
					semcount(rdptr->rd_availsem) - 1);
				found = TRUE;
			}
			break;
		}
		bptr = bptr->rd_next;
	}

	if ( !found ) {
		bptr = rdsbufalloc(rdptr);
	}

	/* Create a write request */

	memcpy(bptr->rd_block, buff, RD_BLKSIZ);
	bptr->rd_op = RD_OP_WRITE;
	bptr->rd_refcnt = 0;
	bptr->rd_blknum = blk;
	bptr->rd_status = RD_VALID;
	bptr->rd_pid = getpid();

	/* Insert new request into list just before tail */

	pptr = rdptr->rd_rtprev;
	rdptr->rd_rtprev = bptr;
	bptr->rd_next = pptr->rd_next;
	bptr->rd_prev = pptr;
	pptr->rd_next = bptr;

	/* Signal semaphore to start communication process */

	signal(rdptr->rd_reqsem);
	return OK;
}
Beispiel #11
0
/**
 * Tests raw sockets.
 * @return OK when testing is complete
 */
thread test_raw(bool verbose)
{
#if RAW0
    /* the failif macro depends on 'passed' and 'verbose' vars */
    bool passed = TRUE;
    device *devptr;
    struct raw *rawptr;
    struct netif *netptr;
    struct netaddr lip;
    struct netaddr rip;
    struct netaddr mask;
    struct packet *pkt;
    struct packet *pktA;
    struct pcap_pkthdr phdr;
    struct pcap_file_header pcap;
    uchar *data;
    uchar buf[500];
    int nproc;
    int wait;
    int i;

    lip.type = NETADDR_IPv4;
    lip.len = IPv4_ADDR_LEN;
    lip.addr[0] = 192;
    lip.addr[1] = 168;
    lip.addr[2] = 1;
    lip.addr[3] = 6;

    rip.type = NETADDR_IPv4;
    rip.len = IPv4_ADDR_LEN;
    rip.addr[0] = 192;
    rip.addr[1] = 168;
    rip.addr[2] = 1;
    rip.addr[3] = 1;

    mask.type = NETADDR_IPv4;
    mask.len = IPv4_ADDR_LEN;
    mask.addr[0] = 255;
    mask.addr[1] = 255;
    mask.addr[2] = 255;
    mask.addr[3] = 0;

    /* Initialization */
    testPrint(verbose, "Test case initialization");
    data = (uchar *)(&_binary_data_testraw_pcap_start);
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);
    if (SYSERR == open(ELOOP))
    {
        failif(TRUE, "");
    }
    else
    {
        if (SYSERR == netUp(ELOOP, &lip, &mask, NULL))
        {
            close(ELOOP);
            failif(TRUE, "");
        }
        else
        {
            netptr = NULL;
            for (i = 0; i < NNETIF; i++)
            {
                if (ELOOP == netiftab[i].dev)
                {
                    netptr = &netiftab[i];
                    break;
                }
            }
            pkt = netGetbuf();
            failif(((NULL == netptr) || (SYSERR == (int)pkt)), "");
        }
    }
    if (!passed)
    {
        testFail(TRUE, "");
        return OK;
    }

    /* Test Open */
    testPrint(verbose, "Open RAW (Proto Only)");
    rawptr = NULL;
    if (SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_ALLOC)
                || (rawptr->dev != devptr)
                || (rawptr->proto != IPv4_PROTO_ICMP)
                || (rawptr->localip.type != NULL)
                || (rawptr->remoteip.type != NULL)
                || (rawptr->icount != 0)
                || (rawptr->istart != 0)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->flags != 0)), "Incorrect control block");
    }

    testPrint(verbose, "Open RAW (Already Open)");
    failif((SYSERR != open(RAW0, NULL, NULL, IPv4_PROTO_ICMP)),
           "Double open() succeeded");

    /* Test Control */
    testPrint(verbose, "Control (Closed Socket)");
    failif((control(RAW1, RAW_CTRL_SETFLAG, NULL, NULL) != SYSERR), "");

    testPrint(verbose, "Control (Bad Params)");
    failif((control(RAW0, -1, NULL, NULL) != SYSERR), "");

    testPrint(verbose, "Control (Set Flag)");
    failif(((NULL != control(RAW0, RAW_CTRL_SETFLAG,
                             (RAW_IACCEPT | RAW_IHDR), NULL))
            || (0 == (rawptr->flags & RAW_IACCEPT))
            || (0 == (rawptr->flags & RAW_IHDR))), "");

    testPrint(verbose, "Control (Clear Flag)");
    failif(((RAW_IHDR != control(RAW0, RAW_CTRL_CLRFLAG,
                                 RAW_IHDR, NULL))
            || (0 == (rawptr->flags & RAW_IACCEPT))
            || (1 == (rawptr->flags & RAW_IHDR))), "");

    /* Test Close */
    testPrint(verbose, "Close RAW");
    if (SYSERR == close(RAW0))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_FREE)
                || (rawptr->dev != NULL)), "Control block not clear");
    }

    testPrint(verbose, "Close RAW (Already Closed)");
    failif((SYSERR != close(RAW0)), "Did not SYSERR");

    /* Test demux */
    testPrint(verbose, "Demulitplexing (No sockets)");
    failif((NULL != rawDemux(&rip, &lip, IPv4_PROTO_ICMP)), "");

    testPrint(verbose, "Demulitplexing (All Protos)");
    if ((SYSERR == open(RAW0, &lip, &rip, IPv4_PROTO_IGMP))
        || (SYSERR == open(RAW1, NULL, NULL, NULL)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Proto)");
    if ((SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, NULL, NULL, IPv4_PROTO_IGMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Remote IP)");
    if ((SYSERR == open(RAW0, NULL, NULL, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, NULL, &rip, IPv4_PROTO_ICMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    testPrint(verbose, "Demulitplexing (Local IP)");
    if ((SYSERR == open(RAW0, NULL, &rip, IPv4_PROTO_ICMP))
        || (SYSERR == open(RAW1, &lip, &rip, IPv4_PROTO_ICMP)))
    {
        failif(TRUE, "Open failed");
    }
    else
    {
        devptr = (device *)&devtab[RAW1];
        rawptr = &rawtab[devptr->minor];
        if (rawptr != rawDemux(&rip, &lip, IPv4_PROTO_ICMP))
        {
            failif(TRUE, "Incorrect socket");
        }
        else
        {
            failif(((SYSERR == close(RAW0)) || (SYSERR == close(RAW1))),
                   "Close failed");
        }
    }

    /* Test Open */
    testPrint(verbose, "Open RAW (Full Spec)");
    if (SYSERR == open(RAW0, &lip, &rip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(((rawptr->state != RAW_ALLOC)
                || (rawptr->dev != devptr)
                || (rawptr->proto != IPv4_PROTO_ICMP)
                || (FALSE == netaddrequal(&lip, &rawptr->localip))
                || (FALSE == netaddrequal(&rip, &rawptr->remoteip))
                || (rawptr->icount != 0)
                || (rawptr->istart != 0)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->flags != 0)), "Incorrect control block");
    }

    /* Test receive */
    testPrint(verbose, "Receive (Bad Params)");
    /* Get 1st packet */
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    pkt->len = phdr.caplen;
    memcpy(pkt->data, data, phdr.caplen);
    pkt->linkhdr = pkt->data;
    pkt->nethdr = pkt->linkhdr + ETH_HDR_LEN;
    pkt->curr = pkt->nethdr + IPv4_HDR_LEN;
    failif(((SYSERR != rawRecv(NULL, NULL, NULL, NULL))
            || (SYSERR != rawRecv(pkt, &rip, NULL, NULL))), "");

    testPrint(verbose, "Receive (No Match)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_IGMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        failif(((rawptr->icount != 0)
                || (semcount(rawptr->isema) != 0)
                || (TRUE == netaddrequal(&rawptr->src[0], &rip))
                || (rawptr->in[0] == pktA)), "Packet enqueued");

    }

    testPrint(verbose, "Receive (One Pkt)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        failif(((rawptr->istart != 0)
                || (rawptr->icount != 1)
                || (semcount(rawptr->isema) != 1)
                || (FALSE == netaddrequal(&rawptr->src[0], &rip))
                || (rawptr->in[0] != pktA)), "Incorrectly enqueued");
    }

    testPrint(verbose, "Read (Closed socket)");
    failif((SYSERR != read(RAW1, buf, 500)), "");

    testPrint(verbose, "Read (One Pkt)");
    failif(((read(RAW0, buf, 500) != 8)
            || (memcmp(buf, (pkt->data + ETH_HDR_LEN + IPv4_HDR_LEN), 8)
                != 0)
            || (rawptr->icount != 0)
            || (rawptr->istart != 1)
            || (semcount(rawptr->isema) != 0)
            || (rawptr->in[0] != NULL)), "");

    testPrint(verbose, "Read (Include header)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    rawptr->flags = RAW_IHDR;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 500) != (IPv4_HDR_LEN + 8))
                ||
                (memcmp(buf, (pkt->data + ETH_HDR_LEN), IPv4_HDR_LEN + 8)
                 != 0) || (rawptr->icount != 0) || (rawptr->istart != 2)
                || (semcount(rawptr->isema) != 0)
                || (rawptr->in[0] != NULL)), "");
    }


    testPrint(verbose, "Read (Accept)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    rawptr->flags = RAW_IACCEPT;
    rawptr->remoteip.type = NULL;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 500) != 8)
                || (FALSE == netaddrequal(&rawptr->remoteip, &rip))), "");
    }

    testPrint(verbose, "Read (Small buf)");
    pktA = netGetbuf();
    memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
    pktA->linkhdr = pktA->data;
    pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
    pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
    if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Recv returned SYSERR");
    }
    else
    {
        failif(((read(RAW0, buf, 2) != 2)
                ||
                (memcmp(buf, (pkt->data + ETH_HDR_LEN + IPv4_HDR_LEN), 2)
                 != 0)), "");
    }

    testPrint(verbose, "Receive (Full buf)");
    for (i = 0; i < RAW_IBLEN; i++)
    {
        memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
        pktA->linkhdr = pktA->data;
        pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
        pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
        if (SYSERR == rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP))
        {
            break;
        }
    }
    if (i < RAW_IBLEN)
    {
        failif(TRUE, "Unable to fill buffer");
    }
    else
    {
        memcpy(pktA, pkt, sizeof(struct packet) + pkt->len);
        pktA->linkhdr = pktA->data;
        pktA->nethdr = pktA->linkhdr + ETH_HDR_LEN;
        pktA->curr = pktA->nethdr + IPv4_HDR_LEN;
        failif((SYSERR != rawRecv(pktA, &rip, &lip, IPv4_PROTO_ICMP)),
               "Did not return SYSERR");
    }

    testPrint(verbose, "Close RAW");
    failif((SYSERR == close(RAW0)), "");

    /* Test Write/Send */
    testPrint(verbose, "Open RAW");
    if (SYSERR == open(RAW0, &lip, NULL, IPv4_PROTO_ICMP))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        devptr = (device *)&devtab[RAW0];
        rawptr = &rawtab[devptr->minor];
        failif(FALSE, "");
    }

    testPrint(verbose, "Send (Bad Params)");
    failif((rawSend(NULL, NULL, 0) != SYSERR), "");

    testPrint(verbose, "Send (Incomplete Spec)");
    failif((rawSend(rawptr, pkt->curr, 8) != SYSERR), "");

    testPrint(verbose, "Send (Incomplete Spec Hdr Inc)");
    rawptr->flags = RAW_OHDR;
    failif((rawSend(rawptr, pkt->curr, 8) != SYSERR), "");

    testPrint(verbose, "Send (Net Hdr Included)");
    /* Add ARP entry */
    /* Get 2nd Packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Get 3rd Packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    memcpy(pkt->data, data, phdr.caplen);
    pkt->len = phdr.caplen;
    pkt->linkhdr = pkt->data;
    pkt->nethdr = pkt->linkhdr + ETH_HDR_LEN;
    pkt->curr = pkt->nethdr + IPv4_HDR_LEN;
    /* Wait for ARP entry to be added */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(10);
    }
    if (MAX_WAIT == wait)
    {
        failif(MAX_WAIT, "ARP entry failed");
    }
    else
    {
        netaddrcpy(&rawptr->remoteip, &rip);
        control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
        if (SYSERR == rawSend(rawptr, pkt->nethdr, IPv4_HDR_LEN + 8))
        {
            failif(TRUE, "Returned SYSERR");
        }
        else
        {
            control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
            failif((memcmp(pkt->data, buf, pkt->len) != 0),
                   "Incorrect Packet");
        }
    }

    testPrint(verbose, "Send");
    rawptr->flags = NULL;
    netaddrcpy(&rawptr->remoteip, &rip);
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == rawSend(rawptr, pkt->curr, 8))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
        failif((memcmp(pkt->data, buf, pkt->len) != 0),
               "Incorrect Packet");
    }

    testPrint(verbose, "Write");
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == write(RAW0, pkt->curr, 8))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (long)buf, 500);
        failif((memcmp(pkt->data, buf, pkt->len) != 0),
               "Incorrect Packet");
    }

    close(RAW0);
    netDown(ELOOP);
    close(ELOOP);

    /* always print out the overall tests status */
    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }
#endif                          /* RAW0 */
    return OK;
}
Beispiel #12
0
/*------------------------------------------------------------------------
 *  ttyInter_out - handle an output on a tty device by sending more
 *		    characters to the device FIFO (interrupts disabled)
 *------------------------------------------------------------------------
 */
void	ttyInter_out(
	 struct	ttycblk	*typtr,		/* ptr to ttytab entry		*/
	 struct	uart_csreg *csrptr	/* address of UART's CSRs	*/
	)
{
	
	int32	ochars;			/* number of output chars sent	*/
					/*   to the UART		*/
	int32	avail;			/* available chars in output buf*/
	int32	uspace;			/* space left in onboard UART	*/
					/*   output FIFO		*/
	byte 	ier = 0;

	/* If output is currently held, simply ignore the call */

	if (typtr->tyoheld) {
		inb( (int)&csrptr->lsr ); /* Clear the interrupt */
		return;
	}

	/* If echo and output queues empty, turn off interrupts */

	if ( (typtr->tyehead == typtr->tyetail) &&
	     (semcount(typtr->tyosem) >= TY_OBUFLEN) ) {
		ier = inb((int)&csrptr->ier);
		outb((int)&csrptr->ier, ier & ~UART_IER_ETBEI);
		return;
	}
	
	/* Initialize uspace to the size of the transmit FIFO */

	uspace = UART_FIFO_SIZE;

	/* While onboard FIFO is not full and the echo queue is	*/
	/* nonempty, xmit chars from the echo queue		*/
  
	while ( (uspace>0) &&  typtr->tyehead != typtr->tyetail) {
		outb( (int)&csrptr->buffer, *typtr->tyehead++);
		if (typtr->tyehead >= &typtr->tyebuff[TY_EBUFLEN]) {
			typtr->tyehead = typtr->tyebuff;
		}
		uspace--;
	}

	/* While onboard FIFO is not full and the output queue	*/
	/* is nonempty,	xmit chars from the output queue	*/

	ochars = 0;
	avail = TY_OBUFLEN - semcount(typtr->tyosem);
	while ( (uspace>0) &&  (avail > 0) ) {
		outb( (int)&csrptr->buffer, *typtr->tyohead++ );
		if (typtr->tyohead >= &typtr->tyobuff[TY_OBUFLEN]) {
			typtr->tyohead = typtr->tyobuff;
		}
		avail--;
		uspace--;
		ochars++;
	}
	if (ochars > 0) {
		signaln(typtr->tyosem, ochars);
	}
	return;
}
Beispiel #13
0
/**
 * Write a buffer to the UART.
 *
 * @param devptr  pointer to UART device
 * @param buf   buffer of characters to write
 * @param len   number of characters to write from the buffer
 */
devcall uartWrite(device *devptr, void *buf, uint len)
{
    irqmask im;
    int count = 0;
    struct uart *uartptr;
    volatile struct uart_csreg *regptr;
    uchar *buffer = buf;

    uartptr = &uarttab[devptr->minor];
    regptr = (struct uart_csreg *)uartptr->csr;
    if (NULL == regptr)
    {
        return SYSERR;
    }

    im = disable();

    /* If in non-blocking mode, ensure there is enough space for the entire
     * write request */
    if ((uartptr->oflags & UART_OFLAG_NOBLOCK)
        && (semcount(uartptr->osema) < len))
    {
        restore(im);
        return SYSERR;
    }

    /* Put each character from the buffer into the output buffer for the
     * lower half */
    while (count < len)
    {
        /* If in non-blocking mode, ensure there is another byte of space
         * for output */
        if ((uartptr->oflags & UART_OFLAG_NOBLOCK)
            && (semcount(uartptr->osema) < 1))
        {
            break;
        }

        /* If the UART transmitter hardware is idle, write directly to the
         * hardware */
        if (uartptr->oidle)
        {
            uartptr->oidle = FALSE;
            regptr->thr = *buffer++;
            count++;
            uartptr->cout++;
        }
        /* Wait for space and place character in the output buffer for the
         * lower half; Preserve the circular buffer */
        else
        {
            wait(uartptr->osema);
            uartptr->out[(uartptr->ostart +
                          uartptr->ocount) % UART_OBLEN] = *buffer++;
            count++;
            uartptr->ocount++;
        }
    }

    restore(im);
    return count;
}
/*------------------------------------------------------------------------
 *  ttyInter_out - handle an output on a tty device by sending more
 *		    characters to the device FIFO (interrupts disabled)
 *------------------------------------------------------------------------
 */
void	ttyInter_out(
	 struct	ttycblk	*typtr,		/* ptr to ttytab entry		*/
	 struct	uart_csreg *uptr	/* address of UART's CSRs	*/
	)
{
	
	int32	ochars;			/* number of output chars sent	*/
					/*   to the UART		*/
	int32	avail;			/* available chars in output buf*/
	int32	uspace;			/* space left in onboard UART	*/
					/*   output FIFO		*/

	/* If output is currently held, turn off output interrupts */

	if (typtr->tyoheld) {
		uptr->uart_int_en &= (~UART_TX_EMPTY_INT_EN);
		return;
	}

        /* If echo and output queues empty, turn off output interrupts */

	if ( (typtr->tyehead == typtr->tyetail) &&
	     (semcount(typtr->tyosem) >= TY_OBUFLEN) ) {
		uptr->uart_int_en &= (~UART_TX_EMPTY_INT_EN);
		return;
	}
	
	/* Initialize uspace to the size of the transmit FIFO */

	uspace = UART_FIFO_SIZE;

	/* While onboard FIFO is not full and the echo queue is	*/
	/* nonempty, xmit chars from the echo queue		*/

	while ( (uspace>0) &&  typtr->tyehead != typtr->tyetail) {
		uptr->uart_data = ((*typtr->tyehead++) | UART_TX_CSR);
		if (typtr->tyehead >= &typtr->tyebuff[TY_EBUFLEN]) {
			typtr->tyehead = typtr->tyebuff;
		}
		uspace--;
	}

	/* While onboard FIFO is not full and the output queue	*/
	/* is nonempty,	xmit chars from the output queue	*/

	ochars = 0;
	avail = TY_OBUFLEN - semcount(typtr->tyosem);
	while ( (uspace>0) &&  (avail > 0) ) {
		uptr->uart_data = ((*typtr->tyohead++) | UART_TX_CSR);
		if (typtr->tyohead >= &typtr->tyobuff[TY_OBUFLEN]) {
			typtr->tyohead = typtr->tyobuff;
		}
		avail--;
		uspace--;
		ochars++;
	}
	if (ochars > 0) {
		signaln(typtr->tyosem, ochars);
	}
	return;
}