Пример #1
0
targeter()
{

    while (TRUE) {
	recvclr();
	targetx = (rand() % (XMAXFIELD-6)) + 2;
	targety = (rand() % (YMAXFIELD-6)) + 2;
	targetvalue=(rand() % 9)+1;
	newsend(pidplotter,3,targetx,targety,targetvalue+48 );
	resume(pidtimer = create(removetarget,200,13,"remover",0));
	if (receive() != REMOVE)
	    kill(pidtimer);
	else	
	    newsend(pidplotter,3,targetx,targety ,' ');
    }
}
Пример #2
0
int main(int argc, char **argv)
{
	umsg32 retval;

	/* Creating a shell process */

	resume(create(shell, 4096, 1, "shell", 1, CONSOLE));

	retval = recvclr();
	while (TRUE) {
		retval = receive();
		kprintf("\n\n\rMain process recreating shell\n\n\r");
		resume(create(shell, 4096, 1, "shell", 1, CONSOLE));
	}

	return OK;
}
Пример #3
0
process	main(void)
{
	/* Start the network */

	//ethinit(&devtab[ETHER0]);

	uint32	*macaddr = 0x44e10630;
	kprintf("mac addr: %x %x\n", *macaddr, *(macaddr+1));
	int32 i;
/*	for(i = 0; i < 6; i++) {
		NetData.ethucast[i] = i;
		NetData.ethbcast[i] = 0xff;
	}*/

	//kprintf("reading packet from ETHER0\n");
	//struct netpacket pkt;
	//read(ETHER0, &pkt, 1518);

	//resume(create(counterproc, 8192, 19, "counter proc", 0, NULL));
	//sleep(10);
	//kprintf("Counter value: %d\n", gcounter);

	//DELAY(5000000);

	// Commented by Bryce Himebaugh on 9/02/1015. Generating run time error messages. 
	// netstart();

	kprintf("\n...creating a shell\n");
	recvclr();
	resume(create(shell, 8192, 50, "shell", 1, CONSOLE));

	/* Wait for shell to exit and recreate it */

	while (TRUE) {
		receive();
		sleepms(200);
		kprintf("\n\nMain process recreating shell\n\n");
		resume(create(shell, 4096, 20, "shell", 1, CONSOLE));
	}
	return OK;
}
Пример #4
0
process	main(void)
{
  char bbb_ipaddr[] = "192.168.1.101";
  char bbb_router[] = "192.168.1.255";

  /* Start the network */
  netstart(bbb_ipaddr,bbb_router);
  kprintf("\n...creating a shell\n");
  recvclr();
  resume(create(shell, 8192, 50, "shell", 1, CONSOLE));
  
  /* Wait for shell to exit and recreate it */
  
  while (TRUE) {
    receive();
    sleepms(200);
    kprintf("\n\nMain process recreating shell\n\n");
    resume(create(shell, 4096, 20, "shell", 1, CONSOLE));
  }
  return OK;
}
Пример #5
0
int main(int argc, char **argv)
{
	uint32 retval;

	
	kprintf("main: calling getlocalip\n");
    NetData.ipvalid = FALSE;
	retval = getlocalip();

	if (retval == SYSERR) {
		kprintf("I'm here to stop!\n");
	} else {
		kprintf("I'm here to continue!\n");
		kprintf("\n\n###########################################################\n\n");
		kprintf("IP address is %d.%d.%d.%d   %08x\n\r",
			(retval>>24)&0xff, (retval>>16)&0xff, (retval>>8)&0xff,
		 	retval&0xff,retval);

	    	kprintf("Subnet mask is %d.%d.%d.%d and router is %d.%d.%d.%d\n\r",
			(NetData.addrmask>>24)&0xff, (NetData.addrmask>>16)&0xff,
			(NetData.addrmask>> 8)&0xff,  NetData.addrmask&0xff,
			(NetData.routeraddr>>24)&0xff, (NetData.routeraddr>>16)&0xff,
			(NetData.routeraddr>> 8)&0xff, NetData.routeraddr&0xff);
	}
	//netin();


	//while (1);
	resume(create(shell, 8192, 50, "shell", 1, CONSOLE));

	/* Wait for shell to exit and recreate it */
	recvclr();
	while (TRUE) {
		retval = receive();
		kprintf("\n\n\rMain process recreating shell\n\n\r");
		resume(create(shell, 4096, 1, "shell", 1, CONSOLE));
	}

	return OK;
}
Пример #6
0
/*------------------------------------------------------------------------
 *  rarpsend  -  broadcast a RARP packet to obtain my IP address
 *------------------------------------------------------------------------
 */
int
rarpsend(int ifn)
{
	STATWORD		ps;
	struct	netif		*pni = &nif[ifn];
	struct	ep		*pep;
	int			i, mypid, resp;
	IPaddr			junk = 0; /* arg to mkarp; never used */

	mypid = getpid();
	for (i=0; i<ARP_MAXRETRY; ++i) {
		pep = mkarp(ifn, EPT_RARP, RA_REQUEST, junk, junk);
		if ((int)pep == SYSERR)
			break;
		disable(ps);
		rarppid = mypid;
		restore(ps);
		recvclr();
		write(pni->ni_dev, pep, EP_MINLEN);
		/* ARP_RESEND is in secs, recvtim uses 1/10's of secs	*/
		resp = recvtim(10*ARP_RESEND<<i);
		if (resp != TIMEOUT) {
			/* host route */
			rtadd(pni->ni_ip, ip_maskall, pni->ni_ip, 0,
				NI_LOCAL, RT_INF);

			/* non-subnetted route */
			rtadd(pni->ni_net, ip_maskall, pni->ni_ip, 0,
				NI_LOCAL, RT_INF);

			return OK;
		}
	}
	panic("No response to RARP");
	return SYSERR;
}
Пример #7
0
/*------------------------------------------------------------------------
 * udp_recvaddr - receive a UDP packet and record the sender's address
 *------------------------------------------------------------------------
 */
int32	udp_recvaddr (
    uint32	*remip,			/* loc to record remote IP addr.*/
    uint16	*remport,		/* loc to record remote port	*/
    uint16	locport,		/* local UDP protocol port	*/
    char   *buff,			/* buffer to hold UDP data	*/
    int32	len,			/* length of buffer		*/
    uint32	timeout			/* read timeout in msec		*/
)
{
    intmask	mask;			/* saved interrupt mask		*/
    int32	i;			/* index into udptab		*/
    struct	udpentry *udptr;	/* pointer to udptab entry	*/
    umsg32	msg;			/* message from recvtime()	*/
    struct	eth_packet *pkt;		/* ptr to packet being read	*/
    struct  ipv4_packet *ippkt = NULL;
    struct  udp_packet * udppkt = NULL;
    int32	msglen;			/* length of UDP data in packet	*/
    char	*udataptr;		/* pointer to UDP data		*/

    /* Insure only one process access UDP table at a time */

    mask = disable();

    for (i=0; i<UDP_SLOTS; i++) {
        udptr = &udptab[i];
        if ( (udptr->udremip == 0 ) &&
                (locport == udptr->udlocport) ) {

            /* Entry in table matches request */
            break;
        }
    }

    if (i >= UDP_SLOTS) {
        restore(mask);
        return SYSERR;
    }

    if (udptr->udcount == 0) {	/* no packet is waiting */
        udptr->udstate = UDP_RECV;
        udptr->udpid = currpid;
        msg = recvclr();
        msg = recvtime(timeout);	/* wait for packet */
        udptr->udstate = UDP_USED;
        if (msg == TIMEOUT) {
            restore(mask);
            return TIMEOUT;
        } else if (msg != OK) {
            restore(mask);
            return SYSERR;
        }
    }

    /* Packet has arrived -- dequeue it */

    pkt = udptr->udqueue[udptr->udhead++];
    ippkt = (struct ipv4_packet *)(pkt->net_ethdata);
    udppkt = (struct udp_packet *)(ippkt->net_ipdata);
    if (udptr->udhead >= UDP_SLOTS) {
        udptr->udhead = 0;
    }
    udptr->udcount--;

    /* Record sender's IP address and UDP port number */

    *remip = ippkt->net_ipsrc;
    *remport = udppkt->net_udpsport;

    /* Copy UDP data from packet into caller's buffer */

    msglen = udppkt->net_udplen - UDP_HDR_LEN;
    udataptr = (char *)udppkt->net_udpdata;
    for (i=0; i<msglen; i++) {
        if (i >= len) {
            break;
        }
        *buff++ = *udataptr++;
    }
    freebuf((char *)pkt);
    restore(mask);
    return i;
}
Пример #8
0
/*------------------------------------------------------------------------
 * udp_recvaddr  -  Receive a UDP packet and record the sender's address
 *------------------------------------------------------------------------
 */
int32	udp_recvaddr (
	 uid32	slot,			/* Slot in table to use		*/
	 uint32	*remip,			/* Loc for remote IP address	*/
	 uint16	*remport,		/* Loc for remote protocol port	*/
	 char   *buff,			/* Buffer to hold UDP data	*/
	 int32	len,			/* Length of buffer		*/
	 uint32	timeout			/* Read timeout in msec		*/
	)
{
	intmask	mask;			/* Saved interrupt mask		*/
	struct	udpentry *udptr;	/* Pointer to udptab entry	*/
	umsg32	msg;			/* Message from recvtime()	*/
	struct	netpacket *pkt;		/* Pointer to packet being read	*/
	int32	msglen;			/* Length of UDP data in packet	*/
	int32	i;			/* Counts bytes copied		*/
	char	*udataptr;		/* Pointer to UDP data		*/

	/* Ensure only one process can access the UDP table at a time	*/

	mask = disable();

	/* Verify that the slot is valid */

	if ((slot < 0) || (slot >= UDP_SLOTS)) {
		restore(mask);
		return SYSERR;
	}

	/* Get pointer to table entry */

	udptr = &udptab[slot];

	/* Verify that the slot has been registered and is valid */

	if (udptr->udstate != UDP_USED) {
		restore(mask);
		return SYSERR;
	}

	/* Wait for a packet to arrive */

	if (udptr->udcount == 0) {		/* No packet is waiting */
		udptr->udstate = UDP_RECV;
		udptr->udpid = currpid;
		msg = recvclr();
		msg = recvtime(timeout);	/* Wait for a packet	*/
		udptr->udstate = UDP_USED;
		if (msg == TIMEOUT) {
			restore(mask);
			return TIMEOUT;
		} else if (msg != OK) {
			restore(mask);
			return SYSERR;
		}
	}

	/* Packet has arrived -- dequeue it */

	pkt = udptr->udqueue[udptr->udhead++];
	if (udptr->udhead >= UDP_QSIZ) {
		udptr->udhead = 0;
	}

	/* Record sender's IP address and UDP port number */

	*remip = pkt->net_ipsrc;
	*remport = pkt->net_udpsport;

	udptr->udcount--;

	/* Copy UDP data from packet into caller's buffer */

	msglen = pkt->net_udplen - UDP_HDR_LEN;
	udataptr = (char *)pkt->net_udpdata;
	if (len < msglen) {
		msglen = len;
	}
	for (i=0; i<msglen; i++) {
		*buff++ = *udataptr++;
	}
	freebuf((char *)pkt);
	restore(mask);
	return msglen;
}
Пример #9
0
process	main(void)
{
	kprintf("\nHello World!\n");
	kprintf("\nI'm the first XINU app and running function main() in system/main.c.\n");
	kprintf("\nI was created by nulluser() in system/initialize.c using create().\n");
	kprintf("\nMy creator will turn itself into the do-nothing null process.\n");
	kprintf("\nI will create a second XINU app that runs shell() in shell/shell.c as an example.\n");
	kprintf("\nYou can do something else, or do nothing; it's completely up to you.\n");
	kprintf("\n...creating a shell\n");
	recvclr();
    // Homework 1
    {
        //resume(create(shell, 8192, 50, "shell", 1, CONSOLE));

        /*
         * Createschild process calling app1()
        resume (
           create((void *)app1, 65536, 20, "app1 process", 0,
               NULL));
        
         * Creates child process calling app2()
        resume (
           create((void *)app2, 65536, 20, "app2 process", 0,
               NULL));*/

        /* Wait for shell to exit and recreate it */
        /*
        while (TRUE) {
            receive();
            sleepms(200);
            kprintf("\n\nMain process recreating shell\n\n");
            resume(create(shell, 4096, 20, "shell", 1, CONSOLE));
        }*/
    }

    // Homework 2 
    {
        /*
        uint32 a = 0xAABBCCDD;
        uint32 b = host2netla(a);
        kprintf("\n\nLil Endian to Big Endian\nBig Endian of 0x%x is 0x%x", a, b);
        
        a = 0xAABBCCDD;
        b = host2netlb(a);
        kprintf("\n\nLil Endian to Big Endian\nBig Endian of 0x%x is 0x%x", a, host2netlb(a));

        a = 0xAABBCCDD;
        b = host2netlc(a);
        kprintf("\n\nLil Endian to Big Endian\nBig Endian of 0x%x is 0x%x", a, b);

        prntsegaddr();
       
        //kprintf("\nStack Depth:%d\n", stackdepth(currpid));
        
        resume (
           create((void *)f1, 65536, 20, "f1  process", 0,
               NULL));

        unsigned long * topsp;

        asm("movl %esp, esp");
        topsp = esp;
        kprintf("\ncurrpid : %d\n", currpid);
        kprintf("\nBefore myappA is created\n");
        kprintf("run-time stack top : address = 0x%x, content = 0x%x\n", topsp, (unsigned long *) *topsp);

        pid32 myappA_pid = create( (void *) myappA, 65536, 20, "myappA process", 2, 5, currpid);
        asm("movl %esp, esp");
        topsp = esp;
        kprintf("\nAfter myappA is created but before resuming it\n");
        kprintf("run-time stack top : address = 0x%x, content = 0x%x\n", topsp, (unsigned long *) *topsp);

        resume(myappA_pid);

        sleepms(500);

        pid32 victim_pid;

        resume (
           create((void *)myvictim, 2048, 10, "myvictim process", 1,
               5));
        resume (victim_pid = 
           create((void *)myvictim, 2048, 10, "myvictim process", 1,
               5));
        resume (
           create((void *)myhacker, 2048, 10, "myhacker process", 1,
               victim_pid));
                return OK;
                */
    }

    // Homework 3
    homework3();
    return OK;
}
Пример #10
0
process	shell (
		did32	dev		/* ID of tty device from which	*/
	)				/*   to accept commands		*/
{
	char	buf[SHELL_BUFLEN];	/* Input line (large enough for	*/
					/*   one line from a tty device	*/
	int32	len;			/* Length of line read		*/
	char	tokbuf[SHELL_BUFLEN +	/* Buffer to hold a set of	*/
			SHELL_MAXTOK];  /* Contiguous null-terminated	*/
					/* Strings of tokens		*/
	int32	tlen;			/* Current length of all data	*/
					/*   in array tokbuf		*/
	int32	tok[SHELL_MAXTOK];	/* Index of each token in	*/
					/*   array tokbuf		*/
	int32	toktyp[SHELL_MAXTOK];	/* Type of each token in tokbuf	*/
	int32	ntok;			/* Number of tokens on line	*/
	pid32	child;			/* Process ID of spawned child	*/
	bool8	backgnd;		/* Run command in background?	*/
	char	*outname, *inname;	/* Pointers to strings for file	*/
					/*   names that follow > and <	*/
	did32	stdinput, stdoutput;	/* Descriptors for redirected	*/
					/*   input and output		*/
	int32	i;			/* Index into array of tokens	*/
	int32	j;			/* Index into array of commands	*/
	int32	msg;			/* Message from receive() for	*/
					/*   child termination		*/
	int32	tmparg;			/* Address of this var is used	*/
					/*   when first creating child	*/
					/*   process, but is replaced	*/
	char	*src, *cmp;		/* Pointers used during name	*/
					/*   comparison			*/
	bool8	diff;			/* Was difference found during	*/
					/*   comparison			*/
	char	*args[SHELL_MAXTOK];	/* Argument vector passed to	*/
					/*   builtin commands		*/

	/* Print shell banner and startup message */

	fprintf(dev, "\n\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
		SHELL_BAN0,SHELL_BAN1,SHELL_BAN2,SHELL_BAN3,SHELL_BAN4,
		SHELL_BAN5,SHELL_BAN6,SHELL_BAN7,SHELL_BAN8,SHELL_BAN9);

	fprintf(dev, "%s\n\n", SHELL_STRTMSG);

	/* Continually prompt the user, read input, and execute command	*/

	while (TRUE) {

		/* Display prompt */

		fprintf(dev, SHELL_PROMPT);

		/* Read a command */

		len = read(dev, buf, sizeof(buf));

		/* Exit gracefully on end-of-file */

		if (len == EOF) {
			break;
		}

		/* If line contains only NEWLINE, go to next line */

		if (len <= 1) {
			continue;
		}

		buf[len] = SH_NEWLINE;	/* terminate line */

		/* Parse input line and divide into tokens */

		ntok = lexan(buf, len, tokbuf, &tlen, tok, toktyp);

		/* Handle parsing error */

		if (ntok == SYSERR) {
			fprintf(dev,"%s\n", SHELL_SYNERRMSG);
			continue;
		}

		/* If line is empty, go to next input line */

		if (ntok == 0) {
			fprintf(dev, "\n");
			continue;
		}

		/* If last token is '&', set background */

		if (toktyp[ntok-1] == SH_TOK_AMPER) {
			ntok-- ;
			tlen-= 2;
			backgnd = TRUE;
		} else {
			backgnd = FALSE;
		}


		/* Check for input/output redirection (default is none) */

		outname = inname = NULL;
		if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS)
				   ||(toktyp[ntok-2] == SH_TOK_GREATER))){
			if (toktyp[ntok-1] != SH_TOK_OTHER) {
				fprintf(dev,"%s\n", SHELL_SYNERRMSG);
				continue;
			}
			if (toktyp[ntok-2] == SH_TOK_LESS) {
				inname =  &tokbuf[tok[ntok-1]];
			} else {
				outname = &tokbuf[tok[ntok-1]];
			}
			ntok -= 2;
			tlen = tok[ntok];
		}


		if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS)
				   ||(toktyp[ntok-2] == SH_TOK_GREATER))){
			if (toktyp[ntok-1] != SH_TOK_OTHER) {
				fprintf(dev,"%s\n", SHELL_SYNERRMSG);
				continue;
			}
			if (toktyp[ntok-2] == SH_TOK_LESS) {
				if (inname != NULL) {
				    fprintf(dev,"%s\n", SHELL_SYNERRMSG);
				    continue;
				}
				inname = &tokbuf[tok[ntok-1]];
			} else {
				if (outname != NULL) {
				    fprintf(dev,"%s\n", SHELL_SYNERRMSG);
				    continue;
				}
				outname = &tokbuf[tok[ntok-1]];
			}
			ntok -= 2;
			tlen = tok[ntok];
		}

		/* Verify remaining tokens are type "other" */

		for (i=0; i<ntok; i++) {
			if (toktyp[i] != SH_TOK_OTHER) {
				break;
			}
		}
		if ((ntok == 0) || (i < ntok)) {
			fprintf(dev, SHELL_SYNERRMSG);
			continue;
		}

		stdinput = stdoutput = dev;

		/* Lookup first token in the command table */

		for (j = 0; j < ncmd; j++) {
			src = cmdtab[j].cname;
			cmp = tokbuf;
			diff = FALSE;
			while (*src != NULLCH) {
				if (*cmp != *src) {
					diff = TRUE;
					break;
				}
				src++;
				cmp++;
			}
			if (diff || (*cmp != NULLCH)) {
				continue;
			} else {
				break;
			}
		}

		/* Handle command not found */

		if (j >= ncmd) {
			fprintf(dev, "command %s not found\n", tokbuf);
			continue;
		}

		/* Handle built-in command */

		if (cmdtab[j].cbuiltin) { /* No background or redirect. */
			if (inname != NULL || outname != NULL || backgnd){
				fprintf(dev, SHELL_BGERRMSG);
				continue;
			} else {
				/* Set up arg vector for call */

				for (i=0; i<ntok; i++) {
					args[i] = &tokbuf[tok[i]];
				}

				/* Call builtin shell function */

				if ((*cmdtab[j].cfunc)(ntok, args)
							== SHELL_EXIT) {
					break;
				}
			}
			continue;
		}

		/* Open files and redirect I/O if specified */

		if (inname != NULL) {
			stdinput = open(NAMESPACE,inname,"ro");
			if (stdinput == SYSERR) {
				fprintf(dev, SHELL_INERRMSG, inname);
				continue;
			}
		}
		if (outname != NULL) {
			stdoutput = open(NAMESPACE,outname,"w");
			if (stdoutput == SYSERR) {
				fprintf(dev, SHELL_OUTERRMSG, outname);
				continue;
			} else {
				control(stdoutput, F_CTL_TRUNC, 0, 0);
			}
		}

		/* Spawn child thread for non-built-in commands */

		child = create(cmdtab[j].cfunc,
			SHELL_CMDSTK, SHELL_CMDPRIO,
			cmdtab[j].cname, 2, ntok, &tmparg);

		/* If creation or argument copy fails, report error */

		if ((child == SYSERR) ||
		    (addargs(child, ntok, tok, tlen, tokbuf, &tmparg)
							== SYSERR) ) {
			fprintf(dev, SHELL_CREATMSG);
			continue;
		}

		/* Set stdinput and stdoutput in child to redirect I/O */

		proctab[child].prdesc[0] = stdinput;
		proctab[child].prdesc[1] = stdoutput;

		msg = recvclr();
		resume(child);
		if (! backgnd) {
			msg = receive();
			while (msg != child) {
				msg = receive();
			}
		}
    }

    /* Terminate the shell process by returning from the top level */

    fprintf(dev,SHELL_EXITMSG);
    return OK;
}
Пример #11
0
/**
 * The Xinu shell.  Provides an interface to execute commands.
 * @param descrp descriptor of device on which the shell is open
 * @return OK for successful exit, SYSERR for unrecoverable error
 */
thread shell(int indescrp, int outdescrp, int errdescrp)
{
  char buf[SHELL_BUFLEN];     /* line input buffer        */
  short buflen;               /* length of line input     */
  char tokbuf[SHELL_BUFLEN + SHELL_MAXTOK];   /* token value buffer       */
  short ntok;                 /* number of tokens         */
  char *tok[SHELL_MAXTOK];    /* pointers to token values */
  char *outname;              /* name of output file      */
  char *inname;               /* name of input file       */
  bool background;            /* is background proccess?  */
  syscall child;              /* pid of child thread      */
  ushort i, j;                /* temp variables           */
  irqmask im;                 /* interrupt mask state     */

  /* hostname variables */
  char hostnm[NET_HOSTNM_MAXLEN + 1]; /* hostname of backend      */
  char *hostptr;              /* pointer to hostname      */
  int hostname_strsz;         /* nvram hostname name size */
  device *devptr;             /* device pointer           */

  printf( "Welcome to the shell!\n" );

  /* Enable interrupts */
  enable();

  hostptr = NULL;
  devptr = NULL;
  hostname_strsz = 0;
  bzero(hostnm, NET_HOSTNM_MAXLEN + 1);

  /* Setup buffer for string for nvramGet call for hostname */
#ifdef ETH0
  if (!isbaddev(ETH0))
  {
    /* Determine the hostname of the main network device */
    devptr = (device *)&devtab[ETH0];
    hostname_strsz = strnlen(NET_HOSTNAME, NVRAM_STRMAX) + 1;
    hostname_strsz += DEVMAXNAME;
    char nvramget_hostname_str[hostname_strsz];
    sprintf(nvramget_hostname_str, "%s_%s", devptr->name,
        NET_HOSTNAME);

    /* Acquire the backend's hostname */
#if NVRAM
    hostptr = nvramGet(nvramget_hostname_str);
#endif                          /* NVRAM */
    if (hostptr != NULL)
    {
      memcpy(hostnm, hostptr, NET_HOSTNM_MAXLEN);
      hostptr = hostnm;
    }
  }
#endif

  /* Set command devices for input, output, and error */
  stdin = indescrp;
  stdout = outdescrp;
  stderr = errdescrp;

  /* Print shell banner */
  printf(SHELL_BANNER);
  /* Print shell welcome message */
  printf(SHELL_START);

  /* Continually receive and handle commands */
  while (TRUE)
  {
    /* Display prompt */
    printf(SHELL_PROMPT);

    if (NULL != hostptr)
    {
      printf("@%s$ ", hostptr);
    }
    else
    {
      printf("$ ");
    }

    /* Setup proper tty modes for input and output */
    control(stdin, TTY_CTRL_CLR_IFLAG, TTY_IRAW, NULL);
    control(stdin, TTY_CTRL_SET_IFLAG, TTY_ECHO, NULL);

    /* Null out the buf and read command */
    memset(buf, '\0', SHELL_BUFLEN);
    buflen = shellRead(stdin, buf, SHELL_BUFLEN);

    if(buf[0] != '!') {
      addHistoryItem(buf, buflen);
    }

    /* Check for EOF and exit gracefully if seen */
    if (EOF == buflen)
    {
      break;
    }

    // Check for indicator of history command
    if (buf[0] == '!')
    {
      int index;

      // handler for !! (just execute most recent command)
      if(buf[1] == '!') {
        index = 0;
      } else {
        // extract the number string
        char indexString[buflen];
        strncpy(indexString, &buf[1], buflen - 1);
        indexString[buflen] = '\0';

        // convert number string into a valid index
        // calculation is done because the index numbers
        // are reverse of their numbers printed using 'history'
        index = numHistoryItems - atoi(indexString);
      }

      //replace buf and buflen with the last command
      strncpy(buf, history[index].command, SHELL_BUFLEN);
      buflen = history[index].commandLength + 1;
    }

    /* Parse line input into tokens */
    if (SYSERR == (ntok = lexan(buf, buflen, &tokbuf[0], &tok[0])))
    {
      fprintf(stderr, SHELL_SYNTAXERR);
      continue;
    }

    /* Ensure parse generated tokens */
    if (0 == ntok)
    {
      continue;
    }

    /* Initialize command options */
    inname = NULL;
    outname = NULL;
    background = FALSE;

    /* Mark as background thread, if last token is '&' */
    if ('&' == *tok[ntok - 1])
    {
      ntok--;
      background = TRUE;
    }

    /* Check each token and perform special handling of '>' and '<' */
    for (i = 0; i < ntok; i++)
    {
      /* Background '&' should have already been handled; Syntax error */
      if ('&' == *tok[i])
      {
        ntok = -1;
        break;
      }

      /* Setup for output redirection if token is '>'  */
      if ('>' == *tok[i])
      {
        /* Syntax error */
        if (outname != NULL || i >= ntok - 1)
        {
          ntok = -1;
          break;
        }

        outname = tok[i + 1];
        ntok -= 2;

        /* shift tokens (not to be passed to command */
        for (j = i; j < ntok; j++)
        {
          tok[j] = tok[j + 2];
        }
        continue;
      }

      /* Setup for input redirection if token is '<' */
      if ('<' == *tok[i])
      {
        /* Syntax error */
        if (inname != NULL || i >= ntok - 1)
        {
          ntok = -1;
          break;
        }
        inname = tok[i + 1];
        ntok -= 2;

        /* shift tokens (not to be passed to command */
        for (j = i; j < ntok; j++)
        {
          tok[j] = tok[j + 2];
        }

        continue;
      }
    }

    /* Handle syntax error */
    if (ntok <= 0)
    {
      fprintf(stderr, SHELL_SYNTAXERR);
      continue;
    }

    /* Lookup first token in the command table */
    for (i = 0; i < ncommand; i++)
    {
      if (0 == strncmp(commandtab[i].name, tok[0], SHELL_BUFLEN))
      {
        break;
      }
    }

    /* Handle command not found */
    if (i >= ncommand)
    {
      fprintf(stderr, "%s: command not found\n", tok[0]);
      continue;
    }

    /* Handle command if it is built-in */
    if (commandtab[i].builtin)
    {
      if (inname != NULL || outname != NULL || background)
      {
        fprintf(stderr, SHELL_SYNTAXERR);
      }
      else
      {
        (*commandtab[i].procedure) (ntok, tok);
      }
      continue;
    }

    /* Spawn child thread for non-built-in commands */
    child =
      create(commandtab[i].procedure,
          SHELL_CMDSTK, SHELL_CMDPRIO,
          commandtab[i].name, 2, ntok, tok);



    /* Ensure child command thread was created successfully */
    if (SYSERR == child)
    {
      fprintf(stderr, SHELL_CHILDERR);
      continue;
    }

    /* Set file descriptors for newly created thread */
    if (NULL == inname)
    {
      thrtab[child].fdesc[0] = stdin;
    }
    else
    {
      thrtab[child].fdesc[0] = getdev(inname);
    }
    if (NULL == outname)
    {
      thrtab[child].fdesc[1] = stdout;
    }
    else
    {
      thrtab[child].fdesc[1] = getdev(outname);
    }
    thrtab[child].fdesc[2] = stderr;

    if (background)
    {
      /* Make background thread ready, but don't reschedule */
      im = disable();
      ready(child, RESCHED_NO);
      restore(im);
    }
    else
    {
      /* Clear waiting message; Reschedule; */
      while (recvclr() != NOMSG);
      im = disable();
      ready(child, RESCHED_YES);
      restore(im);

      /* Wait for command thread to finish */
      while (receive() != child);
      sleep(10);
    }
  }

  /* Close shell */
  fprintf(stdout, SHELL_EXIT);
  sleep(10);
  return OK;
}
Пример #12
0
/**
 * @ingroup shell
 *
 * Shell command (ping).
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return OK for success, SYSERR for syntax error
 */
shellcmd xsh_ping(int nargs, char *args[])
{
    int i = 0;
    int interval = 1000, count = 10, recv = 0, echoq = 0;
    ulong rtt = 0, min = 0, max = 0, total = 0;
    ulong startsec = 0, startms = 0;
    struct netaddr target;
    struct packet *pkt = NULL;
    char str[50];

    /* Output help, if '--help' argument was supplied */
    if (nargs == 2 && strncmp(args[1], "--help", 7) == 0)
    {
        printf("Usage: ping <IP>\n\n");
        printf("Description:\n");
        printf("\tSend ICMP echo requests to network hosts\n");
        printf("Options:\n");
        printf("\t<IP>\t\tIP address\n");
        printf("\t-c count\tstop after sending count packets\n");
        printf
            ("\t-i interval\tsleep interval milliseconds between pings\n");
        printf("\t--help\t\tdisplay this help and exit\n");
        return OK;
    }

    /* Check for correct number of arguments */
    if (nargs < 2)
    {
        fprintf(stderr, "ping: too few arguments\n");
        fprintf(stderr, "Try 'ping --help' for more information\n");
        return SHELL_ERROR;
    }

    i = 1;
    while (i < nargs)
    {
        if (0 == strncmp(args[i], "-c", 3))
        {
            i++;
            if (i < nargs)
            {
                count = atoi(args[i]);
            }
            else
            {
                fprintf(stderr, "ping: -c requires integer argument\n");
                return SHELL_ERROR;
            }
        }
        else if (0 == strncmp(args[i], "-i", 3))
        {
            i++;
            if (i < nargs)
            {
                interval = atoi(args[i]);
            }
            else
            {
                fprintf(stderr, "ping: -i requires integer argument\n");
                return SHELL_ERROR;
            }
        }
        else if (SYSERR == dot2ipv4(args[i], &target))
        {
            fprintf(stderr, "ping: %s is not a valid IPv4 address.\n",
                    args[i]);
            return SHELL_ERROR;
        }
        i++;
    }

    netaddrsprintf(str, &target);
    if (0 == strncmp(str, "ERROR", 6))
    {
        fprintf(stderr, "ping: destination IP address required.\n");
        return SHELL_ERROR;
    }
    printf("PING %s\n", str);

    echoq = echoQueueAlloc();
    if (SYSERR == echoq)
    {
        printf("...No free echo queues!\n");
        return SHELL_ERROR;
    }

    startsec = clktime;
    startms = clkticks;

    for (i = 0; i < count; i++)
    {
        // Send ping packet
        if (SYSERR == icmpEchoRequest(&target, gettid(), i))
        {
            printf("...Failed to reach %s\n", str);
            return SHELL_ERROR;
        }

        sleep(interval);
        if (NOMSG != recvclr())
        {
            // pick reply packets off of the queue
            pkt = echoQueueGet(echoq);
            while ((NULL != (ulong)pkt) && (SYSERR != (ulong)pkt))
            {
                rtt = echoTripTime(pkt);
                total += rtt;
                if ((rtt < min) || (0 == min))
                {
                    min = rtt;
                }
                if (rtt > max)
                {
                    max = rtt;
                }

                echoPrintPkt(pkt, rtt);
                netFreebuf(pkt);
                recv++;
                pkt = echoQueueGet(echoq);
            }
        }
    }
    echoQueueDealloc(echoq);

    netaddrsprintf(str, &target);
    printf("--- %s ping statistics ---\n", str);
    printf("%d packets transmitted, %d received,", count, recv);
    printf(" %d%% packet loss,", (count - recv) * 100 / count);
    printf(" time %dms\n", (clktime - startsec) * 1000 +
           ((clkticks - startms) * 1000) / CLKTICKS_PER_SEC);
    printf("rtt min/avg/max = %d.%03d/", min / 1000, min % 1000);
    if (0 != recv)
    {
        printf("%d.%03d/", (total / recv) / 1000, (total / recv) % 1000);
    }
    else
    {
        printf("-/");
    }
    printf("%d.%03d ms\n", max / 1000, max % 1000);

    return SHELL_OK;
}
Пример #13
0
/**
 * @ingroup shell
 *
 * Shell command (telnet).
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return 0 for success, 1 for error
 */
shellcmd xsh_telnet(int nargs, char *args[])
{
    int i;
    ushort port = 0;
    struct netaddr host;
    struct netaddr *localhost;
    struct netif *interface;

    tid_typ recvthr;
    tid_typ sendthr;
    int msg = 0;
    int dev;

    for (i = 1; i < nargs; i++)
    {
        /* Help */
        if (0 == strcmp(args[i], "--help"))
        {
            usage(args[0]);
            return 0;
        }

        /* Host */
        if (0 == host.len)
        {
            if (SYSERR == dot2ipv4(args[i], &host))
            {
                fprintf(stderr, "Invalid hostname\n");
                return 1;
            }
            continue;
        }

        /* Port */
        if (0 == port)
        {
            port = atoi(args[i]);
            if (port == 0)
            {
                fprintf(stderr, "Port must be greater than 0\n");
                return 1;
            }
            continue;
        }

        /* Otherwise */
        fprintf(stderr, "Invalid number of arguments\n");
        return 1;
    }

    /* Verify a valid number of arguments were processed */
    if (0 == host.len)
    {
        fprintf(stderr, "Invalid number of arguments\n");
        return 1;
    }

    /* Set default port if none is specified */
    if (port == 0)
    {
        port = TELNET_PORT;
    }

    /* Print that the client is trying to connect to the server */
    printf("Trying %s...\n", args[1]);

    interface = netLookup((ethertab[0].dev)->num);
    if (NULL == interface)
    {
        fprintf(stderr, "No network interface found\n");
        return 1;
    }
    localhost = &(interface->ip);

    /* Open connection */
#if NTCP
    dev = tcpAlloc();
#else
    dev = SYSERR;
#endif                          /* NTCP */
    if (SYSERR == dev)
    {
        fprintf(stderr, "Failed to allocate TCP device\n");
        return 1;
    }


    if (SYSERR == open(dev, localhost, &host, NULL, port, TCP_ACTIVE))
    {
        fprintf(stderr, "Failed to establish connection\n");
        return 1;
    }

    /* Display a connection prompt and tell the user how to quit */
    printf("Connected to %s.\nQuit character is '^]'.\n", args[1]);

    recvthr =
        create(telnetRecv, SHELL_CMDSTK, SHELL_CMDPRIO, "telnet_recv", 1,
               dev);
    sendthr =
        create(telnetSend, SHELL_CMDSTK, SHELL_CMDPRIO, "telnet_send", 1,
               dev);

    if ((SYSERR == recvthr) || (SYSERR == sendthr))
    {
        kill(recvthr);
        kill(sendthr);
        close(dev);
        return 1;
    }

    thrtab[recvthr].fdesc[0] = stdin;
    thrtab[recvthr].fdesc[1] = stdout;
    thrtab[recvthr].fdesc[2] = stderr;
    thrtab[sendthr].fdesc[0] = stdin;
    thrtab[sendthr].fdesc[1] = stdout;
    thrtab[sendthr].fdesc[2] = stderr;

    /* Start both threads */
    while (recvclr() != NOMSG);
    control(stdin, TTY_CTRL_SET_IFLAG, TTY_ECHO, NULL);
    control(stdin, TTY_CTRL_CLR_IFLAG, TTY_IRAW, NULL);
    ready(recvthr, RESCHED_YES);
    ready(sendthr, RESCHED_NO);

    /* Wait for one thread to die */
    while ((msg != recvthr) && (msg != sendthr))
    {
        msg = receive();
    }
    sleep(10);

    /* Kill both threads */
    kill(recvthr);
    kill(sendthr);

    close(dev);

    control(stdin, TTY_CTRL_SET_IFLAG, TTY_ECHO, NULL);
    control(stdin, TTY_CTRL_CLR_IFLAG, TTY_IRAW, NULL);

    return 0;
}
Пример #14
0
/*------------------------------------------------------------------------
 * icmp_recv  -  Receive an icmp echo reply packet
 *------------------------------------------------------------------------
 */
int32	icmp_recv (
	 int32	icmpid,			/* ICMP slot identifier		*/
	 char   *buff,			/* Buffer to ICMP data		*/
	 int32	len,			/* Length of buffer		*/
	 uint32	timeout			/* Time to wait in msec		*/
	)
{
	intmask	mask;			/* Saved interrupt mask		*/
	struct	icmpentry *icmptr;	/* Pointer to icmptab entry	*/
	umsg32	msg;			/* Message from recvtime()	*/
	struct	netpacket *pkt;		/* Pointer to packet being read	*/
	int32	datalen;		/* Length of ICMP data area	*/
	char	*icdataptr;		/* Pointer to icmp data		*/
	int32	i;			/* Counter for data copy	*/

	/* Verify that the ID is valid */

	if ( (icmpid < 0) || (icmpid >= ICMP_SLOTS) ) {
		return SYSERR;
	}

	/* Insure only one process touches the table at a time */

	mask = disable();

	/* Verify that the ID has been registered and is idle */

	icmptr = &icmptab[icmpid];
	if (icmptr->icstate != ICMP_USED) {
		restore(mask);
		return SYSERR;
	}

	if (icmptr->iccount == 0) {		/* No packet is waiting */
		icmptr->icstate = ICMP_RECV;
		icmptr->icpid = currpid;
		msg = recvclr();
		msg = recvtime(timeout);	/* Wait for a reply */
		icmptr->icstate = ICMP_USED;
		if (msg == TIMEOUT) {
			restore(mask);
			return TIMEOUT;
		} else if (msg != OK) {
			restore(mask);
			return SYSERR;
		}
	}

	/* Packet has arrived -- dequeue it */

	pkt = icmptr->icqueue[icmptr->ichead++];
	if (icmptr->ichead >= ICMP_SLOTS) {
		icmptr->ichead = 0;
	}
	icmptr->iccount--;

	/* Copy data from ICMP message into caller's buffer */

	datalen = pkt->net_iplen - IP_HDR_LEN - ICMP_HDR_LEN;
	icdataptr = (char *) &pkt->net_icdata;
	for (i=0; i<datalen; i++) {
		if (i >= len) {
			break;
		}
		*buff++ = *icdataptr++;
	}
	freebuf((char *)pkt);
	restore(mask);
	return i;
}
Пример #15
0
/**
 * @ingroup arp
 *
 * Obtains a hardware address from the ARP table given a protocol address.
 * @param netptr network interface
 * @param praddr protocol address
 * @param hwaddr buffer into which hardware address should be placed
 * @return OK if hardware address was obtained, otherwise TIMEOUT or SYSERR
 */
syscall arpLookup(struct netif *netptr, const struct netaddr *praddr,
                  struct netaddr *hwaddr)
{
    struct arpEntry *entry = NULL;  /**< pointer to ARP table entry   */
    uint lookups = 0;                   /**< num of ARP lookups performed */
    int ttl;                            /**< TTL for ARP table entry      */
    irqmask im;                         /**< interrupt state              */

    /* Error check pointers */
    if ((NULL == netptr) || (NULL == praddr) || (NULL == hwaddr))
    {
        ARP_TRACE("Invalid args");
        return SYSERR;
    }

    ARP_TRACE("Looking up protocol address");

    /* Attempt to obtain destination hardware address from ARP table until:
     * 1) lookup succeeds; 2) TIMEOUT occurs; 3) SYSERR occurs; or
     * 4) maximum number of lookup attempts occrus. */
    while (lookups < ARP_MAX_LOOKUP)
    {
        lookups++;

        /* Obtain entry from ARP table */
        im = disable();
        entry = arpGetEntry(praddr);

        /* If ARP entry does not exist; create an unresolved entry */
        if (NULL == entry)
        {
            ARP_TRACE("Entry does not exist");
            entry = arpAlloc();
            if (SYSERR == (int)entry)
            {
                restore(im);
                return SYSERR;
            }

            entry->state = ARP_UNRESOLVED;
            entry->nif = netptr;
            netaddrcpy(&entry->praddr, praddr);
            entry->expires = clktime + ARP_TTL_UNRESOLVED;
            entry->count = 0;
        }

        /* Place hardware address in buffer if entry is resolved */
        if (ARP_RESOLVED == entry->state)
        {
            netaddrcpy(hwaddr, &entry->hwaddr);
            ARP_TRACE("Entry exists");
            return OK;
        }

        /* Entry is unresolved; enqueue thread to wait for resolution */
        if (entry->count >= ARP_NTHRWAIT)
        {
            restore(im);
            ARP_TRACE("Queue of waiting threads is full");
            return SYSERR;
        }
        entry->waiting[entry->count] = gettid();
        entry->count++;
        ttl = (entry->expires - clktime) * CLKTICKS_PER_SEC;
        restore(im);

        /* Send an ARP request and wait for response */
        if (SYSERR == arpSendRqst(entry))
        {
            ARP_TRACE("Failed to send request");
            return SYSERR;
        }
        recvclr();
        switch (recvtime(ttl))
        {
        case TIMEOUT:
        case SYSERR:
            return SYSERR;
        case ARP_MSG_RESOLVED:
        default:
            /* Reply received, address resolved, re-attempt lookup */
            continue;
        }
    }

    return SYSERR;
}
Пример #16
0
int main(int argc, char **argv)
{
	uint32 retval;

	/*
	kprintf("main: calling getlocalip\n");
	retval = getlocalip();

	if (retval == SYSERR) {
		kprintf("I'm here to stop!\n");
	} else {
		kprintf("I'm here to continue!\n");
		kprintf("\n\n###########################################################\n\n");
		kprintf("IP address is %d.%d.%d.%d   %08x\n\r",
			(retval>>24)&0xff, (retval>>16)&0xff, (retval>>8)&0xff,
		 	retval&0xff,retval);

	    	kprintf("Subnet mask is %d.%d.%d.%d and router is %d.%d.%d.%d\n\r",
			(NetData.addrmask>>24)&0xff, (NetData.addrmask>>16)&0xff,
			(NetData.addrmask>> 8)&0xff,  NetData.addrmask&0xff,
			(NetData.routeraddr>>24)&0xff, (NetData.routeraddr>>16)&0xff,
			(NetData.routeraddr>> 8)&0xff, NetData.routeraddr&0xff);
	}
	*/
	
	//BEG Lab1_______________________________________________________
	/*kprintf("%x\n",host2netl_asm (0x12345678));
	//long test_asm_val;
	//long testa = 3;
	//test_asm_val = host2netl_asm(testa);
	//kprintf("host2netl_asm: %s \r\n\r\n", test_asm_val);
	printsegaddress();
	printprocstks();
	myprogA();

	kprintf("\r\nSpawning Processes...\r\n");
	resume(create(myprogA,1024,20,"Process A",0));
	//resume(create(myprogA,1024,20,"Process 2",0));
	printprocstks();*/
	//END Lab1_______________________________________________________
	

	//BEG Lab2_______________________________________________________
	//1024, 20priority, nameProcess, 1 arg, char
	
	/*
	uint32 pidA, pidB,pidC;
	pidA = create(printloop,1024,10,"Process A",1,'A');
	pidB = create(printloop,1024,10,"Process B",1,'B');
	pidC = create(printloop,1024,10,"Process C",1,'C');
	//pidA = create(printloop,1024,6,"Process A",1,'A');
	//pidB = create(printloop,1024,8,"Process B",1,'B');
	//pidC = create(printloop,1024,10,"Process C",1,'C');
	
	kprintf("P\r\n");
	resume(pidA);
	kprintf("P\r\n");
	resume(pidB);
	kprintf("P\r\n");
	resume(pidC);
	
	//sleep for 5 seconds
	//sleepms(5000);
	sleepms(5000);
	*/
	
	//END Lab2_______________________________________________________
	
	//BEG Lab3_______________________________________________________
	//1024, 20priority, nameProcess, 1 arg, char
	
	test1();
	sleepms(5000);
	test2();
	sleepms(5000);
	
	test4();
//	resume(create(cpuintensive, 1024, 20, "cpuintensiveA", 0));
//	resume(create(cpuintensive, 1024, 20, "cpuintensiveB", 0));
//	resume(create(cpuintensive, 1024, 20, "cpuintensiveC", 0)); 
//    resume(create(cpuintensive, 1024, 20, "cpuintensiveD", 0));
	//resume(create(cpuintensive, 1024, 20, "cpuintensiveE", 0));
	//resume(create(cpuintensive, 1024, 20, "cpuintensiveF", 0));
	
	
	/*
	resume(create(iointensive, 1024, 20, "iointensiveA", 0));
	resume(create(iointensive, 1024, 20, "iointensiveB", 0));
	resume(create(iointensive, 1024, 20, "iointensiveC", 0));
    resume(create(iointensive, 1024, 20, "iointensiveD", 0));
	resume(create(iointensive, 1024, 20, "iointensiveE", 0));
	resume(create(iointensive, 1024, 20, "iointensiveF", 0));
	*/
	
	/*
	uint32 pidA, pidB,pidC;
	pidA = create(printloop,1024,10,"Process A",1,'A');
	pidB = create(printloop,1024,10,"Process B",1,'B');
	pidC = create(printloop,1024,10,"Process C",1,'C');
	//pidA = create(printloop,1024,6,"Process A",1,'A');
	//pidB = create(printloop,1024,8,"Process B",1,'B');
	//pidC = create(printloop,1024,10,"Process C",1,'C');
	
	kprintf("P\r\n");
	resume(pidA);
	kprintf("P\r\n");
	resume(pidB);
	kprintf("P\r\n");
	resume(pidC);
	
	//sleep for 5 seconds
	//sleepms(5000);
	sleepms(5000);
	*/
	
	//END Lab3_______________________________________________________

	//comment out following line before, uncommented out lab 3
	while (1);
	
	//Kalena commented out following line for lab3
	//resume(create(shell, 8192, 50, "shell", 1, CONSOLE));	

	/* Wait for shell to exit and recreate it */
	recvclr();
	while (TRUE) {
		retval = receive();
		kprintf("\n\n\rMain process recreating shell\n\n\r");
		resume(create(shell, 4096, 1, "shell", 1, CONSOLE));
	}

	return OK;
}
Пример #17
0
/*------------------------------------------------------------------------
 * rdsRead - Read a block from a remote disk
 *------------------------------------------------------------------------
 */
devcall	rdsRead (
	  struct dentry	*devptr,	/* entry in device switch table	*/
	  char	*buff,			/* buffer to hold disk block	*/
	  int32	blk			/* block number of block to read*/
	)
{
	struct	rdscblk	*rdptr;		/* pointer to control block	*/
	struct	rdbuff	*bptr;		/* ptr to buffer possibly on	*/
					/*  the request list		*/
	struct	rdbuff	*nptr;		/* ptr to "next" node on a	*/
					/*  list			*/
	struct	rdbuff	*pptr;		/* ptr to "previous" node on	*/
					/*  a list			*/
	struct	rdbuff	*cptr;		/* ptr used to walk the cache	*/

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

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

	/* Search the cache for specified block */

	bptr = rdptr->rd_chnext;
	while (bptr != (struct rdbuff *)&rdptr->rd_ctnext) {
		if (bptr->rd_blknum == blk) {
			if (bptr->rd_status == RD_INVALID) {
				break;
			}
			memcpy(buff, bptr->rd_block, RD_BLKSIZ);
			return OK;
		}
		bptr = bptr->rd_next;
	}

	/* Search the request list for most recent occurrence of block */

	bptr = rdptr->rd_rtprev;	/* start at tail of list */

	while (bptr != (struct rdbuff *)&rdptr->rd_rhnext) {
	    if (bptr->rd_blknum == blk)  {

		/* If most recent request for block is write, copy data */

		if (bptr->rd_op == RD_OP_WRITE) {
			memcpy(buff, bptr->rd_block, RD_BLKSIZ);
			return OK;
		}
		break;
	    }
	    bptr = bptr->rd_prev;
	}

	/* Allocate a buffer and add read request to tail of req. queue */

	bptr = rdsbufalloc(rdptr);	
	bptr->rd_op = RD_OP_READ;
	bptr->rd_refcnt = 1;
	bptr->rd_blknum = blk;
	bptr->rd_status = RD_INVALID;
	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;

	/* Prepare to receive message when read completes */

	recvclr();

	/* Signal semaphore to start communication process */

	signal(rdptr->rd_reqsem);

	/* Block to wait for message */

	bptr = (struct rdbuff *)receive();
	if (bptr == (struct rdbuff *)SYSERR) {	
		return SYSERR;
	}
	memcpy(buff, bptr->rd_block, RD_BLKSIZ);
	bptr->rd_refcnt--;
	if (bptr->rd_refcnt <= 0) {

		/* Look for previous item in cache with the same block	*/
		/*    number to see if this item was only being kept	*/
		/*    until pending read completed			*/
				
		cptr = rdptr->rd_chnext;
		while (cptr != bptr) {
			if (cptr->rd_blknum == blk) {

				/* Unlink from cache */

				pptr = bptr->rd_prev;
				nptr = bptr->rd_next;
				pptr->rd_next = nptr;
				nptr->rd_prev = pptr;

				/* Add to the free list */

				bptr->rd_next = rdptr->rd_free;
				rdptr->rd_free = bptr;
			}
		}
	}
	return OK;
}
Пример #18
0
/**
 * @ingroup shell
 *
 * Shell command (nc).
 * @param nargs  number of arguments in args array
 * @param args   array of arguments
 * @return 0 for success, 1 for error
 */
shellcmd xsh_nc(int nargs, char *args[])
{
    int a;
    ushort port;
    bool listen = FALSE;
    struct netaddr dst;
    struct netaddr src;
    tid_typ recvthr;
    tid_typ sendthr;
    int msg = 0;
    int dev;

    /* Output help, if '--help' argument was supplied */
    if (nargs == 2 && 0 == strncmp(args[1], "--help", 7))
    {
        usage(args[0]);
        return 0;
    }

    port = 0;
    dst.type = NULL;
    src.type = NULL;

    /* Parse arguments */
    for (a = 1; a < nargs; a++)
    {
        if (args[a][0] != '-')
        {
            if (!listen && NULL == dst.type)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                dot2ipv4(args[a], &dst);
            }
            else if (listen && NULL == src.type)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                dot2ipv4(args[a], &src);
            }
            else if (NULL == port)
            {
                if (!isdigit(args[a][0]))
                {
                    return argError(args[a]);
                }
                port = atoi(args[a]);
            }
        }
        else
        {
            switch (args[a][1])
            {
                /* Listen on port */
            case 'l':
                listen = TRUE;
                break;
                /* Source IP */
            case 's':
                a++;
                if (a >= nargs || !isdigit(args[a][0]))
                {
                    return argError(args[a - 1]);
                }
                dot2ipv4(args[a], &src);
                break;
            default:
                return argError(args[a]);
            }
        }
    }

    /* Verify arguments */
    if (NULL == src.type)
    {
        fprintf(stderr, "Source/listen IP address required\n");
        return 1;
    }
    if (NULL == port)
    {
        fprintf(stderr, "Invalid port\n");
        return 1;
    }
    if (!listen && NULL == dst.type)
    {
        fprintf(stderr, "Remote IP address required\n");
        return 1;
    }

    /* Allocate a TCP device */
#ifdef NTCP
    dev = tcpAlloc();
#else
    dev = SYSERR;
#endif                          /* NTCP */
    if (SYSERR == dev)
    {
        return connError();
    }

    if (listen)
    {
        if (SYSERR == open(dev, &src, NULL, port, NULL, TCP_PASSIVE))
        {
            close(dev);
            return connError();
        }
    }
    else
    {
        if (SYSERR == open(dev, &src, &dst, NULL, port, TCP_ACTIVE))
        {
            close(dev);
            return connError();
        }
    }

    recvthr =
        create(ncRecv, SHELL_CMDSTK, SHELL_CMDPRIO, "nc_recv", 1, dev);
    sendthr =
        create(ncSend, SHELL_CMDSTK, SHELL_CMDPRIO, "nc_send", 1, dev);
    if ((SYSERR == recvthr) || (SYSERR == sendthr))
    {
        kill(recvthr);
        kill(sendthr);
        close(dev);
        fprintf(stderr, "Failed to spawn threads");
        return 1;
    }
    thrtab[recvthr].fdesc[0] = stdin;
    thrtab[recvthr].fdesc[1] = stdout;
    thrtab[recvthr].fdesc[2] = stderr;
    thrtab[sendthr].fdesc[0] = stdin;
    thrtab[sendthr].fdesc[1] = stdout;
    thrtab[sendthr].fdesc[2] = stderr;

    /* Start both threads */
    while (recvclr() != NOMSG);
    ready(recvthr, RESCHED_YES);
    ready(sendthr, RESCHED_NO);

    /* Wait for one thread to die */
    while ((msg != recvthr) && (msg != sendthr))
    {
        msg = receive();
    }
    sleep(10);

    /* Kill both threads */
    kill(recvthr);
    kill(sendthr);

    close(dev);
    return 0;
}
Пример #19
0
process	main(void)
{

	//printf("S**T\n");

	
	recvclr();

	//printf("----------Timed blocking message send TEST for PART 1-------\n");

	//TEST1

	//printf("TEST1 started\n");
	
	//bmstest1();

	//TEST2

	//printf("TEST2 started\n");

	//bmstest2();

	//TEST3

	//printf("TEST3 started\n");

	//bmstest3();

	//TEST4

	//printf("TEST4 started\n");

	//bmstest4();


	
	//printbsmtests(); // prints the result of the tests


	

	printf("---------------ASYNC MSG RECV TEST CASES FOR PART2------------\n");

	//TEST 1 - 

	printf("TEST1 started\n");

	asmtest1();
	printf("TEST1 finished\n");

	//TEST2 - 

	printf("TEST2 started\n");
	asmtest2();
	printf("TEST2 finished\n");


	printf("TEST3 started\n");
	//TEST3 - 


	asmtest3();

	printf("TEST3 finished\n");
	
	/*pid32 ar1 = create(asyncrec,1024,20,"asyncreceiver",0,NULL);
	pid32 as1 = create(asyncsend,1024,20,"asyncsender1",2,ar1,'A');
	pid32 as2 = create(asyncsend,1024,20,"asyncsender2",2,ar1,'B');	
	pid32 as3 = create(asyncsend,1024,20,"asyncsender3",2,ar1,'C');
	pid32 as4 = create(asyncsend,1024,20,"asyncsender4",2,ar1,'D');
	
	resume(ar1);
	sleepms(25);
	resume(as1);
	sleepms(25);
	resume(as2);
	sleepms(25);
	resume(as3);
	sleepms(25);
	resume(as4);*/
	
	




	return OK;
}
Пример #20
0
/**
 * Tests ARP.
 * @return OK when testing is complete
 */
thread test_arp(bool verbose)
{
    bool passed = TRUE;
    int i = 0;
    struct netaddr ip;
    struct netaddr mask;
    struct netaddr praddr;
    struct netaddr hwaddr;
    struct netaddr addrbuf;
    struct pcap_file_header pcap;
    struct pcap_pkthdr phdr;
    struct packet *pkt;
    struct netif *netptr;
    struct ethloop *pelp;
    uchar *data;
    uchar *request;
    struct arpPkt *arp;
    struct arpEntry *entry;
    uchar buf[ELOOP_BUFSIZE];
    int nproc;
    int nout;
    int wait;
    tid_typ tids[ARP_NTHRWAIT];
    tid_typ tid;
    irqmask im;

    enable();

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

    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;

    /* Initialize loopback ethernet and network interface */
    testPrint(verbose, "Test case initialization");

    data = (uchar *)(&_binary_data_testarp_pcap_start);
    memcpy(&pcap, data, sizeof(pcap));
    data += sizeof(pcap);

    if (SYSERR == open(ELOOP))
    {
        failif(TRUE, "");
    }
    else
    {
        failif((SYSERR == netUp(ELOOP, &ip, &mask, NULL)), "");
    }
    if (!passed)
    {
        testFail(TRUE, "");
        return OK;
    }

    /* Setup pointers to underlying structures */
#if NNETIF
    for (i = 0; i < NNETIF; i++)
    {
        if ((NET_ALLOC == netiftab[i].state)
            && (ELOOP == netiftab[i].dev))
        {
            break;
        }
    }
#endif
    netptr = &netiftab[i];
    pelp = &elooptab[devtab[ELOOP].minor];

    pkt = netGetbuf();
    if ((int)pkt != SYSERR)
    {
        pkt->nif = netptr;
    }

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

    hwaddr.type = NETADDR_ETHERNET;
    hwaddr.len = ETH_ADDR_LEN;
    hwaddr.addr[0] = 0xAA;
    hwaddr.addr[1] = 0xBB;
    hwaddr.addr[2] = 0xCC;
    hwaddr.addr[3] = 0xDD;
    hwaddr.addr[4] = 0xEE;
    hwaddr.addr[5] = 0xFF;

    /* Test arpPkt structure */
    testPrint(verbose, "Header structure (Request)");
    /* Get 1st packet */
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    pkt = netGetbuf();
    pkt->len +=
        ARP_CONST_HDR_LEN + (2 * IPv4_ADDR_LEN) + (2 * ETH_ADDR_LEN);
    pkt->curr -= pkt->len;
    arp = (struct arpPkt *)pkt->curr;
    arp->hwtype = hs2net(ARP_HWTYPE_ETHERNET);
    arp->prtype = hs2net(ARP_PRTYPE_IPv4);
    arp->hwalen = ETH_ADDR_LEN;
    arp->pralen = IPv4_ADDR_LEN;
    arp->op = hs2net(ARP_OP_RQST);
    memcpy(&arp->addrs[ARP_ADDR_SHA(arp)], netptr->hwaddr.addr,
           arp->hwalen);
    memcpy(&arp->addrs[ARP_ADDR_SPA(arp)], netptr->ip.addr, arp->pralen);
    memcpy(&arp->addrs[ARP_ADDR_DPA(arp)], praddr.addr, arp->pralen);
    failif((0 != memcmp(data + ELOOP_LINKHDRSIZE, arp, pkt->len)), "");

    /* Test arpPkt structure */
    testPrint(verbose, "Header structure (Reply)");
    /* Get 2nd packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    arp->op = hs2net(ARP_OP_REPLY);
    memcpy(&arp->addrs[ARP_ADDR_DHA(arp)], &arp->addrs[ARP_ADDR_SHA(arp)],
           arp->hwalen);
    arp->addrs[ARP_ADDR_DHA(arp) + ETH_ADDR_LEN - 1] = 0xCC;
    memcpy(&arp->addrs[ARP_ADDR_DPA(arp)], praddr.addr, arp->pralen);
    memcpy(&arp->addrs[ARP_ADDR_SHA(arp)], netptr->hwaddr.addr,
           arp->hwalen);
    memcpy(&arp->addrs[ARP_ADDR_SPA(arp)], netptr->ip.addr, arp->pralen);
    failif((0 != memcmp(data + ELOOP_LINKHDRSIZE, arp, pkt->len)), "");

    /* Test arpAlloc, free entry exists */
    testPrint(verbose, "Allocate free entry");
    /* Make first entry used */
    arptab[0].state = ARP_USED;
    arptab[0].expires = clktime + ARP_TTL_UNRESOLVED;
    entry = arpAlloc();
    failif(((NULL == entry) || (entry == &arptab[0])
            || (0 == (entry->state & ARP_USED))), "");

    /* Test arpAlloc, free entry exists */
    testPrint(verbose, "Allocate used entry");
    arptab[1].state = ARP_USED;
    arptab[1].expires = clktime + 1;
    /* Make all entries (except the first 2) have ARP_TTL_RESOLVED */
    for (i = 2; i < ARP_NENTRY; i++)
    {
        arptab[i].state = ARP_USED;
        arptab[i].expires = clktime + ARP_TTL_RESOLVED;
    }
    entry = arpAlloc();
    failif(((NULL == entry) || (entry != &arptab[1])
            || (0 == (entry->state & ARP_USED))), "");

    /* Test arpNotify */
    testPrint(verbose, "Notify waiting threads (bad params)");
    failif((SYSERR != arpNotify(NULL, TIMEOUT)), "");

    /* Test arpNotify */
    testPrint(verbose, "Notify waiting threads");
    entry = &arptab[0];
    entry->state = ARP_UNRESOLVED;
    for (i = 0; i < ARP_NTHRWAIT; i++)
    {
        tid =
            create((void *)notifyTest, INITSTK, INITPRIO, "notifyTest",
                   0);
        tids[i] = tid;
        entry->waiting[i] = tid;
        entry->count++;
        ready(tid, RESCHED_NO);
    }
    recvclr();
    arpNotify(entry, ARP_MSG_RESOLVED);
    nout = FALSE;
    nproc = 0;
    tid = recvtime(100);
    while ((tid != TIMEOUT) && (nproc < ARP_NTHRWAIT))
    {
        for (i = 0; i < ARP_NTHRWAIT; i++)
        {
            if (tid == tids[i])
            {
                tids[i] = NULL;
            }
        }
        nproc++;
        tid = recvtime(100);
    }
    for (i = 0; i < ARP_NTHRWAIT; i++)
    {
        if (tids[i] != NULL)
        {
            kill(tids[i]);
            nout = TRUE;
        }
    }
    failif(nout || (entry->count != 0), "");

    /* Test arpFree */
    testPrint(verbose, "Free entry (bad params)");
    failif((SYSERR != arpFree(NULL)), "");

    /* Test arpFree */
    testPrint(verbose, "Free resolved entry");
    entry = &arptab[0];
    entry->state = ARP_RESOLVED;
    entry->expires = clktime;
    failif(((SYSERR == arpFree(entry)) || (entry->expires != 0)), "");

    /* Test arpFree */
    testPrint(verbose, "Free unresolved entry");
    entry = &arptab[0];
    entry->state = ARP_UNRESOLVED;
    for (i = 0; i < ARP_NTHRWAIT; i++)
    {
        tid = create((void *)freeTest, INITSTK, INITPRIO, "freeTest", 0);
        tids[i] = tid;
        entry->waiting[i] = tid;
        entry->count++;
        ready(tid, RESCHED_NO);
    }
    recvclr();
    if (SYSERR == arpFree(entry))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        nout = FALSE;
        nproc = 0;
        tid = recvtime(100);
        while ((tid != TIMEOUT) && (nproc < ARP_NTHRWAIT))
        {
            for (i = 0; i < ARP_NTHRWAIT; i++)
            {
                if (tid == tids[i])
                {
                    tids[i] = NULL;
                }
            }
            nproc++;
            tid = recvtime(100);
        }
        for (i = 0; i < ARP_NTHRWAIT; i++)
        {
            if (tids[i] != NULL)
            {
                kill(tids[i]);
                nout = TRUE;
            }
        }
        failif(nout || (entry->count != 0), "");
    }

    /* Test arpGetEntry */
    testPrint(verbose, "Get entry");
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }
    nout = 4;
    if (ARP_NENTRY < nout)
    {
        nout = ARP_NENTRY;
    }
    for (i = 1; i < nout; i++)
    {
        entry = &arptab[i];
        entry->state = ARP_RESOLVED;
        entry->nif = netptr;
        praddr.addr[3] = i + 1;
        hwaddr.addr[5] = ((i + 0xA) << 4) + (i + 0xA);
        netaddrcpy(&entry->hwaddr, &hwaddr);
        netaddrcpy(&entry->praddr, &praddr);
        entry->expires = clktime + ARP_TTL_RESOLVED;
    }
    for (i = 1; i < nout; i++)
    {
        praddr.addr[3] = i + 1;
        entry = arpGetEntry(&praddr);
        if (entry != &arptab[i])
        {
            break;
        }
    }
    failif((i != nout), "");

    /* Test arpGetEntry with timeout */
    testPrint(verbose, "Get entry (timeout entries)");
    arptab[i].expires = clktime - 1;
    praddr.addr[3] = 2;
    entry = arpGetEntry(&praddr);
    if (entry != &arptab[1])
    {
        failif(TRUE, "Incorrect entry");
    }
    else
    {
        failif((arptab[0].state != ARP_FREE),
               "Did not free expired entry");
    }
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }

    /* Test receive reply for non-existing ARP table entry */
    testPrint(verbose, "Receive ARP reply, new entry");
    /* Get 3rd packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 3;
    hwaddr.addr[5] = 0xCC;
    nout = pelp->nout;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(10);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Check entry and ensure reply was not sent */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if (ARP_RESOLVED == arptab[i].state)
            {
                entry = &arptab[i];
                break;
            }
        }
        if (NULL == entry)
        {
            failif(TRUE, "No entry inserted");
        }
        else if ((FALSE == netaddrequal(&praddr, &entry->praddr))
                 || (FALSE == netaddrequal(&hwaddr, &entry->hwaddr))
                 || (entry->nif != netptr) || (entry->count != 0))
        {
            failif(TRUE, "Entry incorrect");
        }
        else if (pelp->nout > (nout + 1))
        {
            failif(TRUE, "Reply sent to reply");
        }
        else
        {
            failif(FALSE, "");
        }
    }

    /* Test receive request for non-existing ARP table entry */
    testPrint(verbose, "Receive ARP request, new entry");
    /* Get 4th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 1;
    hwaddr.addr[5] = 0xAA;
    nout = pelp->nout;
    nproc = netptr->nproc;
    im = disable();
    write(ELOOP, data, phdr.caplen);
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    restore(im);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Check entry and ensure reply was not sent */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        if (NULL == entry)
        {
            failif(TRUE, "No entry inserted");
        }
        else if ((FALSE == netaddrequal(&praddr, &entry->praddr))
                 || (FALSE == netaddrequal(&hwaddr, &entry->hwaddr))
                 || (entry->nif != netptr) || (entry->count != 0))
        {
            failif(TRUE, "Entry incorrect");
        }
        else
        {
            control(ELOOP, ELOOP_CTRL_GETHOLD, (int)buf, ELOOP_BUFSIZE);
            /* Get 5th packet */
            data += phdr.caplen;
            memcpy(&phdr, data, sizeof(phdr));
            data += sizeof(phdr);
            if (PCAP_MAGIC != pcap.magic)
            {
                phdr.caplen = endswap(phdr.caplen);
            }
            failif((memcmp(data, buf, phdr.caplen) != 0),
                   "Invalid reply");
        }
    }

    /* Test receive request for non-supported hardware type */
    testPrint(verbose, "Receive ARP request, bad HW type");
    /* Get 6th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 2;
    hwaddr.addr[5] = 0xBB;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Ensure entry was not added */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((entry != NULL), "Entry inserted");
    }

    /* Test receive reply for non-supported protocol type */
    testPrint(verbose, "Receive ARP reply, bad protocol type");
    /* Get 7th 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);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Ensure entry was not added */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((entry != NULL), "Entry inserted");
    }

    /* Test receive reply for existing resolved ARP table entry */
    testPrint(verbose, "Receive ARP reply, resolved entry");
    /* Get 8th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 3;
    hwaddr.addr[5] = 0x0C;
    nout = pelp->nout;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Check entry */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((FALSE == netaddrequal(&hwaddr, &entry->hwaddr)),
               "Entry incorrect");
    }

    /* Test receive request not for me */
    testPrint(verbose, "Receive ARP request, not mine");
    /* Get 9th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    praddr.addr[3] = 4;
    hwaddr.addr[5] = 0xDD;
    nproc = netptr->nproc;
    write(ELOOP, data, phdr.caplen);
    /* Wait until packet is processed */
    wait = 0;
    while ((wait < MAX_WAIT) && (netptr->nproc == nproc))
    {
        wait++;
        sleep(100);
    }
    if (MAX_WAIT == wait)
    {
        failif(TRUE, "Wait time expired");
    }
    else
    {
        /* Ensure entry was not added */
        entry = NULL;
        for (i = 0; i < ARP_NENTRY; i++)
        {
            if ((ARP_RESOLVED == arptab[i].state)
                && (netaddrequal(&praddr, &arptab[i].praddr)))
            {
                entry = &arptab[i];
                break;
            }
        }
        failif((entry != NULL), "Entry inserted");
    }

    /* Test arpSendRequest */
    testPrint(verbose, "Send ARP request (bad params)");
    failif((SYSERR != arpSendRqst(NULL)), "");

    /* Test arpSendRequest */
    testPrint(verbose, "Send ARP request");
    /* Get 10th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    entry = &arptab[0];
    entry->state = ARP_UNRESOLVED;
    entry->nif = netptr;
    praddr.addr[3] = 2;
    hwaddr.addr[5] = 0xBB;
    netaddrcpy(&entry->hwaddr, &hwaddr);
    netaddrcpy(&entry->praddr, &praddr);
    entry->expires = clktime + ARP_TTL_UNRESOLVED;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    if (SYSERR == arpSendRqst(entry))
    {
        failif(TRUE, "Returned SYSERR");
    }
    else
    {
        control(ELOOP, ELOOP_CTRL_GETHOLD, (int)buf, ELOOP_BUFSIZE);
        failif((memcmp(buf, data, phdr.caplen) != 0), "");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup address (bad params)");
    failif((SYSERR != arpLookup(NULL, NULL, NULL)), "");

    /* Test arpLookup */
    testPrint(verbose, "Lookup existing resolved address");
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }
    entry = &arptab[0];
    entry->state = ARP_RESOLVED;
    entry->nif = netptr;
    praddr.addr[3] = 1;
    hwaddr.addr[5] = 0xAA;
    netaddrcpy(&entry->hwaddr, &hwaddr);
    netaddrcpy(&entry->praddr, &praddr);
    entry->expires = clktime + ARP_TTL_UNRESOLVED;
    i = arpLookup(netptr, &praddr, &addrbuf);
    if ((SYSERR == i) || (TIMEOUT == i))
    {
        failif(TRUE, "Returned SYSERR or TIMEOUT");
    }
    else
    {
        failif((FALSE == netaddrequal(&addrbuf, &hwaddr)),
               "Wrong address");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup existing unresolved address");
    entry = &arptab[1];
    entry->state = ARP_UNRESOLVED;
    entry->nif = netptr;
    praddr.addr[3] = 2;
    hwaddr.addr[5] = 0xBB;
    netaddrcpy(&entry->hwaddr, &hwaddr);
    netaddrcpy(&entry->praddr, &praddr);
    entry->expires = clktime + ARP_TTL_UNRESOLVED;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    request = data;
    wait = phdr.caplen;
    /* Get 11th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    tid =
        ready(create
              ((void *)lookupTest, INITSTK, INITPRIO, "lookupTest", 4,
               request, wait, data, phdr.caplen), RESCHED_NO);
    i = arpLookup(netptr, &praddr, &addrbuf);
    if ((SYSERR == i) || (TIMEOUT == i))
    {
        kill(tid);
        failif(TRUE, "Returned SYSERR or TIMEOUT");
    }
    else
    {
        failif((FALSE == netaddrequal(&addrbuf, &hwaddr)),
               "Wrong address");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup max threads wait for resolve");
    entry->state = ARP_UNRESOLVED;
    entry->count = ARP_NTHRWAIT;
    failif((arpLookup(netptr, &praddr, &addrbuf) != SYSERR), "");

    /* Test arpLookup */
    testPrint(verbose, "Lookup non-existing unresolved addr");
    praddr.addr[3] = 3;
    hwaddr.addr[5] = 0xCC;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_HOLDNXT, NULL);
    request = data;
    wait = phdr.caplen;
    /* Get 12th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    request = data;
    wait = phdr.caplen;
    /* Get 13th packet */
    data += phdr.caplen;
    memcpy(&phdr, data, sizeof(phdr));
    data += sizeof(phdr);
    if (PCAP_MAGIC != pcap.magic)
    {
        phdr.caplen = endswap(phdr.caplen);
    }
    tid =
        ready(create
              ((void *)lookupTest, INITSTK, INITPRIO, "lookupTest", 4,
               request, wait, data, phdr.caplen), RESCHED_NO);
    i = arpLookup(netptr, &praddr, &addrbuf);
    if ((SYSERR == i) || (TIMEOUT == i))
    {
        kill(tid);
        failif(TRUE, "Returned SYSERR or TIMEOUT");
    }
    else
    {
        failif((FALSE == netaddrequal(&addrbuf, &hwaddr)),
               "Wrong address");
    }

    /* Test arpLookup */
    testPrint(verbose, "Lookup timeout");
    praddr.addr[3] = 4;
    hwaddr.addr[5] = 0xDD;
    control(ELOOP, ELOOP_CTRL_SETFLAG, ELOOP_FLAG_DROPALL, NULL);
    failif((SYSERR != arpLookup(netptr, &praddr, &addrbuf)), "");

    /* Stop loopback ethernet and network interface */
    testPrint(verbose, "Test case cleanup");
    for (i = 0; i < ARP_NENTRY; i++)
    {
        arpFree(&arptab[i]);
    }
    failif(((SYSERR == netFreebuf(pkt)) || (SYSERR == netDown(ELOOP))
            || (SYSERR == close(ELOOP))), "");

    if (passed)
    {
        testPass(TRUE, "");
    }
    else
    {
        testFail(TRUE, "");
    }

    return OK;
}
Пример #21
0
Файл: shell.c Проект: osa1/osdev
/**
 * @ingroup shell
 *
 * The Xinu shell.  Provides an interface to execute commands.
 * @param descrp descriptor of device on which the shell is open
 * @return OK for successful exit, SYSERR for unrecoverable error
 */
