⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev_vtty.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 2 页
字号:
         close(vtty->fd);         vtty->fstream = NULL;         vtty->fd = -1;         vtty->select_fd = &vtty->accept_fd;         vtty->state = VTTY_STATE_TCP_WAITING;         return(-1);      case VTTY_STATE_TCP_WAITING:         /* A new connection has arrived */         vtty_tcp_conn_accept(vtty);         return(-1);   }   /* Shouldn't happen... */   return(-1);}/* * Read a character from the virtual TTY. * * If the VTTY is a TCP connection, restart it in case of error. */static int vtty_read(vtty_t *vtty){   switch(vtty->type) {      case VTTY_TYPE_TERM:      case VTTY_TYPE_SERIAL:         return(vtty_term_read(vtty));      case VTTY_TYPE_TCP:         return(vtty_tcp_read(vtty));      default:         fprintf(stderr,"vtty_read: bad vtty type %d\n",vtty->type);         return(-1);   }   /* NOTREACHED */   return(-1);}/* Remote control for MIPS64 processors */static int remote_control_mips64(vtty_t *vtty,char c,cpu_mips_t *cpu){   switch(c) {          /* Show information about JIT compiled pages */      case 'b':         printf("\nCPU0: %u JIT compiled pages [Exec Area Pages: %lu/%lu]\n",                cpu->compiled_pages,                (u_long)cpu->exec_page_alloc,                (u_long)cpu->exec_page_count);         break;      /* Non-JIT mode statistics */      case 'j':         mips64_dump_stats(cpu);         break;      default:         return(FALSE);   }   return(TRUE);}/* Remote control for PPC32 processors */static int remote_control_ppc32(vtty_t *vtty,char c,cpu_ppc_t *cpu){   switch(c) {      /* Show information about JIT compiled pages */      case 'b':         printf("\nCPU0: %u JIT compiled pages [Exec Area Pages: %lu/%lu]\n",                cpu->compiled_pages,                (u_long)cpu->exec_page_alloc,                (u_long)cpu->exec_page_count);         break;      /* Non-JIT mode statistics */      case 'j':         ppc32_dump_stats(cpu);         break;      default:         return(FALSE);   }      return(TRUE);}/* Process remote control char */static void remote_control(vtty_t *vtty,u_char c){   vm_instance_t *vm = vtty->vm;   cpu_gen_t *cpu0;     cpu0 = vm->boot_cpu;   /* Specific commands for the different CPU models */   if (cpu0) {      switch(cpu0->type) {         case CPU_TYPE_MIPS64:            if (remote_control_mips64(vtty,c,CPU_MIPS64(cpu0)))               return;            break;         case CPU_TYPE_PPC32:            if (remote_control_ppc32(vtty,c,CPU_PPC32(cpu0)))               return;            break;      }   }   switch(c) {      /* Show the object list */      case 'o':         vm_object_dump(vm);         break;        /* Stop the MIPS VM */      case 'q':         vm->status = VM_STATUS_SHUTDOWN;         break;        /* Reboot the C7200 */      case 'k':#if 0         if (vm->type == VM_TYPE_C7200)            c7200_boot_ios(VM_C7200(vm));#endif         break;        /* Show the device list */      case 'd':         dev_show_list(vm);         pci_dev_show_list(vm->pci_bus[0]);         pci_dev_show_list(vm->pci_bus[1]);         break;      /* Show info about Port Adapters or Network Modules */      case 'p':         vm_slot_show_all_info(vm);         break;        /* Dump the MIPS registers */      case 'r':         if (cpu0) cpu0->reg_dump(cpu0);         break;      /* Dump the latest memory accesses */      case 'm':         if (cpu0) memlog_dump(cpu0);         break;                     /* Suspend CPU emulation */      case 's':         vm_suspend(vm);         break;        /* Resume CPU emulation */      case 'u':         vm_resume(vm);         break;        /* Dump the MMU information */      case 't':         if (cpu0) cpu0->mmu_dump(cpu0);         break;        /* Dump the MMU information (raw mode) */      case 'z':         if (cpu0) cpu0->mmu_raw_dump(cpu0);         break;      /* Memory translation cache statistics */      case 'l':         if (cpu0) cpu0->mts_show_stats(cpu0);         break;      /* Extract the configuration from the NVRAM */      case 'c':         vm_ios_save_config(vm);         break;        /* Determine an idle pointer counter */      case 'i':         if (cpu0)            cpu0->get_idling_pc(cpu0);         break;        /* Experimentations / Tests */      case 'x':         if (cpu0) {            /* IRQ triggering */            //vm_set_irq(vm,5);            CPU_MIPS64(cpu0)->irq_disable = TRUE;         }         break;      case 'y':         if (cpu0) {            /* IRQ clearing */            vm_clear_irq(vm,5);         }         break;      /* Twice Ctrl + ']' (0x1d, 29), or Alt-Gr + '*' (0xb3, 179) */      case 0x1d:      case 0xb3:         vtty_store(vtty,c);         break;               default:         printf("\n\nInstance %s (ID %d)\n\n",vm->name,vm->instance_id);                  printf("o     - Show the VM object list\n"                "d     - Show the device list\n"                "r     - Dump CPU registers\n"                "t     - Dump MMU information\n"                "z     - Dump MMU information (raw mode)\n"                "m     - Dump the latest memory accesses\n"                "s     - Suspend CPU emulation\n"                "u     - Resume CPU emulation\n"                "q     - Quit the emulator\n"                "k     - Reboot the virtual machine\n"                "b     - Show info about JIT compiled pages\n"                "l     - MTS cache statistics\n"                "c     - Write IOS configuration to disk\n"                "j     - Non-JIT mode statistics\n"                "i     - Determine an idling pointer counter\n"                "x     - Experimentations (can crash the box!)\n"                "^]    - Send ^]\n"                "Other - This help\n");   }}    /* Read a character (until one is available) and store it in buffer */static void vtty_read_and_store(vtty_t *vtty){   int c;      /* wait until we get a character input */   c = vtty_read(vtty);     /* if read error, do nothing */   if (c < 0) return;     if (!vtty->terminal_support) {      vtty_store(vtty,c);      return;   }     switch(vtty->input_state) {      case VTTY_INPUT_TEXT :         switch(c) {            case 0x1b:               vtty->input_state = VTTY_INPUT_VT1;               return;            /* Ctrl + ']' (0x1d, 29), or Alt-Gr + '*' (0xb3, 179) */            case 0x1d:            case 0xb3:               vtty->input_state = VTTY_INPUT_REMOTE;               return;            case IAC :               vtty->input_state = VTTY_INPUT_TELNET;               return;            case 0:  /* NULL - Must be ignored - generated by Linux telnet */            case 10: /* LF (Line Feed) - Must be ignored on Windows platform */               return;            default:               /* Store a standard character */               vtty_store(vtty,c);               return;         }               case VTTY_INPUT_VT1 :         switch(c) {            case 0x5b:               vtty->input_state = VTTY_INPUT_VT2;               return;            default:               vtty_store(vtty,0x1b);               vtty_store(vtty,c);         }         vtty->input_state = VTTY_INPUT_TEXT;         return;        case VTTY_INPUT_VT2 :         switch(c) {            case 0x41:   /* Up Arrow */               vtty_store(vtty,16);               break;            case 0x42:   /* Down Arrow */               vtty_store(vtty,14);               break;            case 0x43:   /* Right Arrow */               vtty_store(vtty,6);               break;            case 0x44:   /* Left Arrow */               vtty_store(vtty,2);               break;            default:               vtty_store(vtty,0x5b);               vtty_store(vtty,0x1b);               vtty_store(vtty,c);               break;         }         vtty->input_state = VTTY_INPUT_TEXT;         return;        case VTTY_INPUT_REMOTE :         remote_control(vtty, c);         vtty->input_state = VTTY_INPUT_TEXT;         return;        case VTTY_INPUT_TELNET :         vtty->telnet_cmd = c;         switch(c) {            case WILL:            case WONT:            case DO:            case DONT:               vtty->input_state = VTTY_INPUT_TELNET_IYOU;               return;            case SB :               vtty->telnet_cmd = c;               vtty->input_state = VTTY_INPUT_TELNET_SB1;               return;            case SE:               break;            case IAC :               vtty_store(vtty, IAC);               break;         }         vtty->input_state = VTTY_INPUT_TEXT;         return;        case VTTY_INPUT_TELNET_IYOU :         vtty->telnet_opt = c;         /* if telnet client can support ttype, ask it to send ttype string */         if ((vtty->telnet_cmd == WILL) &&              (vtty->telnet_opt == TELOPT_TTYPE))          {            vtty_put_char(vtty, IAC);            vtty_put_char(vtty, SB);            vtty_put_char(vtty, TELOPT_TTYPE);            vtty_put_char(vtty, TELQUAL_SEND);            vtty_put_char(vtty, IAC);            vtty_put_char(vtty, SE);         }         vtty->input_state = VTTY_INPUT_TEXT;         return;        case VTTY_INPUT_TELNET_SB1 :         vtty->telnet_opt = c;         vtty->input_state = VTTY_INPUT_TELNET_SB2;         return;        case VTTY_INPUT_TELNET_SB2 :         vtty->telnet_qual = c;         if ((vtty->telnet_opt == TELOPT_TTYPE) &&              (vtty->telnet_qual == TELQUAL_IS))            vtty->input_state = VTTY_INPUT_TELNET_SB_TTYPE;         else            vtty->input_state = VTTY_INPUT_TELNET_NEXT;         return;        case VTTY_INPUT_TELNET_SB_TTYPE :         /* parse ttype string: first char is sufficient */         /* if client is xterm or vt, set the title bar */         if ((c == 'x') || (c == 'X') || (c == 'v') || (c == 'V')) {            fprintf(vtty->fstream, "\033]0;Dynamips(%i): %s, %s\07",                     vtty->vm->instance_id, vtty->vm->name, vtty->name);         }         vtty->input_state = VTTY_INPUT_TELNET_NEXT;         return;        case VTTY_INPUT_TELNET_NEXT :         /* ignore all chars until next IAC */         if (c == IAC)            vtty->input_state = VTTY_INPUT_TELNET;         return;   }}/* Read a character from the buffer (-1 if the buffer is empty) */int vtty_get_char(vtty_t *vtty){   u_char c;   VTTY_LOCK(vtty);      if (vtty->read_ptr == vtty->write_ptr) {      VTTY_UNLOCK(vtty);      return(-1);   }      c = vtty->buffer[vtty->read_ptr++];   if (vtty->read_ptr == VTTY_BUFFER_SIZE)      vtty->read_ptr = 0;   VTTY_UNLOCK(vtty);   return(c);}/* Returns TRUE if a character is available in buffer */int vtty_is_char_avail(vtty_t *vtty){   int res;   VTTY_LOCK(vtty);   res = (vtty->read_ptr != vtty->write_ptr);   VTTY_UNLOCK(vtty);   return(res);}/* Put char to vtty */void vtty_put_char(vtty_t *vtty, char ch){   switch(vtty->type) {      case VTTY_TYPE_NONE:         break;      case VTTY_TYPE_TERM:         fwrite(&ch, 1, 1, vtty->fstream);         break;      case VTTY_TYPE_TCP:         if ((vtty->state == VTTY_STATE_TCP_RUNNING) &&              (fwrite(&ch, 1, 1, vtty->fstream) != 1))         {            vm_log(vtty->vm,"VTTY","%s: put char %d failed (%s)\n",                   vtty->name,(int)ch,strerror(errno));         }         break;      case VTTY_TYPE_SERIAL:         if (write(vtty->fd,&ch,1) != 1) {            vm_log(vtty->vm,"VTTY","%s: put char 0x%x failed (%s)\n",                   vtty->name,(int)ch,strerror(errno));         }         break;      default:         fprintf(stderr,"vtty_put_char: bad vtty type %d\n",vtty->type);         exit(1);   }}/* Put a buffer to vtty */void vtty_put_buffer(vtty_t *vtty,char *buf,size_t len){   size_t i;   for(i=0;i<len;i++)      vtty_put_char(vtty,buf[i]);      vtty_flush(vtty);}/* Flush VTTY output */void vtty_flush(vtty_t *vtty){   switch(vtty->type) {      case VTTY_TYPE_TERM:      case VTTY_TYPE_TCP:         if (vtty->fstream != NULL)            fflush(vtty->fstream);         break;      case VTTY_TYPE_SERIAL:         if (vtty->fd != -1)            fsync(vtty->fd);         break;   }}/* VTTY thread */static void *vtty_thread_main(void *arg){   vtty_t *vtty;   struct timeval tv;   int fd,fd_max,res;   fd_set rfds;   for(;;) {      VTTY_LIST_LOCK();      /* Build the FD set */      FD_ZERO(&rfds);      fd_max = -1;      for(vtty=vtty_list;vtty;vtty=vtty->next) {         if (!vtty->select_fd)            continue;         if ((fd = *vtty->select_fd) < 0)            continue;         if (fd > fd_max) fd_max = fd;         FD_SET(fd,&rfds);      }      VTTY_LIST_UNLOCK();      /* Wait for incoming data */      tv.tv_sec  = 0;      tv.tv_usec = 50 * 1000;  /* 50 ms */      res = select(fd_max+1,&rfds,NULL,NULL,&tv);      if (res == -1) {         if (errno != EINTR) {            perror("vtty_thread: select");            for(vtty=vtty_list;vtty;vtty=vtty->next) {               fprintf(stderr,"   %-15s: %s, FD %d\n",                       vtty->vm->name,vtty->name,vtty->fd);            }         }         continue;      }      /* Examine active FDs and call user handlers */      VTTY_LIST_LOCK();      for(vtty=vtty_list;vtty;vtty=vtty->next) {         if (!vtty->select_fd)            continue;                  if ((fd = *vtty->select_fd) < 0)            continue;                  if (FD_ISSET(fd,&rfds)) {            vtty_read_and_store(vtty);            vtty->input_pending = TRUE;         }         if (vtty->input_pending) {            if (vtty->read_notifier != NULL)               vtty->read_notifier(vtty);            vtty->input_pending = FALSE;         }         /* Flush any pending output */         if (!vtty->managed_flush)            vtty_flush(vtty);      }      VTTY_LIST_UNLOCK();   }      return NULL;}/* Initialize the VTTY thread */int vtty_init(void){   if (pthread_create(&vtty_thread,NULL,vtty_thread_main,NULL)) {      perror("vtty: pthread_create");      return(-1);   }   return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -