/* Reads a packet at an offset. */ static gboolean observer_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info) { union wtap_pseudo_header *pseudo_header = &phdr->pseudo_header; packet_entry_header packet_header; int offset; int data_bytes_consumed; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; /* process the packet header, including TLVs */ offset = read_packet_header(wth, wth->random_fh, pseudo_header, &packet_header, err, err_info); if (offset <= 0) return FALSE; /* EOF or error */ if (!process_packet_header(wth, &packet_header, phdr, err, err_info)) return FALSE; /* read the frame data */ data_bytes_consumed = read_packet_data(wth->random_fh, packet_header.offset_to_frame, offset, buf, phdr->caplen, err, err_info); if (data_bytes_consumed < 0) { return FALSE; } return TRUE; }
/* Reads a packet at an offset. */ static gboolean observer_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header, guint8 *pd, int length, int *err, gchar **err_info) { packet_entry_header packet_header; int offset; if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; /* process the packet header, including TLVs */ offset = read_packet_header(wth->random_fh, pseudo_header, &packet_header, err, err_info); if (offset <= 0) return FALSE; /* EOF or error */ /* update the pseudo header */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* There is no FCS in the frame */ pseudo_header->eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: /* Updated in read_packet_header */ break; } /* read the frame data */ if (!read_packet_data(wth->random_fh, packet_header.offset_to_frame, offset, pd, length, err, err_info)) return FALSE; return TRUE; }
/* Reads the next packet. */ static gboolean observer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int header_bytes_consumed; int data_bytes_consumed; packet_entry_header packet_header; /* skip records other than data records */ for (;;) { *data_offset = file_tell(wth->fh); /* process the packet header, including TLVs */ header_bytes_consumed = read_packet_header(wth, wth->fh, &wth->phdr.pseudo_header, &packet_header, err, err_info); if (header_bytes_consumed <= 0) return FALSE; /* EOF or error */ if (packet_header.packet_type == PACKET_TYPE_DATA_PACKET) break; /* skip to next packet */ if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet, header_bytes_consumed, err, err_info)) { return FALSE; /* EOF or error */ } } if (!process_packet_header(wth, &packet_header, &wth->phdr, err, err_info)) return FALSE; /* read the frame data */ data_bytes_consumed = read_packet_data(wth->fh, packet_header.offset_to_frame, header_bytes_consumed, wth->frame_buffer, wth->phdr.caplen, err, err_info); if (data_bytes_consumed < 0) { return FALSE; } /* skip over any extra bytes following the frame data */ if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet, header_bytes_consumed + data_bytes_consumed, err, err_info)) { return FALSE; } return TRUE; }
static ssize_t read_rbu_data(struct kobject *kobj, char *buffer, loff_t pos, size_t count) { ssize_t ret_count = 0; spin_lock(&rbu_data.lock); if (!strcmp(image_type, "mono")) ret_count = read_rbu_mono_data(buffer, pos, count); else if (!strcmp(image_type, "packet")) ret_count = read_packet_data(buffer, pos, count); else pr_debug("read_rbu_data: invalid image type specified\n"); spin_unlock(&rbu_data.lock); return ret_count; }
/* process login reply packet which includes redirected new server address */ static gint _qq_process_login_redirect(PurpleConnection *gc, guint8 *data, gint len) { gint bytes, ret; guint8 *cursor; gchar *new_server_str; qq_data *qd; qq_login_reply_redirect_packet lrrp; qd = (qq_data *) gc->proto_data; cursor = data; bytes = 0; /* 000-000: reply code */ bytes += read_packet_b(data, &cursor, len, &lrrp.result); /* 001-004: login uid */ bytes += read_packet_dw(data, &cursor, len, &lrrp.uid); /* 005-008: redirected new server IP */ bytes += read_packet_data(data, &cursor, len, lrrp.new_server_ip, 4); /* 009-010: redirected new server port */ bytes += read_packet_w(data, &cursor, len, &lrrp.new_server_port); if (bytes != QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN) { purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Fail parsing login redirect packet, expect %d bytes, read %d bytes\n", QQ_LOGIN_REPLY_REDIRECT_PACKET_LEN, bytes); ret = QQ_LOGIN_REPLY_MISC_ERROR; } else { /* start new connection */ new_server_str = gen_ip_str(lrrp.new_server_ip); purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Redirected to new server: %s:%d\n", new_server_str, lrrp.new_server_port); qq_connect(gc->account, new_server_str, lrrp.new_server_port, qd->use_tcp, TRUE); g_free(new_server_str); ret = QQ_LOGIN_REPLY_REDIRECT; } return ret; }
/* Reads the next packet. */ static gboolean observer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int header_bytes_consumed; int data_bytes_consumed; packet_entry_header packet_header; /* skip records other than data records */ for (;;) { *data_offset = file_tell(wth->fh); /* process the packet header, including TLVs */ header_bytes_consumed = read_packet_header(wth->fh, &wth->phdr.pseudo_header, &packet_header, err, err_info); if (header_bytes_consumed <= 0) return FALSE; /* EOF or error */ if (packet_header.packet_type == PACKET_TYPE_DATA_PACKET) break; /* skip to next packet */ if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet, header_bytes_consumed, err, err_info)) { return FALSE; /* EOF or error */ } } /* neglect frame markers for wiretap */ if (packet_header.network_size < 4) { *err = WTAP_ERR_BAD_FILE; *err_info = g_strdup_printf("Observer: bad record: Packet length %u < 4", packet_header.network_size); return FALSE; } /* set the wiretap packet header fields */ wth->phdr.presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN; wth->phdr.pkt_encap = observer_to_wtap_encap(packet_header.network_type); if(wth->file_encap == WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS) { wth->phdr.len = packet_header.network_size; wth->phdr.caplen = packet_header.captured_size; } else { wth->phdr.len = packet_header.network_size - 4; wth->phdr.caplen = MIN(packet_header.captured_size, wth->phdr.len); } /* set the wiretap timestamp, assuming for the moment that Observer encoded it in GMT */ wth->phdr.ts.secs = (time_t) ((packet_header.nano_seconds_since_2000 / 1000000000) + ansi_to_observer_epoch_offset); wth->phdr.ts.nsecs = (int) (packet_header.nano_seconds_since_2000 % 1000000000); /* adjust to local time, if necessary, also accounting for DST if the frame was captured while it was in effect */ if (((observer_dump_private_state*)wth->priv)->time_format == TIME_INFO_LOCAL) { struct tm daylight_tm; struct tm standard_tm; time_t dst_offset; /* the Observer timestamp was encoded as local time, so add a correction from local time to GMT */ wth->phdr.ts.secs += gmt_to_localtime_offset; /* perform a DST adjustment if necessary */ standard_tm = *localtime(&wth->phdr.ts.secs); if (standard_tm.tm_isdst > 0) { daylight_tm = standard_tm; standard_tm.tm_isdst = 0; dst_offset = mktime(&standard_tm) - mktime(&daylight_tm); wth->phdr.ts.secs -= dst_offset; } } /* update the pseudo header */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* There is no FCS in the frame */ wth->phdr.pseudo_header.eth.fcs_len = 0; break; case WTAP_ENCAP_IEEE_802_11_WITH_RADIO: /* Updated in read_packet_header */ break; } /* set-up the packet buffer */ buffer_assure_space(wth->frame_buffer, packet_header.captured_size); /* read the frame data */ data_bytes_consumed = read_packet_data(wth->fh, packet_header.offset_to_frame, header_bytes_consumed, buffer_start_ptr(wth->frame_buffer), packet_header.captured_size, err, err_info); if (data_bytes_consumed < 0) { return FALSE; } /* skip over any extra bytes following the frame data */ if (!skip_to_next_packet(wth, packet_header.offset_to_next_packet, header_bytes_consumed + data_bytes_consumed, err, err_info)) { return FALSE; } return TRUE; }
/* reads the next packet */ static gboolean observer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { int offset; packet_entry_header packet_header; /* * Skip records other than data records. */ for (;;) { *data_offset = wth->data_offset; /* process the packet header, including TLVs */ offset = read_packet_header(wth->fh, &packet_header, err, err_info); if (offset <= 0) return FALSE; /* EOF or error */ wth->data_offset += offset; if (packet_header.packet_type == PACKET_TYPE_DATA_PACKET) break; /* skip to next packet */ packet_header.offset_to_next_packet = GUINT16_FROM_LE(packet_header.offset_to_next_packet); if (!skip_to_next_packet(wth, offset, packet_header.offset_to_next_packet, err, err_info)) return FALSE; /* EOF or error */ } /* set-up the packet header */ packet_header.network_size = GUINT16_FROM_LE(packet_header.network_size); /* neglect frame markers for wiretap */ if (packet_header.network_size < 4) { *err = WTAP_ERR_BAD_RECORD; *err_info = g_strdup_printf("Observer: bad record: Packet length %u < 4", packet_header.network_size); return FALSE; } packet_header.network_size -= 4; packet_header.captured_size = GUINT16_FROM_LE(packet_header.captured_size); wth->phdr.pkt_encap = observer_encap[packet_header.network_type]; wth->phdr.len = packet_header.network_size; wth->phdr.caplen = MIN(packet_header.captured_size, wth->phdr.len); packet_header.nano_seconds_since_2000 = GUINT64_FROM_LE(packet_header.nano_seconds_since_2000); wth->phdr.ts.secs = (time_t) (packet_header.nano_seconds_since_2000/1000000000 + seconds1970to2000); wth->phdr.ts.nsecs = (int) (packet_header.nano_seconds_since_2000%1000000000); /* set-up the packet buffer */ buffer_assure_space(wth->frame_buffer, packet_header.captured_size); /* read data */ if (!read_packet_data(wth->fh, packet_header.offset_to_frame, offset, buffer_start_ptr(wth->frame_buffer), packet_header.captured_size, err, err_info)) return FALSE; wth->data_offset += packet_header.captured_size; offset += packet_header.captured_size; /* update the pseudo header */ switch (wth->file_encap) { case WTAP_ENCAP_ETHERNET: /* There is no FCS in the frame */ wth->pseudo_header.eth.fcs_len = 0; break; } return TRUE; }
/* process login reply which says OK */ static gint _qq_process_login_ok(PurpleConnection *gc, guint8 *data, gint len) { gint bytes; guint8 *cursor; qq_data *qd; qq_login_reply_ok_packet lrop; qd = (qq_data *) gc->proto_data; cursor = data; bytes = 0; /* 000-000: reply code */ bytes += read_packet_b(data, &cursor, len, &lrop.result); /* 001-016: session key */ lrop.session_key = g_memdup(cursor, QQ_KEY_LENGTH); cursor += QQ_KEY_LENGTH; bytes += QQ_KEY_LENGTH; purple_debug(PURPLE_DEBUG_INFO, "QQ", "Get session_key done\n"); /* 017-020: login uid */ bytes += read_packet_dw(data, &cursor, len, &lrop.uid); /* 021-024: server detected user public IP */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.client_ip, 4); /* 025-026: server detected user port */ bytes += read_packet_w(data, &cursor, len, &lrop.client_port); /* 027-030: server detected itself ip 127.0.0.1 ? */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.server_ip, 4); /* 031-032: server listening port */ bytes += read_packet_w(data, &cursor, len, &lrop.server_port); /* 033-036: login time for current session */ bytes += read_packet_time(data, &cursor, len, &lrop.login_time); /* 037-062: 26 bytes, unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown1, 26); /* 063-066: unknown server1 ip address */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown_server1_ip, 4); /* 067-068: unknown server1 port */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown_server1_port); /* 069-072: unknown server2 ip address */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown_server2_ip, 4); /* 073-074: unknown server2 port */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown_server2_port); /* 075-076: 2 bytes unknown */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown2); /* 077-078: 2 bytes unknown */ bytes += read_packet_w(data, &cursor, len, &lrop.unknown3); /* 079-110: 32 bytes unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown4, 32); /* 111-122: 12 bytes unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown5, 12); /* 123-126: login IP of last session */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.last_client_ip, 4); /* 127-130: login time of last session */ bytes += read_packet_time(data, &cursor, len, &lrop.last_login_time); /* 131-138: 8 bytes unknown */ bytes += read_packet_data(data, &cursor, len, (guint8 *) &lrop.unknown6, 8); if (bytes != QQ_LOGIN_REPLY_OK_PACKET_LEN) { /* fail parsing login info */ purple_debug(PURPLE_DEBUG_WARNING, "QQ", "Fail parsing login info, expect %d bytes, read %d bytes\n", QQ_LOGIN_REPLY_OK_PACKET_LEN, bytes); } /* but we still go on as login OK */ qd->session_key = lrop.session_key; qd->session_md5 = _gen_session_md5(qd->uid, qd->session_key); qd->my_ip = gen_ip_str(lrop.client_ip); qd->my_port = lrop.client_port; qd->login_time = lrop.login_time; qd->last_login_time = lrop.last_login_time; qd->last_login_ip = gen_ip_str(lrop.last_client_ip); purple_connection_set_state(gc, PURPLE_CONNECTED); qd->logged_in = TRUE; /* must be defined after sev_finish_login */ /* now initiate QQ Qun, do it first as it may take longer to finish */ qq_group_init(gc); /* Now goes on updating my icon/nickname, not showing info_window */ qd->modifying_face = FALSE; qq_send_packet_get_info(gc, qd->uid, FALSE); /* grab my level */ qq_send_packet_get_level(gc, qd->uid); qq_send_packet_change_status(gc); /* refresh buddies */ qq_send_packet_get_buddies_list(gc, QQ_FRIENDS_LIST_POSITION_START); /* refresh groups */ qq_send_packet_get_all_list_with_group(gc, QQ_FRIENDS_LIST_POSITION_START); return QQ_LOGIN_REPLY_OK; }