📄 vl.c
字号:
for(j=0;j<len;j++) { c = buf[i+j]; if (c < ' ' || c > '~') c = '.'; fprintf(f, "%c", c); } fprintf(f, "\n"); }}static int parse_macaddr(uint8_t *macaddr, const char *p){ int i; for(i = 0; i < 6; i++) { macaddr[i] = strtol(p, (char **)&p, 16); if (i == 5) { if (*p != '\0') return -1; } else { if (*p != ':') return -1; p++; } } return 0;}static int get_str_sep(char *buf, int buf_size, const char **pp, int sep){ const char *p, *p1; int len; p = *pp; p1 = strchr(p, sep); if (!p1) return -1; len = p1 - p; p1++; if (buf_size > 0) { if (len > buf_size - 1) len = buf_size - 1; memcpy(buf, p, len); buf[len] = '\0'; } *pp = p1; return 0;}int parse_host_port(struct sockaddr_in *saddr, const char *str){ char buf[512]; struct hostent *he; const char *p, *r; int port; p = str; if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) return -1; saddr->sin_family = AF_INET; if (buf[0] == '\0') { saddr->sin_addr.s_addr = 0; } else { if (isdigit(buf[0])) { if (!inet_aton(buf, &saddr->sin_addr)) return -1; } else { if ((he = gethostbyname(buf)) == NULL) return - 1; saddr->sin_addr = *(struct in_addr *)he->h_addr; } } port = strtol(p, (char **)&r, 0); if (r == p) return -1; saddr->sin_port = htons(port); return 0;}/* find or alloc a new VLAN */VLANState *qemu_find_vlan(int id){ VLANState **pvlan, *vlan; for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) { if (vlan->id == id) return vlan; } vlan = qemu_mallocz(sizeof(VLANState)); if (!vlan) return NULL; vlan->id = id; vlan->next = NULL; pvlan = &first_vlan; while (*pvlan != NULL) pvlan = &(*pvlan)->next; *pvlan = vlan; return vlan;}VLANClientState *qemu_new_vlan_client(VLANState *vlan, IOReadHandler *fd_read, IOCanRWHandler *fd_can_read, void *opaque){ VLANClientState *vc, **pvc; vc = qemu_mallocz(sizeof(VLANClientState)); if (!vc) return NULL; vc->fd_read = fd_read; vc->fd_can_read = fd_can_read; vc->opaque = opaque; vc->vlan = vlan; vc->next = NULL; pvc = &vlan->first_client; while (*pvc != NULL) pvc = &(*pvc)->next; *pvc = vc; return vc;}int qemu_can_send_packet(VLANClientState *vc1){ VLANState *vlan = vc1->vlan; VLANClientState *vc; for(vc = vlan->first_client; vc != NULL; vc = vc->next) { if (vc != vc1) { if (vc->fd_can_read && !vc->fd_can_read(vc->opaque)) return 0; } } return 1;}void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size){ VLANState *vlan = vc1->vlan; VLANClientState *vc;#if 0 printf("vlan %d send:\n", vlan->id); hex_dump(stdout, buf, size);#endif for(vc = vlan->first_client; vc != NULL; vc = vc->next) { if (vc != vc1) { vc->fd_read(vc->opaque, buf, size); } }}#if defined(CONFIG_SLIRP)/* slirp network adapter */static int slirp_inited;static VLANClientState *slirp_vc;int slirp_can_output(void){ return !slirp_vc || qemu_can_send_packet(slirp_vc);}void slirp_output(const uint8_t *pkt, int pkt_len){#if 0 printf("slirp output:\n"); hex_dump(stdout, pkt, pkt_len);#endif if (!slirp_vc) return; qemu_send_packet(slirp_vc, pkt, pkt_len);}static void slirp_receive(void *opaque, const uint8_t *buf, int size){#if 0 printf("slirp input:\n"); hex_dump(stdout, buf, size);#endif slirp_input(buf, size);}static int net_slirp_init(VLANState *vlan){ if (!slirp_inited) { slirp_inited = 1; slirp_init(); } slirp_vc = qemu_new_vlan_client(vlan, slirp_receive, NULL, NULL); snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector"); return 0;}static void net_slirp_redir(const char *redir_str){ int is_udp; char buf[256], *r; const char *p; struct in_addr guest_addr; int host_port, guest_port; if (!slirp_inited) { slirp_inited = 1; slirp_init(); } p = redir_str; if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) goto fail; if (!strcmp(buf, "tcp")) { is_udp = 0; } else if (!strcmp(buf, "udp")) { is_udp = 1; } else { goto fail; } if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) goto fail; host_port = strtol(buf, &r, 0); if (r == buf) goto fail; if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) goto fail; if (buf[0] == '\0') { pstrcpy(buf, sizeof(buf), "10.0.2.15"); } if (!inet_aton(buf, &guest_addr)) goto fail; guest_port = strtol(p, &r, 0); if (r == p) goto fail; if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) { fprintf(stderr, "qemu: could not set up redirection\n"); exit(1); } return; fail: fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n"); exit(1);} #ifndef _WIN32char smb_dir[1024];static void smb_exit(void){ DIR *d; struct dirent *de; char filename[1024]; /* erase all the files in the directory */ d = opendir(smb_dir); for(;;) { de = readdir(d); if (!de) break; if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) { snprintf(filename, sizeof(filename), "%s/%s", smb_dir, de->d_name); unlink(filename); } } closedir(d); rmdir(smb_dir);}/* automatic user mode samba server configuration */void net_slirp_smb(const char *exported_dir){ char smb_conf[1024]; char smb_cmdline[1024]; FILE *f; if (!slirp_inited) { slirp_inited = 1; slirp_init(); } /* XXX: better tmp dir construction */ snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid()); if (mkdir(smb_dir, 0700) < 0) { fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir); exit(1); } snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf"); f = fopen(smb_conf, "w"); if (!f) { fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf); exit(1); } fprintf(f, "[global]\n" "private dir=%s\n" "smb ports=0\n" "socket address=127.0.0.1\n" "pid directory=%s\n" "lock directory=%s\n" "log file=%s/log.smbd\n" "smb passwd file=%s/smbpasswd\n" "security = share\n" "[qemu]\n" "path=%s\n" "read only=no\n" "guest ok=yes\n", smb_dir, smb_dir, smb_dir, smb_dir, smb_dir, exported_dir ); fclose(f); atexit(smb_exit); snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s", smb_conf); slirp_add_exec(0, smb_cmdline, 4, 139);}#endif /* !defined(_WIN32) */#endif /* CONFIG_SLIRP */#if !defined(_WIN32)typedef struct TAPState { VLANClientState *vc; int fd;} TAPState;static void tap_receive(void *opaque, const uint8_t *buf, int size){ TAPState *s = opaque; int ret; for(;;) { ret = write(s->fd, buf, size); if (ret < 0 && (errno == EINTR || errno == EAGAIN)) { } else { break; } }}static void tap_send(void *opaque){ TAPState *s = opaque; uint8_t buf[4096]; int size; size = read(s->fd, buf, sizeof(buf)); if (size > 0) { qemu_send_packet(s->vc, buf, size); }}/* fd support */static TAPState *net_tap_fd_init(VLANState *vlan, int fd){ TAPState *s; s = qemu_mallocz(sizeof(TAPState)); if (!s) return NULL; s->fd = fd; s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s); qemu_set_fd_handler(s->fd, tap_send, NULL, s); snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd); return s;}#ifdef _BSDstatic int tap_open(char *ifname, int ifname_size){ int fd; char *dev; struct stat s; fd = open("/dev/tap", O_RDWR); if (fd < 0) { fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n"); return -1; } fstat(fd, &s); dev = devname(s.st_rdev, S_IFCHR); pstrcpy(ifname, ifname_size, dev); fcntl(fd, F_SETFL, O_NONBLOCK); return fd;}#elif defined(__sun__)static int tap_open(char *ifname, int ifname_size){ fprintf(stderr, "warning: tap_open not yet implemented\n"); return -1;}#elsestatic int tap_open(char *ifname, int ifname_size){ struct ifreq ifr; int fd, ret; fd = open("/dev/net/tun", O_RDWR); if (fd < 0) { fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n"); return -1; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; if (ifname[0] != '\0') pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname); else pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d"); ret = ioctl(fd, TUNSETIFF, (void *) &ifr); if (ret != 0) { fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n"); close(fd); return -1; } pstrcpy(ifname, ifname_size, ifr.ifr_name); fcntl(fd, F_SETFL, O_NONBLOCK); return fd;}#endifstatic int net_tap_init(VLANState *vlan, const char *ifname1, const char *setup_script){ TAPState *s; int pid, status, fd; char *args[3]; char **parg; char ifname[128]; if (ifname1 != NULL) pstrcpy(ifname, sizeof(ifname), ifname1); else ifname[0] = '\0'; fd = tap_open(ifname, sizeof(ifname)); if (fd < 0) return -1; if (!setup_script) setup_script = ""; if (setup_script[0] != '\0') { /* try to launch network init script */ pid = fork(); if (pid >= 0) { if (pid == 0) { parg = args; *parg++ = (char *)setup_script; *parg++ = ifname; *parg++ = NULL; execv(setup_script, args); _exit(1); } while (waitpid(pid, &status, 0) != pid); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { fprintf(stderr, "%s: could not launch network script\n", setup_script); return -1; } } } s = net_tap_fd_init(vlan, fd); if (!s) return -1; snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: ifname=%s setup_script=%s", ifname, setup_script); return 0;}#endif /* !_WIN32 *//* network connection */typedef struct NetSocketState { VLANClientState *vc; int fd; int state; /* 0 = getting length, 1 = getting data */ int index; int packet_len; uint8_t buf[4096]; struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */} NetSocketState;typedef struct NetSocketListenState { VLANState *vlan; int fd;} NetSocketListenState;/* XXX: we consider we can send the whole packet without blocking */static void net_socket_receive(void *opaque, const uint8_t *buf, int size){ NetSocketState *s = opaque; uint32_t len; len = htonl(size); send_all(s->fd, (const uint8_t *)&len, sizeof(len)); send_all(s->fd, buf, size);}static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size){ NetSocketState *s = opaque; sendto(s->fd, buf, size, 0, (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));}static void net_socket_send(void *opaque){ NetSocketState *s = opaque; int l, size, err; uint8_t buf1[4096]; const uint8_t *buf; size = recv(s->fd, buf1, sizeof(buf1), 0); if (size < 0) { err = socket_error(); if (err != EWOULDBLOCK) goto eoc; } else if (size == 0) { /* end of connection */ eoc: qemu_set_fd_handler(s->fd, NULL, NULL, NULL); closesocket(s->fd); return; } buf = buf1; while (size > 0) { /* reassemble a packet from the network */ switch(s->state) { case 0: l = 4 - s->index;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -