📄 packetstore.cc
字号:
/* * PXE daemon - enable the remote booting of PXE enabled machines. * Copyright (C) 2000 Tim Hurman (kano@kano.org.uk) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *//****************************************************************************** * packetstore.cc - decode and store a packet in memory * ******************************************************************************/#include "packetstore.h"/* some global variables */const char *DHCP_types[DHCP_MAX_TYPES] = { "INVALID", "DHCPDISCOVER", "DHCPOFFER", "DHCPREQUEST", "DHCPDECLINE", "DHCPACK", "DHCPNACK", "DHCPRELEASE", "DHCPINFORM"};/****************************************************************************** * PacketStore - null packet constructor * ******************************************************************************/PacketStore::PacketStore(LogFile *_logger){ this->logger = _logger; head = head43 = NULL; Initalise();}/****************************************************************************** * PacketStore - full packet analyse * ******************************************************************************/PacketStore::PacketStore(LogFile *_logger, struct sockaddr_in *_address, uint8_t *bootp_pkt, int bootp_pkt_len){ this->logger = _logger; memcpy(&(this->address), _address, sizeof(this->address)); ReadPacket(bootp_pkt, bootp_pkt_len);}/****************************************************************************** * ~PacketStore - descructor * ******************************************************************************/PacketStore::~PacketStore(){ Initalise();}/****************************************************************************** * Initalise - init/blank a packet * ******************************************************************************/voidPacketStore::Initalise(void){ option *optptr, *optnext; // basic stuff op=htype=hlen=hops=0; secs=0; xid=0; memset(chaddr, 0, 16); sname[0] = file[0] = 0; magic_cookie = 0; memset(&ciaddr, 0, sizeof(ciaddr)); memset(&yiaddr, 0, sizeof(yiaddr)); memset(&siaddr, 0, sizeof(siaddr)); memset(&giaddr, 0, sizeof(giaddr)); memset(&address, 0, sizeof(giaddr)); // options for(optptr=head; optptr != NULL; optptr=optnext) { optnext = optptr->next; delete[] optptr->data; delete optptr; } head = NULL; // options 43 for(optptr=head43; optptr != NULL; optptr=optnext) { optnext = optptr->next; delete[] optptr->data; delete optptr; } head43 = NULL;}/****************************************************************************** * ReadPacket - read a bootp packet * ******************************************************************************/intPacketStore::ReadPacket(uint8_t *bootp_pkt, int bootp_pkt_len){ if(bootp_pkt_len < 300) throw new SysException(0, "PacketStore::ReadPacket", "Invalid packet length"); op = bootp_pkt[0]; htype = bootp_pkt[1]; hlen = bootp_pkt[2]; hops = bootp_pkt[3]; // xid - store in network byte order xid = bootp_pkt[4]; xid <<= 8; xid |= bootp_pkt[5]; xid <<= 8; xid |= bootp_pkt[6]; xid <<= 8; xid |= bootp_pkt[7]; xid = htonl(xid); // no of secs secs = bootp_pkt[8]; secs <<= 8; secs |= bootp_pkt[9]; secs = htons(secs); // client IP addr (filled in by client) ciaddr.s_addr = bootp_pkt[12]; ciaddr.s_addr <<= 8; ciaddr.s_addr |= bootp_pkt[13]; ciaddr.s_addr <<= 8; ciaddr.s_addr |= bootp_pkt[14]; ciaddr.s_addr <<= 8; ciaddr.s_addr |= bootp_pkt[15]; ciaddr.s_addr = htonl(ciaddr.s_addr); // client IP addr (filled in by server) yiaddr.s_addr = bootp_pkt[16]; yiaddr.s_addr <<= 8; yiaddr.s_addr |= bootp_pkt[17]; yiaddr.s_addr <<= 8; yiaddr.s_addr |= bootp_pkt[18]; yiaddr.s_addr <<= 8; yiaddr.s_addr |= bootp_pkt[19]; yiaddr.s_addr = htonl(yiaddr.s_addr); // server IP address (filled in by server) siaddr.s_addr = bootp_pkt[20]; siaddr.s_addr <<= 8; siaddr.s_addr |= bootp_pkt[21]; siaddr.s_addr <<= 8; siaddr.s_addr |= bootp_pkt[22]; siaddr.s_addr <<= 8; siaddr.s_addr |= bootp_pkt[23]; siaddr.s_addr = htonl(siaddr.s_addr); // gateway IP address giaddr.s_addr = bootp_pkt[24]; giaddr.s_addr <<= 8; giaddr.s_addr |= bootp_pkt[25]; giaddr.s_addr <<= 8; giaddr.s_addr |= bootp_pkt[26]; giaddr.s_addr <<= 8; giaddr.s_addr |= bootp_pkt[27]; giaddr.s_addr = htonl(giaddr.s_addr); // client hardware address memcpy(chaddr, bootp_pkt+28, 16); // the servername if(bootp_pkt[107] != 0) throw new SysException(0, "PacketStore::ReadPacket", "Invalid servername"); strcpy(sname, (char*)bootp_pkt+44); // the file if(bootp_pkt[235] != 0) throw new SysException(0, "PacketStore::ReadPacket", "Invalid filename"); strcpy(file, (char*)bootp_pkt+108); // the magic cookie magic_cookie = bootp_pkt[236]; magic_cookie <<= 8; magic_cookie |= bootp_pkt[237]; magic_cookie <<= 8; magic_cookie |= bootp_pkt[238]; magic_cookie <<= 8; magic_cookie |= bootp_pkt[239]; magic_cookie = htonl(magic_cookie); if(bootp_pkt[236] == 0xff) return(0); // read the options head=head43=NULL; return(ReadOptions(bootp_pkt+240, bootp_pkt_len-240));}/****************************************************************************** * print the packet to stdout * ******************************************************************************/std::ostream&operator<< (std::ostream& os, PacketStore &pkt){ int i; option *optptr; // basic info os << "BOOTP type : " << (int)pkt.op << "\n"; os << "Hardware type : " << (int)pkt.htype << "\n"; os << "Hardware Length : " << (int)pkt.hlen << "\n"; os << "Hops : " << (int)pkt.hops << "\n"; os << "Transaction ID : 0x" << std::hex << ntohl(pkt.xid) << std::dec <<"\n"; os << "Seconds : " << ntohs(pkt.secs) << "\n"; os << "Client IP (From Client): " << inet_ntoa(pkt.ciaddr) << "\n"; os << "Client IP (From Server): " << inet_ntoa(pkt.yiaddr) << "\n"; os << "Server IP : " << inet_ntoa(pkt.siaddr) << "\n"; os << "Gateway IP : " << inet_ntoa(pkt.giaddr) << "\n"; os << "Client Hardware address: " ; // client hardware addr for(i=0; i<pkt.hlen; i++) os << std::hex << (int)pkt.chaddr[i] << std::dec << "."; os << "\n"; // string info os << "Server name : " << pkt.sname << "\n"; os << "Boot filename : " << pkt.file << "\n"; os << "Magic cookie : 0x" << std::hex << ntohl(pkt.magic_cookie) << std::dec << "\n"; if(pkt.head == NULL) return os; // print the options os << "Options :\n"; for(optptr = pkt.head; optptr != NULL; optptr = optptr->next) { os << "Option major:" << (int)optptr->major_no << " minor: " << (int)optptr->minor_no << ", Length: " << (int)optptr->len << ", Data: "; for(i=0; i<optptr->len; i++) if((optptr->data[i] >0x20) && (optptr->data[i] < 0x7f)) os << "[" << (int)optptr->data[i] << "," << std::hex << (int)optptr->data[i] << std::dec << "," << (char)optptr->data[i] << "] "; else os << "[" << (int)optptr->data[i] << "," << std::hex << (int)optptr->data[i] << std::dec << ", ] "; os << "\n"; } if(pkt.head43 == NULL) return os; // option 43 os << "Options (sub-packed) :\n"; for(optptr = pkt.head43; optptr != NULL; optptr = optptr->next) { os << "Option [43] " << (int)optptr->major_no << " minor: " << (int)optptr->minor_no << ", Length: " << (int)optptr->len << ", Data: "; for(i=0; i<optptr->len; i++) if((optptr->data[i] >0x20) && (optptr->data[i] < 0x7f)) os << "[" << (int)optptr->data[i] << "," << std::hex << (int)optptr->data[i] << std::dec << "," << (char)optptr->data[i] << "] "; else os << "[" << (int)optptr->data[i] << "," << std::hex << (int)optptr->data[i] << std::dec << ", ] "; os << "\n"; } return os;}/****************************************************************************** * ReadOptions - read all the options contained within a packet * ******************************************************************************/intPacketStore::ReadOptions(uint8_t *bootp_pkt, int bootp_pkt_len){ // everything will always be null here int pos; option *optptr = NULL; option *optprev = NULL; for(pos=0; pos < bootp_pkt_len; pos++) { if(bootp_pkt[pos] == 0) goto ReadOptions_next; // pad if(bootp_pkt[pos] == 255) break; // end options // lots of sub options if(bootp_pkt[pos] == 43) { ReadOptions43(bootp_pkt+pos+2, bootp_pkt[pos+1]); pos += bootp_pkt[pos+1]+1; goto ReadOptions_next; // next } // default optptr = new option; optptr->major_no = bootp_pkt[pos++]; optptr->minor_no = 0; optptr->len = bootp_pkt[pos++]; optptr->data = new uint8_t[optptr->len]; optptr->next = NULL; memcpy(optptr->data, bootp_pkt+pos, optptr->len); // increment pos, accounting to cyclic increment pos += (optptr->len-1); if(head != NULL) { optprev->next = optptr; // assign optprev = optprev->next; // advance } else optprev = head = optptr; ReadOptions_next: pos=pos; } return(0);}/****************************************************************************** * ReadOptions43 - read all the options contained within a packet * ******************************************************************************/intPacketStore::ReadOptions43(uint8_t *bootp_pkt, int bootp_pkt_len){ // everything will always be null here int pos; option *optptr=NULL; option *optprev=NULL; for(pos=0; pos < bootp_pkt_len; pos++) { if(bootp_pkt[pos] == 0) goto ReadOptions43_next; // pad if(bootp_pkt[pos] == 255) break; // end options // lots of sub options if(bootp_pkt[pos] == 43) { std::cerr << "Option 43 detected\n"; break; } // default optptr = new option; optptr->major_no = 43; optptr->minor_no = bootp_pkt[pos++]; optptr->len = bootp_pkt[pos++]; optptr->data = new uint8_t[optptr->len]; optptr->next = NULL; memcpy(optptr->data, bootp_pkt+pos, optptr->len); // increment pos, accounting to cyclic increment pos += (optptr->len-1); if(head43 != NULL) { optprev->next = optptr; // assign optprev = optprev->next; // advance } else optprev = head43 = optptr; ReadOptions43_next: pos=pos; } return(0);}/****************************************************************************** * operator() - get an option from the list * ******************************************************************************/option *PacketStore::operator()(int major_opt=0, int minor_opt=0){ return(GetOption(major_opt, minor_opt));}/****************************************************************************** * GetOption - get an option fromthe option list * ******************************************************************************/option *PacketStore::GetOption(int major_opt=0, int minor_opt=0){ option *opt = new option; option *optptr; if(major_opt == 43) optptr = head43; else optptr = head; for(; optptr != NULL; optptr = optptr->next) if((major_opt == optptr->major_no) && (minor_opt == optptr->minor_no)) break; if(optptr == NULL) return(NULL); opt->major_no = optptr->major_no; opt->minor_no = optptr->minor_no; opt->len = optptr->len; opt->next = NULL; opt->data = new uint8_t[opt->len]; memcpy(opt->data, optptr->data, opt->len); return(opt);}/****************************************************************************** * DelOption - delete an option from the list * ******************************************************************************/intPacketStore::DelOption(int major_opt=0, int minor_opt=0){ option *optptr, *optprev; if(major_opt == 43) optptr = optprev = head43; else optptr = optprev = head; for(; ((major_opt != optptr->major_no) && (minor_opt != optptr->minor_no)) || (optptr != NULL); optptr = optptr->next) optprev = optptr; if(optptr != NULL) // option found { // re-arrange the pointers if(optprev == optptr) // head if(optptr == head43) head43 = optptr->next; else head = optptr->next; else optprev->next = optptr->next; // delete the memory delete[] optptr->data; delete optptr; } else return(1); // no found return(0);}/****************************************************************************** * AddOption - add an option to the list (overwrite) * ******************************************************************************/intPacketStore::AddOption(const option *opt){ option *optptr, *optprev; if(opt->major_no == 43) optptr = optprev = head43; else optptr = optprev = head; // find the entry or null; while(optptr != NULL) { if((opt->major_no != optptr->major_no) && (opt->minor_no != optptr->minor_no)) break; optprev = optptr; optptr = optptr->next; } if(optptr == NULL) // new item { optptr = new option; optptr->major_no = opt->major_no; optptr->minor_no = opt->minor_no; optptr->next = NULL; if((43 == opt->major_no) && (NULL == head43)) head43 = optptr; else if(NULL == head) head = optptr; else optprev->next = optptr; } else // old item { delete[] optptr->data; } optptr->len = opt->len; optptr->data = new uint8_t[optptr->len]; memcpy(optptr->data, opt->data, opt->len); return(0);}/****************************************************************************** * htois - host to intel order (short) * ******************************************************************************/uint16_tPacketStore::htois(uint16_t value){ uint8_t t1, t2; uint16_t val; // convert to a standard val = htons(value); // check if we need to go any further // since Intel order != network order
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -