static void change(char *dev, char *what, unsigned char *addr, unsigned char *netmask) { char addr_buf[sizeof("255.255.255.255\0")]; char netmask_buf[sizeof("255.255.255.255\0")]; char version[sizeof("nnnnn\0")]; char *argv[] = { "uml_net", version, what, dev, addr_buf, netmask_buf, NULL }; char *output; int output_len, pid; sprintf(version, "%d", UML_NET_VERSION); sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]); output_len = page_size(); output = um_kmalloc(output_len); if(output == NULL) printk("change : failed to allocate output buffer\n"); pid = change_tramp(argv, output, output_len); if(pid < 0) return; if(output != NULL){ printk("%s", output); kfree(output); } }
static int slip_tramp(char **argv, int fd) { struct slip_pre_exec_data pe_data; char *output; int status, pid, fds[2], err, output_len; err = os_pipe(fds, 1, 0); if(err < 0){ printk("slip_tramp : pipe failed, err = %d\n", -err); goto out; } err = 0; pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; err = run_helper(slip_pre_exec, &pe_data, argv, NULL); if(err < 0) goto out_close; pid = err; output_len = page_size(); output = um_kmalloc(output_len); if(output == NULL){ printk("slip_tramp : failed to allocate output buffer\n"); os_kill_process(pid, 1); err = -ENOMEM; goto out_free; } os_close_file(fds[1]); read_output(fds[0], output, output_len); printk("%s", output); CATCH_EINTR(err = waitpid(pid, &status, 0)); if(err < 0) err = errno; else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ printk("'%s' didn't exit with status 0\n", argv[0]); err = -EINVAL; } else err = 0; os_close_file(fds[0]); out_free: kfree(output); return err; out_close: os_close_file(fds[0]); os_close_file(fds[1]); out: return err; }
static struct sockaddr_un *new_addr(void *name, int len) { struct sockaddr_un *sun; sun = um_kmalloc(sizeof(struct sockaddr_un)); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); return(NULL); } sun->sun_family = AF_UNIX; memcpy(sun->sun_path, name, len); return(sun); }
static struct sockaddr_in *new_addr(char *addr, unsigned short port) { struct sockaddr_in *sin; sin = um_kmalloc(sizeof(struct sockaddr_in)); if(sin == NULL){ printk("new_addr: allocation of sockaddr_in failed\n"); return NULL; } sin->sin_family = AF_INET; sin->sin_addr.s_addr = in_aton(addr); sin->sin_port = htons(port); return sin; }
static int etap_open(void *data) { struct ethertap_data *pri = data; char *output; int data_fds[2], control_fds[2], err, output_len; err = tap_open_common(pri->dev, pri->gate_addr); if(err) return(err); err = os_pipe(data_fds, 0, 0); if(err < 0){ printk("data os_pipe failed - err = %d\n", -err); return(err); } err = os_pipe(control_fds, 1, 0); if(err < 0){ printk("control os_pipe failed - err = %d\n", -err); return(err); } err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); output_len = page_size(); output = um_kmalloc(output_len); read_output(control_fds[0], output, output_len); if(output == NULL) printk("etap_open : failed to allocate output buffer\n"); else { printk("%s", output); kfree(output); } if(err < 0){ printk("etap_tramp failed - err = %d\n", -err); return(err); } pri->data_fd = data_fds[0]; pri->control_fd = control_fds[0]; iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); return(data_fds[0]); }
static int pcap_open(void *data) { struct pcap_data *pri = data; __u32 netmask; int err; if(pri->pcap == NULL) return(-ENODEV); if(pri->filter != NULL){ err = dev_netmask(pri->dev, &netmask); if(err < 0){ printk("pcap_open : dev_netmask failed\n"); return(-EIO); } pri->compiled = um_kmalloc(sizeof(struct bpf_program)); if(pri->compiled == NULL){ printk("pcap_open : kmalloc failed\n"); return(-ENOMEM); } err = pcap_compile(pri->pcap, (struct bpf_program *) pri->compiled, pri->filter, pri->optimize, netmask); if(err < 0){ printk("pcap_open : pcap_compile failed - '%s'\n", pcap_geterr(pri->pcap)); return(-EIO); } err = pcap_setfilter(pri->pcap, pri->compiled); if(err < 0){ printk("pcap_open : pcap_setfilter failed - '%s'\n", pcap_geterr(pri->pcap)); return(-EIO); } } return(PCAP_FD(pri->pcap)); }
static int slip_tramp(char **argv, int fd) { struct slip_pre_exec_data pe_data; char *output; int status, pid, fds[2], err, output_len; err = os_pipe(fds, 1, 0); if(err){ printk("slip_tramp : pipe failed, errno = %d\n", -err); return(err); } err = 0; pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); if(pid < 0) err = pid; else { output_len = page_size(); output = um_kmalloc(output_len); if(output == NULL) printk("slip_tramp : failed to allocate output " "buffer\n"); close(fds[1]); read_output(fds[0], output, output_len); if(output != NULL){ printk("%s", output); kfree(output); } if(waitpid(pid, &status, 0) < 0) err = errno; else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ printk("'%s' didn't exit with status 0\n", argv[0]); err = EINVAL; } } return(err); }
static void etap_change(int op, unsigned char *addr, unsigned char *netmask, int fd) { struct addr_change change; char *output; int n; change.what = op; memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); n = os_write_file(fd, &change, sizeof(change)); if(n != sizeof(change)) printk("etap_change - request failed, err = %d\n", -n); output = um_kmalloc(page_size()); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); read_output(fd, output, page_size()); if(output != NULL){ printk("%s", output); kfree(output); } }
static int connect_to_switch(struct daemon_data *pri) { struct sockaddr_un *ctl_addr = pri->ctl_addr; struct sockaddr_un *local_addr = pri->local_addr; struct sockaddr_un *sun; struct request_v3 req; int fd, n, err; pri->control = socket(AF_UNIX, SOCK_STREAM, 0); if(pri->control < 0){ printk("daemon_open : control socket failed, errno = %d\n", errno); return(-errno); } if(connect(pri->control, (struct sockaddr *) ctl_addr, sizeof(*ctl_addr)) < 0){ printk("daemon_open : control connect failed, errno = %d\n", errno); err = -errno; goto out; } fd = socket(AF_UNIX, SOCK_DGRAM, 0); if(fd < 0){ printk("daemon_open : data socket failed, errno = %d\n", errno); err = -errno; goto out; } if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){ printk("daemon_open : data bind failed, errno = %d\n", errno); err = -errno; goto out_close; } sun = um_kmalloc(sizeof(struct sockaddr_un)); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); err = -ENOMEM; goto out_close; } req.magic = SWITCH_MAGIC; req.version = SWITCH_VERSION; req.type = REQ_NEW_CONTROL; req.sock = *local_addr; n = os_write_file(pri->control, &req, sizeof(req)); if(n != sizeof(req)){ printk("daemon_open : control setup request failed, err = %d\n", -n); err = -ENOTCONN; goto out_free; } n = os_read_file(pri->control, sun, sizeof(*sun)); if(n != sizeof(*sun)){ printk("daemon_open : read of data socket failed, err = %d\n", -n); err = -ENOTCONN; goto out_free; } pri->data_addr = sun; return(fd); out_free: kfree(sun); out_close: os_close_file(fd); out: os_close_file(pri->control); return(err); }