void Packet::print() { uint32_t tsval, tsecr; char sip_str[INET_ADDRSTRLEN]; char dip_str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ip_hdr->ip_src.s_addr, sip_str, INET_ADDRSTRLEN); inet_ntop(AF_INET, &ip_hdr->ip_dst.s_addr, dip_str, INET_ADDRSTRLEN); get_tcp_ts(&tsval,&tsecr); switch(get_ip_protocol()) { case IPPROTO_TCP: std::cout << "TCP packet: " << "[" << get_ts().tv_sec << "." << std::setw(9) << std::setfill('0') << get_ts().tv_nsec << "] [" << sip_str << ":" << get_tcp_sport() << "->" << dip_str << ":" << get_tcp_dport() << "] " << "[S:" << get_tcp_seq() << "] " << "[A:" << get_tcp_ack() << "] " << "[L:" << get_tcp_payload_len() << "] " << "[M:" << get_tcp_mss() << "] " << "[TV:" << tsval << "] " << "[TE:" << tsecr << "]" << std::endl << std::flush; break; case IPPROTO_ICMP: std::cout << "ICMP packet: [" << sip_str << "->" << dip_str << "] " << "[TTL:" << get_ip_ttl() << "]" << std::endl << std::flush; break; default: std::cout << "Unknown packet!" << std::endl << std::flush; break; } }
int main(int argc, char **argv) { if (argc != 2) { printf("usage: trans_pack file\n"); exit(-1); } FILE *fp = NULL; size_t ret = 0, leftlen = 0, cnt = 0, bodylen = 0; uint8_t buf[65536], *u8p = NULL; fp = open_file(argv[1]); ret = read_pcap_hdr(fp, buf); print_pcap_hdr(buf); //Read Packet while ((ret = read_pkt_hdr(fp, buf)) > 0) { leftlen = bodylen = ret; cnt++; printf("--------------------------\n"); //if (cnt++ == 5) break; ret = read_pkt_body(fp, buf, leftlen); /// 不是IP的话直接跳过 if (get_ether_type(buf) != ETHER_TYPE_IP) { //printf("It is Not IP\n"); continue; } /// 跳过Ethernet u8p = buf + sizeof(struct ether_header); leftlen = ret - sizeof(struct ether_header); if (get_ip_protocol(u8p) != IP_PROT_UDP) { // 不是UDP直接跳过 //printf("It's not UDP\n"); continue; } /// 跳过IP和UDP u8p = u8p + sizeof(struct udphdr) + sizeof(struct iphdr); leftlen = leftlen - sizeof(struct udphdr) - sizeof(struct iphdr); /// 找到NS_UNIDATA数据包 if (get_ns_type(u8p, leftlen) != NS_UNIDATA) { // 不是NS_UNIDATA数据包直接跳过 //printf("Not NS-UNIDATA: %x\n", get_ns_type(u8p, leftlen)); continue; } /// 跳过NS u8p = u8p + sizeof(struct ns); leftlen = leftlen - sizeof(struct ns); uint8_t sdu_type = get_sdu_type(u8p, leftlen); if (sdu_type != DL_UNIDATA && sdu_type != UL_UNIDATA) { // 不是DL/UL格式,直接跳过 // printf("Not DL/UL: %x\n", sdu_type); continue; } /// 不需要跳过SDU,直接处理ul/dl unidata if (sdu_type == DL_UNIDATA) { struct dl_unidata *dlp = (struct dl_unidata *)u8p; printf("dl type: %x\n", dlp->type); printf("dl tlli: %x %x %x %x\n", dlp->ctlli[0], dlp->ctlli[1], dlp->ctlli[2], dlp->ctlli[3]); // printf("dl liftime[0]: %x\n", dlp->lifetime[0]); //printf("dl mrac[0]: %x\n", dlp->mrac[0]); //printf("dl drx[0]: %x\n", dlp->drx[0]); //printf("dl ismi[0]: %x\n", dlp->imsi[0]); //printf("sizeof dl: %u\n", sizeof(struct dl_unidata)); // 跳过dl_unidata固定头 u8p += sizeof(struct dl_unidata); leftlen -= sizeof(struct dl_unidata); // 循环处理可变头 uint8_t tmptype = 0; uint8_t tmplen = 0; while (*u8p != LLC_PDU) { tmptype = *u8p++; // 在这里将需要的字段提取出来 tmplen = *u8p & 0x7f; // 跳过tmplen长度 u8p = u8p + tmplen + 1; leftlen = leftlen - tmplen - 1; } } else { struct ul_unidata * ulp = (struct ul_unidata *)u8p; printf("ul type: %x\n", ulp->type); printf("ul tlli: %x %x %x %x\n", ulp->tlli[0], ulp->tlli[1], ulp->tlli[2], ulp->tlli[3]); /// 跳过固定UL_UNIDATA u8p = u8p + sizeof(struct ul_unidata); leftlen = leftlen - sizeof(struct ul_unidata); uint8_t tmptype = 0; uint8_t tmplen = 0; while (*u8p != LLC_PDU) { tmptype = *u8p++; tmplen = *u8p & 0x7f; // 跳过tmplen长度 u8p = u8p + tmplen + 1; leftlen = leftlen - tmplen - 1; } } // 跳过LLC头,考虑变长 u8p += 1; // 跳过ELEMENT ID leftlen -= 1; printf("llc pdu len %x\n", *u8p); if ((*u8p & 0x80) == 0) { u8p += 1; leftlen -= 1; } // 实际LLC PDU的长度 uint8_t llcpdu_len = *u8p; // 跳过LLC 长度字段 u8p += 1; leftlen -= 1; if (get_llc_sapi(u8p) != LLGMM) { printf("Not LLGMM\n"); continue; } /// 跳过LLC SAPI u8p += 1; leftlen -= 1; // 过滤非 Unconfirmed UI数据包 if ((*u8p & 0xe0) != 0xc0) { continue; } u8p += 2; leftlen -= 2; struct gmm *gmmp = (struct gmm*)u8p; printf("-------[%d] len:%u\n", cnt, bodylen); u8p = u8p + sizeof(struct gmm); leftlen = leftlen - sizeof(struct gmm); switch (gmmp->type) { case ATTACH_REQUEST: { printf("It's attach request.\n"); if (*(u8p+6)==0x05) { struct attach_request_t *p_attach_req=(struct attach_request_t*)u8p; printf("tmsi:%x%x%x%x\n",p_attach_req->tmsi[2],p_attach_req->tmsi[3],p_attach_req->tmsi[4],p_attach_req->tmsi[5]); } else if (*(u8p+6)==0x08) { struct attach_request_i *p_attach_req=(struct attach_request_i*)u8p; printf("imsi:%x%x%x%x%x%x%x%x\n",p_attach_req->imsi[1],p_attach_req->imsi[2],p_attach_req->imsi[3],p_attach_req->imsi[4],p_attach_req->imsi[5],p_attach_req->imsi[6],p_attach_req->imsi[7],p_attach_req->imsi[8]); } //printf("imsi:%x%x%x%x%x%x%x%x\n",ntohs(p_attach_req->imsi[1]),ntohs(p_attach_req->imsi[2]),ntohs(p_attach_req->imsi[3]),ntohs(p_attach_req->imsi[4]),ntohs(p_attach_req->imsi[5]),ntohs(p_attach_req->imsi[6]),ntohs(p_attach_req->imsi[7]),ntohs(p_attach_req->imsi[8])); } break; case ATTACH_ACCEPT: { printf("It's attach accept.\n"); struct attach_accept *p_attach_apt=(struct attach_accept*)u8p; printf("p-tmsi:%x%x%x%x\n",p_attach_apt->p_tmsi[3],p_attach_apt->p_tmsi[4],p_attach_apt->p_tmsi[5],p_attach_apt->p_tmsi[6]); } break; case ATTACH_COMPLETE: { printf("It's attach complete.\n"); } break; case ATTACH_REJECT: { printf("It's attach reject.\n"); struct attach_reject *p_attach_rej=(struct attach_reject*)u8p; printf("%x\n",p_attach_rej->cause); } break; case DETACH_REQUEST: { printf("It's detach request.\n"); printf("sizeof u8p is %d\n", llcpdu_len-8); if (llcpdu_len-8>1) { struct detach_request *p_detach_req=(struct detach_request*)u8p; printf("p_tmsi:%x%x%x%x\n.",p_detach_req->p_tmsi[3],p_detach_req->p_tmsi[4],p_detach_req->p_tmsi[5],p_detach_req->p_tmsi[6]); } else { printf("It's a short one.\n"); } } break; case DETACH_ACCEPT: { printf("It's detach accept.\n"); } break; case ROUTE_UPDATE_REQUEST: { printf("It's RA update request.\n"); struct ra_request *p_ra_req=(struct ra_request*)u8p; printf("%x\n",((p_ra_req->type)&0x07)); //printf("%x\n",(p_ra_req->type)&0x07); } break; case ROUTE_UPDATE_ACCEPT: { struct ra_accept *p_ra_apt=(struct ra_accept*)u8p; printf("It's RA update accept.\n"); printf("p-tmsi:%x%x%x%x\n",p_ra_apt->p_tmsi[3],p_ra_apt->p_tmsi[4],p_ra_apt->p_tmsi[5],p_ra_apt->p_tmsi[6]); } break; case ROUTE_UPDATE_COMPLETE: { printf("It's RA update complete.\n"); } break; case ROUTE_UPDATE_REJECT: { printf("It's RA update reject.\n"); struct ra_reject *p_ra_rej=(struct ra_reject*)u8p; printf("cause:%x\n",p_ra_rej->cause); } break; case ACTIVE_PDP_REQUEST: { printf("It's pdp request\n"); struct pdp_request *p_pdp_req=(struct pdp_request*)u8p; u8p=u8p+sizeof(struct pdp_request); uint8_t addr_len=*u8p; printf("addr len is:%x\n",addr_len); u8p=u8p+addr_len+1; if (llcpdu_len-14-addr_len>0) if (*u8p==0x28) { uint8_t apn_len=*(++u8p); u8p++; //uint8_t apn[apn_len]=++u8p; printf("apn:"); int i=0; for (;i<apn_len;i++) { printf("%x",*(u8p+i)); } printf("\n"); } } break; case ACTIVE_PDP_ACCEPT: { printf("It's pdp accept\n"); } break; case ACTIVE_PDP_REJECT: { printf("It's pdp reject\n"); struct pdp_reject *p_pdp_rej=(struct pdp_reject*)u8p; } break; case DEACTIVE_PDP_REQUEST: { printf("It's deactivate pdp request.\n"); struct pdp_deact_request *p_pdp_d_req=(struct pdp_deact_request*)u8p; printf("cause:%x\n",p_pdp_d_req->cause); } break; case DEACTIVE_PDP_ACCEPT: { printf("It's deactivate pdp accept.\n"); } break; default: printf("type is: 0x%x\n", gmmp->type); break; } // test hash key uint8_t keybuf1[20], keybuf2[20]; gen_hash_key(buf, bodylen, keybuf1, keybuf2, 20); printf("Hash key: %s %s\n", keybuf1, keybuf2); } return 0; }