void rpcap_read_payload(int sock, short which, r_dev_t *dev) { int ioret; ioret = read_iov(&dev->data, sock); if (ioret < 0) { free_rdev(dev); return; } if (ioret > 0) { event_set(&dev->event, sock, EV_READ, (void *)rpcap_read_payload, dev); event_add(&dev->event, 0); } if(write(dev->tunfd, dev->data.buf, dev->data.offset) <= 0) { LOG("Error in tuntap write: %s\n", strerror(errno)); exit(1); } reset_iov(&dev->data); event_set(&dev->event, sock, EV_READ, (void *)rpcap_read_len, dev); event_add(&dev->event, 0); }
void free_rdev(r_dev_t *dev) { reset_iov(&dev->data); close(dev->sock); free(dev->serv); free(dev->iface); free(dev); }
void client_read_hdr_data(int sock, short which, client_conn_t * conn) { int ioret; if (!conn->data.buf) initialize_iov(&conn->data, conn->start_header.dev_sz + conn->start_header.bpf_sz); ioret = read_iov(&conn->data, sock); if (ioret < 0) { LOG("sockerr %s\n", strerror(errno)); free_client_conn(conn); return; } if (ioret > 0) { event_set(&conn->event, sock, EV_READ, (void *) client_read_hdr_data, conn); event_add(&conn->event, 0); return; } if (conn->start_header.dev_sz) conn->start_header.dev = calloc(conn->start_header.dev_sz + 1, 1); if (conn->start_header.dev_sz && !conn->start_header.dev) { LOG("alloc err %s\n", strerror(errno)); exit(1); } if (conn->start_header.bpf_sz) conn->start_header.bpf = calloc(conn->start_header.bpf_sz + 1, 1); if (conn->start_header.bpf_sz && !conn->start_header.bpf) { LOG("alloc err %s\n", strerror(errno)); exit(1); } if (conn->start_header.dev_sz) memcpy(conn->start_header.dev, conn->data.buf, conn->start_header.dev_sz); if (conn->start_header.bpf_sz) memcpy(conn->start_header.bpf, &conn->data.buf[conn->start_header.dev_sz], conn->start_header.bpf_sz); LOG("BPF %s\n", conn->start_header.bpf); LOG("DEV %s\n", conn->start_header.dev); reset_iov(&conn->data); pcap_event_init(conn); return; }
wpdu::wpdu(const iovec& iov): valid_flag_(0),comm_len(MAX_COMM_STR_LEN) { community_name[0] = 0; reset_iov(iovec_); version_ = version1; // TODO: figure where this should come from ACE_NEW(iovec_.iov_base, char[iov.iov_len]); if (!iovec_.iov_base) { valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; return; } copy_iovec(iovec_, iov); valid_flag_ = SNMP_CLASS_SUCCESS; }
void free_client_conn(client_conn_t * conn) { reset_iov(&conn->data); event_del(&conn->event); event_del(&conn->pcap_event); close(conn->sock); close(conn->pcap_fd); if (conn->start_header.dev) free(conn->start_header.dev); if (conn->start_header.bpf) free(conn->start_header.bpf); if (conn->descr) pcap_close(conn->descr); free(conn); }
void pcap_write(int sock, short which, client_conn_t * conn) { int ioret; ioret = write_iov(&conn->data, conn->sock); if (ioret < 0) { free_client_conn(conn); return; } if (ioret > 0) { event_set(&conn->event, sock, EV_WRITE, (void *) pcap_write, (void *) conn); event_add(&conn->event, 0); return; } reset_iov(&conn->data); return; }
void rpcap_read_len(int sock, short which, r_dev_t *dev) { int ioret; int toread; if (!dev->data.buf) initialize_iov(&dev->data, sizeof(uint32_t)); ioret = read_iov(&dev->data, sock); if (ioret < 0) { LOG("Lost connection to %s (%s)\n", dev->serv, strerror(errno)); free_rdev(dev); return; } if (ioret > 0) { event_set(&dev->event, sock, EV_READ, (void *)rpcap_read_len, dev); event_add(&dev->event, 0); } memcpy(&toread, dev->data.buf, sizeof(uint32_t)); reset_iov(&dev->data); initialize_iov(&dev->data, toread); event_set(&dev->event, sock, EV_READ, (void *)rpcap_read_payload, dev); event_add(&dev->event, 0); }
wpdu::wpdu(const Pdu& pdu, const UdpTarget& target): valid_flag_(SNMP_CLASS_INVALID ), comm_len(MAX_COMM_STR_LEN) { reset_iov(iovec_); version_ = target.get_version(); int status; OctetStr comm_str; community_name[0] = 0; snmp_pdu *raw_pdu; // create a raw pdu raw_pdu = cmu_snmp::pdu_create( (int) pdu.get_type()); if (!raw_pdu) { valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; return; } raw_pdu->reqid = pdu.get_request_id(); raw_pdu->errstat= (unsigned long) pdu.get_error_status(); raw_pdu->errindex= (unsigned long) pdu.get_error_index(); switch (raw_pdu->command) { case sNMP_PDU_GET: case sNMP_PDU_GETNEXT: target.get_read_community(comm_str); break; case sNMP_PDU_SET: target.get_write_community(comm_str); break; case sNMP_PDU_V1TRAP: target.get_read_community(comm_str); if (set_trap_info(raw_pdu, pdu)) // will free raw_pdu return; break; case sNMP_PDU_RESPONSE: break; default: ACE_ASSERT(0); return; } if (load_vbs(raw_pdu, pdu)) { cmu_snmp::free_pdu( raw_pdu); valid_flag_ = SNMP_CLASS_RESOURCE_UNAVAIL; return; } // TODO: determine how big raw_pdu serializes out to iovec_.iov_len = target.get_max_pdu_size(); ACE_NEW(iovec_.iov_base, char [iovec_.iov_len]); // create raw byte stream // The intermediate integer is to avoid type-punned pointer // dereferencing. int out_length = iovec_.iov_len; status = cmu_snmp::build( raw_pdu, (unsigned char *)iovec_.iov_base, &out_length, target.get_version(), comm_str.data(), comm_str.length()); iovec_.iov_len = out_length; if ( status != 0) { valid_flag_ = SNMP_ERROR_WRONG_ENCODING; cmu_snmp::free_pdu( raw_pdu); return; } cmu_snmp::free_pdu( raw_pdu); valid_flag_ = SNMP_CLASS_SUCCESS; }
wpdu::wpdu(): valid_flag_(0), comm_len(MAX_COMM_STR_LEN) { community_name[0] = 0; reset_iov(iovec_); version_ = version1; // TODO: figure where this should come from }
void rpcap_handshake(int sock, short which, r_dev_t *dev) { int ioret; if (!dev->data.buf) { int iface_len; int bpfstr_len; int flags = 0; bpfstr_len = dev->bpf?strlen(dev->bpf):0; iface_len = strlen(dev->iface); initialize_iov(&dev->data, sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint8_t) + iface_len + bpfstr_len); memcpy(&dev->data.buf[0], &iface_len, sizeof(uint8_t)); memcpy(&dev->data.buf[1], &bpfstr_len, sizeof(uint32_t)); memcpy(&dev->data.buf[5], &dev->snaplen, sizeof(uint16_t)); memcpy(&dev->data.buf[7], &flags, sizeof(uint8_t)); memcpy(&dev->data.buf[8], dev->iface, iface_len); if (dev->bpf) memcpy(&dev->data.buf[8+iface_len], dev->bpf, bpfstr_len); /* if(bpfstr) memcpy(&dev->data.buf[8+iface_len], bpfstr, bpfstr_len); */ } ioret = write_iov(&dev->data, dev->sock); if (ioret < 0) { LOG("Lost connection to %s (%s)\n", dev->serv, strerror(errno)); free_rdev(dev); return; } if (ioret > 0) { event_set(&dev->event, dev->sock, EV_WRITE, (void *)rpcap_handshake, (void *)dev); event_add(&dev->event, 0); return; } reset_iov(&dev->data); event_set(&dev->event, dev->sock, EV_READ, (void *)rpcap_read_len, (void *)dev); event_add(&dev->event, 0); }
void client_read_hdr(int sock, short which, client_conn_t * conn) { int ioret; if (!conn->data.buf) initialize_iov(&conn->data, /* * device str len */ sizeof(uint8_t) + /* * bpf string len */ sizeof(uint32_t) + /* * pcap snaplen */ sizeof(uint16_t) + /* * opts */ sizeof(uint8_t)); ioret = read_iov(&conn->data, sock); if (ioret < 0) { /* * sockerr */ LOG("sockerr %s\n", strerror(errno)); free_client_conn(conn); close(sock); return; } if (ioret > 0) { /* * continue reading header */ event_set(&conn->event, sock, EV_READ, (void *) client_read_hdr, conn); event_add(&conn->event, 0); return; } memcpy(&conn->start_header.dev_sz, &conn->data.buf[0], sizeof(uint8_t)); memcpy(&conn->start_header.bpf_sz, &conn->data.buf[1], sizeof(uint32_t)); memcpy(&conn->start_header.snaplen, &conn->data.buf[5], sizeof(uint16_t)); memcpy(&conn->start_header.opts, &conn->data.buf[7], sizeof(uint8_t)); if (conn->start_header.dev_sz > MAX_DEV_LEN) { free_client_conn(conn); return; } if (conn->start_header.bpf_sz > MAX_BPF_LEN) { free_client_conn(conn); return; } LOG("total = %d\n", conn->start_header.dev_sz + conn->start_header.bpf_sz); LOG("dev_sz = %d\n", conn->start_header.dev_sz); LOG("bpf_sz = %d\n", conn->start_header.bpf_sz); LOG("snaplen = %d\n", conn->start_header.snaplen); LOG("opts = %d\n", conn->start_header.opts); event_set(&conn->event, sock, EV_READ, (void *) client_read_hdr_data, conn); event_add(&conn->event, 0); reset_iov(&conn->data); return; }