thread shell(int indescrp, int outdescrp, int errdescrp)
{
    char buf[SHELL_BUFLEN];     /* line input buffer        */
    short buflen;               /* length of line input     */
    char tokbuf[SHELL_BUFLEN + SHELL_MAXTOK];   /* token value buffer       */
    short ntok;                 /* number of tokens         */
    char *tok[SHELL_MAXTOK];    /* pointers to token values */
    char *outname;              /* name of output file      */
    char *inname;               /* name of input file       */
    bool background;            /* is background proccess?  */
    syscall child;              /* pid of child thread      */
    ushort i, j;                /* temp variables           */
    irqmask im;                 /* interrupt mask state     */
    char *hostptr = NULL;       /* pointer to hostname      */

    /* Setup buffer for string for nvramGet call for hostname */
#if defined(ETH0) && NVRAM
    char hostnm[NET_HOSTNM_MAXLEN + 1]; /* hostname of backend      */
    if (!isbaddev(ETH0))
    {
        size_t hostname_strsz;          /* nvram hostname name size */

        bzero(hostnm, NET_HOSTNM_MAXLEN + 1);

        /* Determine the hostname of the main network device */
        hostname_strsz = strlen(NET_HOSTNAME);
        hostname_strsz += 1;
        hostname_strsz += DEVMAXNAME;
        hostname_strsz += 1;
        char nvramget_hostname_str[hostname_strsz];
        sprintf(nvramget_hostname_str, "%s_%s", devtab[ETH0].name,
                NET_HOSTNAME);

        /* Acquire the backend's hostname */
        hostptr = nvramGet(nvramget_hostname_str);
        if (hostptr != NULL)
        {
            strncpy(hostnm, hostptr, NET_HOSTNM_MAXLEN);
            hostptr = hostnm;
        }
    }
#endif

    /* Set command devices for input, output, and error */
    stdin = indescrp;
    stdout = outdescrp;
    stderr = errdescrp;

    /* Print shell banner to framebuffer, if exists */
#if defined(FRAMEBUF)
    if (indescrp == FRAMEBUF)
    {
        foreground = RASPBERRY;
        printf(SHELL_BANNER_NONVT100);
        foreground = LEAFGREEN;
        printf(SHELL_START);
        foreground = GREEN;
    }
    else
#endif
    {
        printf(SHELL_BANNER);
        printf(SHELL_START);
    }

    /* Continually receive and handle commands */
    while (TRUE)
    {
        /* Display prompt */
        printf(SHELL_PROMPT);

        if (NULL != hostptr)
        {
            printf("@%s$ ", hostptr);
        }
        else
        {
            printf("$ ");
        }

        /* Setup proper tty modes for input and output */
        control(stdin, TTY_CTRL_CLR_IFLAG, TTY_IRAW, NULL);
        control(stdin, TTY_CTRL_SET_IFLAG, TTY_ECHO, NULL);

        /* Read command */
        buflen = read(stdin, buf, SHELL_BUFLEN - 1);

        /* Check for EOF and exit gracefully if seen */
        if (EOF == buflen)
        {
            break;
        }

        /* Parse line input into tokens */
        if (SYSERR == (ntok = lexan(buf, buflen, &tokbuf[0], &tok[0])))
        {
            fprintf(stderr, SHELL_SYNTAXERR);
            continue;
        }

        /* Ensure parse generated tokens */
        if (0 == ntok)
        {
            continue;
        }

        /* Initialize command options */
        inname = NULL;
        outname = NULL;
        background = FALSE;

        /* Mark as background thread, if last token is '&' */
        if ('&' == *tok[ntok - 1])
        {
            ntok--;
            background = TRUE;
        }

        /* Check each token and perform special handling of '>' and '<' */
        for (i = 0; i < ntok; i++)
        {
            /* Background '&' should have already been handled; Syntax error */
            if ('&' == *tok[i])
            {
                ntok = -1;
                break;
            }

            /* Setup for output redirection if token is '>'  */
            if ('>' == *tok[i])
            {
                /* Syntax error */
                if (outname != NULL || i >= ntok - 1)
                {
                    ntok = -1;
                    break;
                }

                outname = tok[i + 1];
                ntok -= 2;

                /* shift tokens (not to be passed to command */
                for (j = i; j < ntok; j++)
                {
                    tok[j] = tok[j + 2];
                }
                continue;
            }

            /* Setup for input redirection if token is '<' */
            if ('<' == *tok[i])
            {
                /* Syntax error */
                if (inname != NULL || i >= ntok - 1)
                {
                    ntok = -1;
                    break;
                }
                inname = tok[i + 1];
                ntok -= 2;

                /* shift tokens (not to be passed to command */
                for (j = i; j < ntok; j++)
                {
                    tok[j] = tok[j + 2];
                }

                continue;
            }
        }

        /* Handle syntax error */
        if (ntok <= 0)
        {
            fprintf(stderr, SHELL_SYNTAXERR);
            continue;
        }

        /* Lookup first token in the command table */
        for (i = 0; i < ncommand; i++)
        {
            if (0 == strcmp(commandtab[i].name, tok[0]))
            {
                break;
            }
        }

        /* Handle command not found */
        if (i >= ncommand)
        {
            fprintf(stderr, "%s: command not found\n", tok[0]);
            continue;
        }

        /* Handle command if it is built-in */
        if (commandtab[i].builtin)
        {
            if (inname != NULL || outname != NULL || background)
            {
                fprintf(stderr, SHELL_SYNTAXERR);
            }
            else
            {
                (*commandtab[i].procedure) (ntok, tok);
            }
            continue;
        }

        /* Spawn child thread for non-built-in commands */
        child =
            create(commandtab[i].procedure,
                   SHELL_CMDSTK, SHELL_CMDPRIO,
                   commandtab[i].name, 2, ntok, tok);

        /* Ensure child command thread was created successfully */
        if (SYSERR == child)
        {
            fprintf(stderr, SHELL_CHILDERR);
            continue;
        }

        /* Set file descriptors for newly created thread */
        if (NULL == inname)
        {
            thrtab[child].fdesc[0] = stdin;
        }
        else
        {
            thrtab[child].fdesc[0] = getdev(inname);
        }
        if (NULL == outname)
        {
            thrtab[child].fdesc[1] = stdout;
        }
        else
        {
            thrtab[child].fdesc[1] = getdev(outname);
        }
        thrtab[child].fdesc[2] = stderr;

        if (background)
        {
            /* Make background thread ready, but don't reschedule */
            im = disable();
            ready(child, RESCHED_NO);
            restore(im);
        }
        else
        {
            /* Clear waiting message; Reschedule; */
            while (recvclr() != NOMSG);
            im = disable();
            ready(child, RESCHED_YES);
            restore(im);

            /* Wait for command thread to finish */
            while (receive() != child);
            sleep(10);
        }
    }

    /* Close shell */
    fprintf(stdout, SHELL_EXIT);
    sleep(10);
    return OK;
}
Пример #22
0
/*------------------------------------------------------------------------
 * arp_resolve  -  Use ARP to resolve an IP address to an Ethernet address
 *------------------------------------------------------------------------
 */
status	arp_resolve (
    uint32	nxthop,			/* Next-hop address to resolve	*/
    byte	mac[ETH_ADDR_LEN]	/* Array into which Ethernet	*/
)				/*   address should be placed	*/
{
    intmask	mask;			/* Saved interrupt mask		*/
    struct	arppacket apkt;		/* Local packet buffer		*/
    int32	i;			/* Index into arpcache		*/
    int32	slot;			/* ARP table slot to use	*/
    struct	arpentry  *arptr;	/* Ptr to ARP cache entry	*/
    int32	msg;			/* Message returned by recvtime	*/

    /* Use MAC broadcast address for IP limited broadcast */

    if (nxthop == IP_BCAST) {
        memcpy(mac, NetData.ethbcast, ETH_ADDR_LEN);
        return OK;
    }

    /* Use MAC broadcast address for IP network broadcast */

    if (nxthop == NetData.ipbcast) {
        memcpy(mac, NetData.ethbcast, ETH_ADDR_LEN);
        return OK;
    }

    /* Ensure only one process uses ARP at a time */

    mask = disable();

    /* See if next hop address is already present in ARP cache */

    for (i=0; i<ARP_SIZ; i++) {
        arptr = &arpcache[i];
        if (arptr->arstate == AR_FREE) {
            continue;
        }
        if (arptr->arpaddr == nxthop) { /* Adddress is in cache	*/
            break;
        }
    }

    if (i < ARP_SIZ) {	/* Entry was found */

        /* If entry is resolved - handle and return */

        if (arptr->arstate == AR_RESOLVED) {
            memcpy(mac, arptr->arhaddr, ARP_HALEN);
            restore(mask);
            return OK;
        }

        /* Entry is already pending -  return error because	*/
        /*	only one process can be	waiting at a time	*/

        if (arptr->arstate == AR_PENDING) {
            restore(mask);
            return SYSERR;
        }
    }

    /* IP address not in cache -  allocate a new cache entry and	*/
    /*	send an ARP request to obtain the answer		*/

    slot = arp_alloc();
    if (slot == SYSERR) {
        restore(mask);
        return SYSERR;
    }

    arptr = &arpcache[slot];
    arptr->arstate = AR_PENDING;
    arptr->arpaddr = nxthop;
    arptr->arpid = currpid;

    /* Hand-craft an ARP Request packet */

    memcpy(apkt.arp_ethdst, NetData.ethbcast, ETH_ADDR_LEN);
    memcpy(apkt.arp_ethsrc, NetData.ethucast, ETH_ADDR_LEN);
    apkt.arp_ethtype = ETH_ARP;	  /* Packet type is ARP		*/
    apkt.arp_htype = ARP_HTYPE;	  /* Hardware type is Ethernet	*/
    apkt.arp_ptype = ARP_PTYPE;	  /* Protocol type is IP	*/
    apkt.arp_hlen = 0xff & ARP_HALEN; /* Ethernet MAC size in bytes	*/
    apkt.arp_plen = 0xff & ARP_PALEN; /* IP address size in bytes	*/
    apkt.arp_op = 0xffff & ARP_OP_REQ;/* ARP type is Request	*/
    memcpy(apkt.arp_sndha, NetData.ethucast, ARP_HALEN);
    apkt.arp_sndpa = NetData.ipucast; /* IP address of interface	*/
    memset(apkt.arp_tarha, '\0', ARP_HALEN); /* Target HA is unknown*/
    apkt.arp_tarpa = nxthop;	  /* Target protocol address	*/

    /* Convert ARP packet from host to net byte order */

    arp_hton(&apkt);

    /* Convert Ethernet header from host to net byte order */

    eth_hton((struct netpacket *)&apkt);

    /* Send the packet ARP_RETRY times and await response */

    msg = recvclr();
    for (i=0; i<ARP_RETRY; i++) {
        write(ETHER0, (char *)&apkt, sizeof(struct arppacket));
        msg = recvtime(ARP_TIMEOUT);
        if (msg == TIMEOUT) {
            continue;
        } else if (msg == SYSERR) {
            restore(mask);
            return SYSERR;
        } else {	/* entry is resolved */
            break;
        }
    }

    /* If no response, return TIMEOUT */

    if (msg == TIMEOUT) {
        arptr->arstate = AR_FREE;   /* Invalidate cache entry */
        restore(mask);
        return TIMEOUT;
    }

    /* Return hardware address */

    memcpy(mac, arptr->arhaddr, ARP_HALEN);
    restore(mask);
    return OK;
}