/* receive an incoming message from a remote user that we are connected to, * given their socket / file descriptor */ void receive_message(int fd) { char buffer[INPUT_LEN]; int i; int length; /* Do a read on the socket. recv() returns the length of the recieved * string. */ length = recv(fd,buffer,INPUT_LEN,0); if (length < 0) { /* length was shorter than specified; read was incomplete */ perror("failed to receive message."); } else if (length == 0) { /* Connection was closed at remote end. Close socket and remove * from user list. */ /* UNSAFE CONCURRENT STUFF BEGINS */ pthread_mutex_lock(&user_list_lock); /* We don't care if they're not on the user list, seeing as * we're deleting them anyway. */ if ((i = lookup_socket(fd)) >= 0) { user_list[i].flags &= ~USER_CONNECTED;/*clear the bit*/ user_list[i].socket = 0; } printf("\n" USERNAME_PRINT_FMT " closed their connection.", user_list[i].name); fflush(stdout); if (close(fd) < 0) { perror("recieve message"); } pthread_mutex_unlock(&user_list_lock); /* UNSAFE CONCURRENT STUFF ENDS */ } else { /* Everything is good! Print out the recieved message and the * user that sent it. */ if (length < INPUT_LEN) { buffer[length] = '\0'; } if (buffer[length-1] == '\n') { buffer[length-1] = '\0'; } pthread_mutex_lock(&user_list_lock); if ((i = lookup_socket(fd)) < 0) { /* this should never happen, as how would we have an * open connection and socket from an unknown user? */ perror("message from unknown user"); } else { printf("\n" USERNAME_PRINT_FMT " says: " INPUT_PRINT_FMT, user_list[i].name, buffer); fflush(stdout); } pthread_mutex_unlock(&user_list_lock); } return; }
static int dump_one_packet_fd(int lfd, u32 id, const struct fd_parms *p) { PacketSockEntry psk = PACKET_SOCK_ENTRY__INIT; SkOptsEntry skopts = SK_OPTS_ENTRY__INIT; struct packet_sock_desc *sd; int i, ret; sd = (struct packet_sock_desc *)lookup_socket(p->stat.st_ino, PF_PACKET, 0); if (IS_ERR_OR_NULL(sd)) { pr_err("Can't find packet socket %"PRIu64"\n", p->stat.st_ino); return -1; } pr_info("Dumping packet socket fd %d id %#x\n", lfd, id); BUG_ON(sd->sd.already_dumped); sd->sd.already_dumped = 1; psk.id = sd->file_id = id; psk.type = sd->type; psk.flags = p->flags; psk.fown = (FownEntry *)&p->fown; psk.opts = &skopts; if (dump_socket_opts(lfd, &skopts)) return -1; psk.protocol = sd->proto; psk.ifindex = sd->nli.pdi_index; psk.version = sd->nli.pdi_version; psk.reserve = sd->nli.pdi_reserve; psk.timestamp = sd->nli.pdi_tstamp; psk.copy_thresh = sd->nli.pdi_copy_thresh; psk.aux_data = (sd->nli.pdi_flags & PDI_AUXDATA ? true : false); psk.orig_dev = (sd->nli.pdi_flags & PDI_ORIGDEV ? true : false); psk.vnet_hdr = (sd->nli.pdi_flags & PDI_VNETHDR ? true : false); psk.loss = (sd->nli.pdi_flags & PDI_LOSS ? true : false); ret = dump_mreqs(&psk, sd); if (ret) goto out; if (sd->fanout != NO_FANOUT) { psk.has_fanout = true; psk.fanout = sd->fanout; } ret = dump_rings(&psk, sd); if (ret) goto out; ret = pb_write_one(img_from_set(glob_imgset, CR_FD_PACKETSK), &psk, PB_PACKET_SOCK); out: release_skopts(&skopts); xfree(psk.rx_ring); xfree(psk.tx_ring); for (i = 0; i < psk.n_mclist; i++) xfree(psk.mclist[i]->addr.data); xfree(psk.mclist); return ret; }
int dump_socket_map(struct vma_area *vma) { struct packet_sock_desc *sd; sd = (struct packet_sock_desc *)lookup_socket(vma->vm_socket_id, PF_PACKET, 0); if (IS_ERR_OR_NULL(sd)) { pr_err("Can't find packet socket %u to mmap\n", vma->vm_socket_id); return -1; } if (!sd->file_id) { pr_err("Mmap-ed socket %u not open\n", vma->vm_socket_id); return -1; } pr_info("Dumping socket map %x -> %"PRIx64"\n", sd->file_id, vma->e->start); vma->e->shmid = sd->file_id; return 0; }
static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p) { struct netlink_sk_desc *sk; NetlinkSkEntry ne = NETLINK_SK_ENTRY__INIT; SkOptsEntry skopts = SK_OPTS_ENTRY__INIT; sk = (struct netlink_sk_desc *)lookup_socket(p->stat.st_ino, PF_NETLINK, 0); if (IS_ERR(sk)) goto err; ne.id = id; ne.ino = p->stat.st_ino; if (!can_dump_netlink_sk(lfd)) goto err; if (sk) { BUG_ON(sk->sd.already_dumped); ne.protocol = sk->protocol; ne.portid = sk->portid; ne.groups = sk->groups; ne.n_groups = sk->gsize / sizeof(ne.groups[0]); /* * On 64-bit sk->gsize is multiple to 8 bytes (sizeof(long)), * so remove the last 4 bytes if they are empty. */ if (ne.n_groups && sk->groups[ne.n_groups - 1] == 0) ne.n_groups -= 1; if (ne.n_groups > 1) { pr_err("%d %x\n", sk->gsize, sk->groups[1]); pr_err("The netlink socket 0x%x has more than 32 groups\n", ne.ino); return -1; } if (sk->groups && !sk->portid) { pr_err("The netlink socket 0x%x is bound to groups but not to portid\n", ne.ino); return -1; } ne.state = sk->state; ne.dst_portid = sk->dst_portid; ne.dst_group = sk->dst_group; } else { /* unconnected and unbound socket */ int val; socklen_t aux = sizeof(val); if (getsockopt(lfd, SOL_SOCKET, SO_PROTOCOL, &val, &aux) < 0) { pr_perror("Unable to get protocol for netlink socket"); goto err; } ne.protocol = val; } ne.fown = (FownEntry *)&p->fown; ne.opts = &skopts; if (dump_socket_opts(lfd, &skopts)) goto err; if (pb_write_one(img_from_set(glob_imgset, CR_FD_NETLINK_SK), &ne, PB_NETLINK_SK)) goto err; return 0; err: return -1; }
static int dump_one_netlink_fd(int lfd, u32 id, const struct fd_parms *p) { struct netlink_sk_desc *sk; FileEntry fe = FILE_ENTRY__INIT; NetlinkSkEntry ne = NETLINK_SK_ENTRY__INIT; SkOptsEntry skopts = SK_OPTS_ENTRY__INIT; sk = (struct netlink_sk_desc *)lookup_socket(p->stat.st_ino, PF_NETLINK, 0); if (IS_ERR(sk)) goto err; ne.id = id; ne.ino = p->stat.st_ino; if (!can_dump_netlink_sk(lfd)) goto err; if (sk) { BUG_ON(sk->sd.already_dumped); ne.protocol = sk->protocol; ne.portid = sk->portid; ne.groups = sk->groups; ne.n_groups = sk->gsize / sizeof(ne.groups[0]); /* * On 64-bit sk->gsize is multiple to 8 bytes (sizeof(long)), * so remove the last 4 bytes if they are empty. */ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ /* * Big endian swap: Ugly hack for zdtm/static/sk-netlink * * For big endian systems: * * - sk->groups[0] are bits 32-64 * - sk->groups[1] are bits 0-32 */ if (ne.n_groups == 2) { uint32_t tmp = sk->groups[1]; sk->groups[1] = sk->groups[0]; sk->groups[0] = tmp; } #endif if (ne.n_groups && sk->groups[ne.n_groups - 1] == 0) ne.n_groups -= 1; if (ne.n_groups > 1) { pr_err("%d %x\n", sk->gsize, sk->groups[1]); pr_err("The netlink socket 0x%x has more than 32 groups\n", ne.ino); return -1; } if (sk->groups && !sk->portid) { pr_err("The netlink socket 0x%x is bound to groups but not to portid\n", ne.ino); return -1; } ne.state = sk->state; ne.dst_portid = sk->dst_portid; ne.dst_group = sk->dst_group; } else { /* unconnected and unbound socket */ int val; socklen_t aux = sizeof(val); if (getsockopt(lfd, SOL_SOCKET, SO_PROTOCOL, &val, &aux) < 0) { pr_perror("Unable to get protocol for netlink socket"); goto err; } ne.protocol = val; } ne.fown = (FownEntry *)&p->fown; ne.opts = &skopts; if (dump_socket_opts(lfd, &skopts)) goto err; fe.type = FD_TYPES__NETLINKSK; fe.id = ne.id; fe.nlsk = ≠ if (pb_write_one(img_from_set(glob_imgset, CR_FD_FILES), &fe, PB_FILE)) goto err; return 0; err: return -1; }