paulo@0: /* paulo@0: * $Id: gt_packet.h,v 1.27 2004/05/02 10:09:41 hipnod Exp $ paulo@0: * paulo@0: * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net) paulo@0: * paulo@0: * This program is free software; you can redistribute it and/or modify it paulo@0: * under the terms of the GNU General Public License as published by the paulo@0: * Free Software Foundation; either version 2, or (at your option) any paulo@0: * later version. paulo@0: * paulo@0: * This program is distributed in the hope that it will be useful, but paulo@0: * WITHOUT ANY WARRANTY; without even the implied warranty of paulo@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU paulo@0: * General Public License for more details. paulo@0: */ paulo@0: paulo@0: #ifndef GIFT_GT_PACKET_H_ paulo@0: #define GIFT_GT_PACKET_H_ paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: #define PACKET_DEBUG gt_config_get_int("packet/debug=0") paulo@0: #define PACKET_ASCII_LOG gt_config_get_str("packet/ascii_log_file=/dev/tty") paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: #define GNUTELLA_HDR_LEN 23 paulo@0: paulo@0: #define GT_PACKET_INITIAL (48) paulo@0: #define GT_PACKET_MAX (65536) /* smallest invalid, including header */ paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: struct gt_packet paulo@0: { paulo@0: uint32_t offset; /* Pointer within packet */ paulo@0: uint32_t len; /* size of packet structure */ paulo@0: uint32_t data_len; /* how big the packet data is */ paulo@0: uint32_t error; /* packet encountered memory error */ paulo@0: paulo@0: unsigned char *data; /* packet header + arbtrary packet data */ paulo@0: }; paulo@0: paulo@0: typedef struct gt_packet GtPacket; paulo@0: paulo@0: typedef enum gt_packet_type paulo@0: { paulo@0: GT_MSG_PING = 0x00, paulo@0: GT_MSG_PING_REPLY = 0x01, paulo@0: GT_MSG_BYE = 0x02, paulo@0: GT_MSG_QUERY_ROUTE = 0x30, paulo@0: GT_MSG_VENDOR = 0x31, paulo@0: GT_MSG_VENDOR_STD = 0x32, paulo@0: GT_MSG_PUSH = 0x40, paulo@0: GT_MSG_QUERY = 0x80, paulo@0: GT_MSG_QUERY_REPLY = 0x81, paulo@0: } gt_packet_type_t; paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: #define VMSG_HDR_LEN (8) paulo@0: paulo@0: typedef struct gt_vendor_msg paulo@0: { paulo@0: char vendor_id[4]; paulo@0: uint16_t id; paulo@0: } gt_vendor_msg_t; paulo@0: paulo@0: /* paulo@0: * Pretend these global variables are enumerated constants...don't squint paulo@0: * too hard and you won't see they are global variables. paulo@0: */ paulo@0: extern const gt_vendor_msg_t *GT_VMSG_MESSAGES_SUPP, paulo@0: *GT_VMSG_TCP_CONNECT_BACK, paulo@0: *GT_VMSG_HOPS_FLOW, paulo@0: *GT_VMSG_PUSH_PROXY_REQ, paulo@0: *GT_VMSG_PUSH_PROXY_ACK; paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: #define get_guid(pkt) ((pkt)[0]) paulo@0: #define get_command(pkt) ((pkt)[16]) paulo@0: #define get_ttl(pkt) ((pkt)[17]) paulo@0: #define get_hops(pkt) ((pkt)[18]) paulo@0: paulo@0: #define get_payload_len(pkt) \ paulo@0: (((pkt)[19]) | ((pkt)[20] << 8) | \ paulo@0: ((pkt)[21] << 16) | ((pkt)[22] << 24)) paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: /* handle little-endian ordering on the network */ paulo@0: paulo@0: #ifdef WORDS_BIGENDIAN paulo@0: /* paulo@0: * It's best to watch out for sign extension, so we copy to temporary paulo@0: * unsigned variables here. In case the arguments are signed, all is paulo@0: * well. paulo@0: * paulo@0: * NOTE: this depends on a gcc-extension. If someone wants to port to paulo@0: * a big-endian, non-gcc compiler, more work here is needed. paulo@0: * paulo@0: * NOTE2: the uint{16,32}_t types are guaranteed to be _at least_ the paulo@0: * number of bits they say they are (i think), so we discard possibly paulo@0: * extra bits by using bitwise-and. paulo@0: */ paulo@0: #define vtohl(x) \ paulo@0: ({ \ paulo@0: uint32_t _tmp = (x); \ paulo@0: (((_tmp & 0xff) << 24) | ((_tmp & 0xff00) << 8) | \ paulo@0: ((_tmp & 0xff0000) >> 8) | ((_tmp >> 24) & 0xff)); \ paulo@0: }) paulo@0: paulo@0: #define vtohs(x) \ paulo@0: ({ \ paulo@0: uint16_t _tmp = (x); \ paulo@0: (((_tmp & 0xff) << 8) | ((_tmp >> 8) & 0xff)); \ paulo@0: }) paulo@0: #else paulo@0: #define vtohs(x) (x) paulo@0: #define vtohl(x) (x) paulo@0: #endif /* WORDS_BIGENDIAN */ paulo@0: paulo@0: #define htovs(x) vtohs(x) paulo@0: #define htovl(x) vtohl(x) paulo@0: paulo@0: /* endianness defines */ paulo@0: #define BIG 1 paulo@0: #define LITTLE 0 paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: #ifdef __GNUC__ paulo@0: #define FORMAT_ATTRIBUTE(kind, fmt_arg, first_arg) \ paulo@0: __attribute__ ((format (kind, fmt_arg, first_arg))) paulo@0: #else paulo@0: #define FORMAT_ATTRIBUTE(kind, fmt_arg, first_arg) paulo@0: #endif paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: GtPacket *gt_packet_new (uint8_t cmd, uint8_t ttl, gt_guid_t *guid); paulo@0: GtPacket *gt_packet_reply (GtPacket *packet, uint8_t cmd); paulo@0: GtPacket *gt_packet_vendor (const gt_vendor_msg_t *vmsg); paulo@0: void gt_packet_free (GtPacket *packet); paulo@0: int gt_packet_error (GtPacket *packet); paulo@0: int gt_packet_seek (GtPacket *packet, int offset); paulo@0: paulo@0: GtPacket *gt_packet_unserialize (unsigned char *data, size_t len); paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: gt_guid_t *gt_packet_guid (GtPacket *packet); paulo@0: uint32_t gt_packet_payload_len (GtPacket *packet); paulo@0: uint32_t gt_packet_command (GtPacket *packet); paulo@0: uint8_t gt_packet_hops (GtPacket *packet); paulo@0: uint8_t gt_packet_ttl (GtPacket *packet); paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: void gt_packet_set_guid (GtPacket *packet, gt_guid_t *guid); paulo@0: void gt_packet_set_payload_len (GtPacket *packet, uint32_t len); paulo@0: void gt_packet_set_command (GtPacket *packet, uint8_t cmd); paulo@0: void gt_packet_set_hops (GtPacket *packet, uint8_t hops); paulo@0: void gt_packet_set_ttl (GtPacket *packet, uint8_t ttl); paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: uint32_t gt_packet_get_uint (GtPacket *packet, size_t size, paulo@0: int endian, int swap); paulo@0: paulo@0: uint8_t gt_packet_get_uint8 (GtPacket *packet); paulo@0: uint16_t gt_packet_get_uint16 (GtPacket *packet); paulo@0: uint32_t gt_packet_get_uint32 (GtPacket *packet); paulo@0: paulo@0: in_addr_t gt_packet_get_ip (GtPacket *packet); paulo@0: in_port_t gt_packet_get_port (GtPacket *packet); paulo@0: paulo@0: char *gt_packet_get_str (GtPacket *packet); paulo@0: unsigned char *gt_packet_get_ustr (GtPacket *packet, size_t len); paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: int gt_packet_put_uint8 (GtPacket *packet, uint8_t byte); paulo@0: int gt_packet_put_uint16 (GtPacket *packet, uint16_t bytes); paulo@0: int gt_packet_put_uint32 (GtPacket *packet, uint32_t bytes); paulo@0: paulo@0: int gt_packet_put_str (GtPacket *packet, const char *str); paulo@0: int gt_packet_put_ustr (GtPacket *packet, const unsigned char *ustr, paulo@0: size_t len); paulo@0: paulo@0: int gt_packet_put_ip (GtPacket *packet, in_addr_t ip); paulo@0: int gt_packet_put_port (GtPacket *packet, in_port_t port); paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: int gt_packet_send (TCPC *c, GtPacket *packet); paulo@0: paulo@0: int gt_packet_send_fmt (TCPC *c, uint8_t cmd, paulo@0: gt_guid_t *guid, uint8_t ttl, paulo@0: uint8_t hops, char *fmt, ...) paulo@0: FORMAT_ATTRIBUTE (printf, 6, 7); paulo@0: paulo@0: int gt_packet_reply_fmt (TCPC *c, GtPacket *packet, paulo@0: uint8_t cmd, char *fmt, ...) paulo@0: FORMAT_ATTRIBUTE (printf, 4, 5); paulo@0: paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: void gt_packet_log (GtPacket *packet, struct tcp_conn *src, int sent); paulo@0: paulo@0: /*****************************************************************************/ paulo@0: paulo@0: #endif /* GIFT_GT_PACKET_H_ */