Example #1
0
/* PROTO */
IMCOMM_RET
snac_send_cli_update(void *handle)
{
	IMCOMM_RET      ret;
	pkt_t          *pkt;

	/*
         * This makes the server send us extended status information
         */
#if 0
	pkt = pkt_init(12);
	pkt_add16(pkt, 0x001d);
	pkt_add16(pkt, 0x0008);
	pkt_add32(pkt, 0x00020404);
	pkt_add32(pkt, 0x00000000);
#endif

	pkt = pkt_init(8);
	pkt_add16(pkt, 0x0006);
	pkt_add16(pkt, 0x0004);
	if (((IMCOMM *) handle)->isinvisible)
		pkt_add32(pkt, 0x00000100);
	else
		pkt_add32(pkt, 0x00000000);

	ret = snac_sendpkt(handle, 0x01, 0x1e, pkt, 0);
	pkt_free(pkt);
	return ret;
}
Example #2
0
/* PROTO */
void
imcomm_request_awayprofile(void *handle, char *sn)
{
	pkt_t          *packet;
	struct MultiPacket *mpkt;

	mpkt = MultiPktInit();

	packet = pkt_init(3 + (uint8_t) strlen(sn));

	pkt_add16(packet, 0x0003);
	pkt_add8(packet, (uint8_t) strlen(sn));
	pkt_addraw(packet, (uint8_t *) sn, strlen(sn));

	snac_addToMulti(handle, mpkt, 0x02, 0x05, packet->data, packet->len,
			0);

	pkt_free(packet);

	packet = pkt_init(3 + (uint8_t) strlen(sn));

	pkt_add16(packet, 0x0001);
	pkt_add8(packet, (uint8_t) strlen(sn));
	pkt_addraw(packet, (uint8_t *) sn, strlen(sn));

	snac_addToMulti(handle, mpkt, 0x02, 0x05, packet->data, packet->len,
			0);
	pkt_free(packet);

	flap_sendMulti(handle, mpkt);
	MultiPktFree(mpkt);
}
Example #3
0
/* PROTO */
void
imcomm_im_add_buddy(void *handle, char *sn)
{
	IMCOMM_BUDDYLIST *temp, *trav;
	struct MultiPacket *mpkt;
	pkt_t          *packet;
	char           *sname;
	uint16_t        nextid;

	sname = imcomm_simplify_sn(sn);

	for (trav = ((IMCOMM *) handle)->buddylist; trav != NULL;
	     trav = trav->next) {
		if (strcmp(sname, trav->sn) == 0) {
			free(sname);
			return;
		}
	}

	nextid = imcomm_get_next_id(handle);

	temp = malloc(sizeof(IMCOMM_BUDDYLIST));
	temp->sn = sname;
	temp->formattedsn = strdup(sname);
	temp->ssi_id = nextid;
	temp->next = NULL;

	if (((IMCOMM *) handle)->buddylist == NULL)
		((IMCOMM *) handle)->buddylist = temp;
	else {
		for (trav = ((IMCOMM *) handle)->buddylist; trav->next != NULL;
		     trav = trav->next);

		trav->next = temp;
	}

	mpkt = MultiPktInit();

	snac_addToMulti(handle, mpkt, 0x13, 0x11, NULL, 0, 0);
	packet = pkt_init(10 + strlen(sname));
	pkt_add16(packet, (uint16_t) strlen(sname));
	pkt_addraw(packet, (unsigned char *) sname, strlen(sname));
	pkt_add16(packet, 0x0001);
	pkt_add16(packet, nextid);
	pkt_add16(packet, 0x0000);
	pkt_add16(packet, 0x0000);
	snac_addToMulti(handle, mpkt, 0x13, 0x08, packet->data, packet->len,
			0);
	pkt_free(packet);

	snac_addToMulti(handle, mpkt, 0x13, 0x012, NULL, 0, 0);

	flap_sendMulti(handle, mpkt);
	MultiPktFree(mpkt);
}
Example #4
0
/* PROTO */
IMCOMM_RET
snac_ack_srv_pause(void *handle, uint8_t * data, size_t len)
{
	pkt_t          *ackpkt;
	struct IMComm_Families *tr;
	int             count;

	for (count = 0, tr = ((IMCOMM *) handle)->families; tr; tr = tr->next)
		count++;

	ackpkt = pkt_init(count * 2);	/* each family is 16 bits */

	for (tr = ((IMCOMM *) handle)->families; tr; tr = tr->next) {
		pkt_add16(ackpkt, tr->family);
		printf("adding family %d (total %d).\n", tr->family, count);
	}

	((IMCOMM *) handle)->srv_pause = 1;

	/* return snac_send(handle, 0x01, 0x0c, data, len, 0); */
	snac_sendpkt(handle, 0x01, 0x0c, ackpkt, 0);

	pkt_free(ackpkt);

	return IMCOMM_RET_OK;
}
Example #5
0
/* PROTO */
IMCOMM_RET
snac_ack_limits(void *handle, unsigned char *data, size_t len)
{
	pkt_t          *pkt;
	uint16_t        x, y, num_classes, *ids;

	num_classes = two_to_16(data);
	ids = malloc(num_classes * 2);	/* it's a 16 bit type, so we need
					 * twice the bytes. Thanks to djgpp
					 * for catching this bug! UNIX/win32
					 * let it go. */


	for (x = 2, y = 0; y < num_classes; y++) {
		ids[y] = two_to_16(data + x);
		x += 35;
	}

	pkt = pkt_init(num_classes * 2);

	for (y = 0; y < num_classes; y++)
		pkt_add16(pkt, ids[y]);

	if (snac_sendpkt(handle, 0x01, 0x08, pkt, 0) != IMCOMM_RET_OK) {
		pkt_free(pkt);
		free(ids);
		return IMCOMM_RET_ERROR;
	}
	pkt_free(pkt);
	free(ids);

	return snac_multireq(handle);
}
Example #6
0
/* PROTO */
void
snac_addToMulti(void *handle, struct MultiPacket * mpkt, uint16_t family, uint16_t subtype, unsigned char *data, uint16_t len, int updateidle)
{
	pkt_t          *snac_packet;

	snac_packet = pkt_init(len + 10);
	pkt_add16(snac_packet, family);
	pkt_add16(snac_packet, subtype);
	pkt_add16(snac_packet, 0);
	pkt_add32(snac_packet, ((IMCOMM *) handle)->snacreq);
	pkt_addraw(snac_packet, (uint8_t *) data, len);
	((IMCOMM *) handle)->snacreq++;

	flap_addToMulti(mpkt, 0x02, snac_packet->data, snac_packet->len,
			updateidle);
	pkt_free(snac_packet);
}
Example #7
0
/* PROTO */
void
imcomm_im_send_message(void *handle, const char *whom, const char *msg, int automsg)
{
	pkt_t          *packet;

	packet = pkt_init(28 + strlen(whom) + strlen(msg) + (4 * automsg));

	/*
         * Message cookie?
         *
         * Putting something random seems to work.
         */
	pkt_add32(packet, 0x01020304);
	pkt_add32(packet, 0x05060708);

	pkt_add16(packet, 0x0001);
	pkt_add8(packet, (uint8_t) strlen(whom));
	pkt_addraw(packet, (uint8_t *) whom, strlen(whom));
	pkt_add16(packet, 0x0002);
	pkt_add16(packet, (uint16_t) (uint16_t) (strlen(msg) + 13));
	pkt_add32(packet, 0x05010001);
	pkt_add8(packet, 0x01);
	pkt_add16(packet, 0x0101);
	pkt_add16(packet, (uint16_t) (uint16_t) (strlen(msg) + 4));
	pkt_add32(packet, 0x00000000);
	pkt_addraw(packet, (uint8_t *) msg, strlen(msg));

	if (automsg) {
		pkt_add16(packet, 0x0004);
		pkt_add16(packet, 0x0000);
	}
	snac_sendpkt(handle, 0x04, 0x06, packet, (automsg ? 0 : 1));
	pkt_free(packet);
}
Example #8
0
/* PROTO */
IMCOMM_RET
snac_send_icbm_params(void *handle, uint16_t channel, uint16_t max_msg_size)
{
	IMCOMM_RET      ret;
	pkt_t          *packet;

	packet = pkt_init(16);
	pkt_add32(packet, 0x00000000);
	pkt_add16(packet, 0x000b);
	pkt_add16(packet, 0x1f40);
	pkt_add16(packet, ((IMCOMM *) handle)->max_sender_warning);
	pkt_add16(packet, ((IMCOMM *) handle)->max_receiver_warning);
	pkt_add32(packet, 0x00000000);

	ret = snac_sendpkt(handle, 0x04, 0x02, packet, 0);
	pkt_free(packet);
	return ret;
}
Example #9
0
/* PROTO */
void
snac_request_new_service(void *handle, uint16_t service)
{
	pkt_t          *pkt;

	pkt = pkt_init(2);
	pkt_add16(pkt, service);
	snac_sendpkt(handle, 0x01, 0x04, pkt, 0);
	pkt_free(pkt);
}
Example #10
0
/* PROTO */
void
snac_finish_buddy_icon(void *handle)
{
	/*
         * The icon data is contained in the parent's node
         */

	pkt_t          *newpkt;
	void           *pptr = ((IMCOMM *) handle)->parent;

	newpkt = pkt_init(4 + ((IMCOMM *) pptr)->iconlen);
	pkt_add16(newpkt, 0x0001);
	pkt_add16(newpkt, ((IMCOMM *) pptr)->iconlen);
	pkt_addraw(newpkt, ((IMCOMM *) pptr)->icondata,
		   ((IMCOMM *) pptr)->iconlen);

	snac_sendpkt(handle, 0x10, 0x02, newpkt, 0);
	pkt_free(newpkt);
}
Example #11
0
/****************************************************************************
 * ow_write_header(struct owctx *ow)
 *
 * Write OLE header block.
 */
void ow_write_header(struct owctx *ow)
{
  int root_start;
  int num_lists;
  struct pkt *pkt;
  int i;

  if (ow->biff_only)
    return;

  ow_calculate_sizes(ow);

  root_start = ow->root_start;
  num_lists = ow->list_blocks;

  pkt = pkt_init(0, VARIABLE_PACKET);
  pkt_add32(pkt, 0xD0CF11E0); /* OLE document file id part 1 */
  pkt_add32(pkt, 0xA1B11AE1); /* OLE document file id part 2 */
  pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 1/4 */
  pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 2/4 */
  pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 3/4 */
  pkt_add32_le(pkt, 0x00); /* UID of this file (can be all 0's) 4/4 */
  pkt_add16_le(pkt, 0x3E); /* Revision number (almost always 0x003E) */
  pkt_add16_le(pkt, 0x03); /* Version number (almost always 0x0003) */
  pkt_add16(pkt, 0xFEFF);  /* Byte order identifier:
                            * (0xFEFF = Little Endian)
                            * (0xFFFE = Big Endian)    */
  pkt_add16_le(pkt, 0x09); /* 2^x  (9 = 512 bytes) */
  pkt_add32_le(pkt, 0x06); /* Unknown 5 */
  pkt_add32_le(pkt, 0x00); /* Unknown 5 */
  pkt_add32_le(pkt, 0x00); /* Unknown 5 */
  pkt_add32_le(pkt, num_lists); /* num_bbd_blocks */
  pkt_add32_le(pkt, root_start); /* root_startblock */
  pkt_add32_le(pkt, 0x00); /* Unknown 6 */
  pkt_add32_le(pkt, 0x1000); /* Unknown 6 */
  pkt_add32_le(pkt, -2);  /* sbd_startblock */
  pkt_add32_le(pkt, 0x00); /* Unknown 7 */
  pkt_add32_le(pkt, -2); /* Unknown 7 */
  pkt_add32_le(pkt, 0x00); /* Unknown 7 */

  for (i = 1; i <= num_lists; i++) {
    root_start++;
    pkt_add32_le(pkt, root_start);

  }

  for (i = num_lists; i <= 108; i++) {
    pkt_add32_le(pkt, -1); /* Unused */
  }

  ow->io_handler.write(ow->io_handle,pkt->data, pkt->len);

  pkt_free(pkt);
}
Example #12
0
/* PROTO */
IMCOMM_RET
snac_send(void *handle, uint16_t family, uint16_t subtype, unsigned char *data, uint16_t len, int updateidle)
{
	pkt_t          *snac_packet;
	IMCOMM_RET      ret;

	if (((IMCOMM *) handle)->srv_pause)
		return IMCOMM_RET_OK;

	snac_packet = pkt_init(len + 10);
	pkt_add16(snac_packet, family);
	pkt_add16(snac_packet, subtype);
	pkt_add16(snac_packet, 0);
	pkt_add32(snac_packet, ((IMCOMM *) handle)->snacreq);
	pkt_addraw(snac_packet, (uint8_t *) data, len);
	((IMCOMM *) handle)->snacreq++;

	ret = flap_sendpkt(handle, 0x02, snac_packet, updateidle);
	pkt_free(snac_packet);
	return ret;
}
Example #13
0
/* PROTO */
IMCOMM_RET
multi_ssiact_cliready(void *handle)
{
	struct MultiPacket *multipkt;
	pkt_t          *cliupdpkt;
	unsigned char   cli_ready_packet[] = {0x00,
		0x13, 0x00, 0x03, 0x01, 0x10, 0x08, 0xE5, 0x00, 0x0b, 0x00, 0x01,
		0x01, 0x10, 0x08, 0xe5, 0x00, 0x0a, 0x00, 0x01, 0x01, 0x10,
		0x08, 0xe5, 0x00, 0x09, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5,
		0x00, 0x08, 0x00, 0x01, 0x01, 0x04, 0x00, 0x01, 0x00, 0x06,
		0x00, 0x01, 0x01, 0x10, 0x08, 0xe5, 0x00, 0x04, 0x00, 0x01,
		0x01, 0x10, 0x08, 0xe5, 0x00, 0x03, 0x00, 0x01, 0x01, 0x10,
		0x08, 0xe5, 0x00, 0x02, 0x00, 0x01, 0x01, 0x10, 0x08, 0xe5,
		0x00, 0x01, 0x00, 0x04, 0x01, 0x10, 0x08, 0xe5
	};

	multipkt = MultiPktInit();

	cliupdpkt = pkt_init(12);
	pkt_add16(cliupdpkt, 0x001d);
	pkt_add16(cliupdpkt, 0x0008);
	pkt_add32(cliupdpkt, 0x00020404);
	pkt_add32(cliupdpkt, 0x00000000);

	snac_addToMulti(handle, multipkt, 0x01, 0x1e, cliupdpkt->data,
			cliupdpkt->len, 0);
	snac_addToMulti(handle, multipkt, 0x01, 0x02, cli_ready_packet,
			sizeof(cli_ready_packet), 0);
	snac_addToMulti(handle, multipkt, 0x13, 0x07, NULL, 0, 0);

	flap_sendMulti(handle, multipkt);
	MultiPktFree(multipkt);
	pkt_free(cliupdpkt);

	if (((IMCOMM *) handle)->callbacks[IMCOMM_ERROR])
		((IMCOMM *) handle)->callbacks[IMCOMM_ERROR] (handle,
						   IMCOMM_STATUS_CONNECTED);

	return IMCOMM_RET_OK;
}
Example #14
0
/* PROTO */
void
imcomm_request_awaymsg(void *handle, char *sn)
{
	pkt_t          *packet;

	packet = pkt_init(3 + (uint8_t) strlen(sn));

	pkt_add16(packet, 0x0003);
	pkt_add8(packet, (uint8_t) strlen(sn));
	pkt_addraw(packet, (uint8_t *) sn, strlen(sn));

	snac_sendpkt(handle, 0x02, 0x05, packet, 0);
	pkt_free(packet);
}
Example #15
0
/* PROTO */
void
imcomm_request_massawaymsg(void *handle, char **sns, int num)
{
	pkt_t          *packet;
	int             x;
	struct MultiPacket *multipkt;

	multipkt = MultiPktInit();

	for (x = 0; x < num; x++) {
		packet = pkt_init(3 + (uint8_t) strlen(sns[x]));

		pkt_add16(packet, 0x0003);
		pkt_add8(packet, (uint8_t) strlen(sns[x]));
		pkt_addraw(packet, (uint8_t *) sns[x], strlen(sns[x]));

		snac_addToMulti(handle, multipkt, 0x02, 0x05, packet->data,
				(uint16_t) packet->len, 0);
		pkt_free(packet);
	}

	flap_sendMulti(handle, multipkt);
	MultiPktFree(multipkt);
}
Example #16
0
/* PROTO */
IMCOMM_RET
snac_set_location_info(void *handle)
{
	pkt_t          *packet;
	char           *idstr = "text/aolrtf; charset=\"iso-8859-1\"";
	int             pktlen = 0;
	uint8_t         capabilities[] =
	{0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44,
		0x45, 0x53, 0x54,
		0x00, 0x00,
		0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44,
		0x45, 0x53, 0x54, 0x00, 0x00,
		0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 0x82, 0x22, 0x44,
		0x45, 0x53, 0x54, 0x00, 0x00
	};

	snac_send_cli_update(handle);

	if (((IMCOMM *) handle)->profile_str != NULL)
		pktlen +=
			8 + strlen(idstr) +
			strlen((char *) ((IMCOMM *) handle)->profile_str);
	if (((IMCOMM *) handle)->away_msg != NULL)
		pktlen += strlen((char *) ((IMCOMM *) handle)->away_msg);

	packet =
		pkt_init(pktlen + 10 + 8 + 4 + strlen(idstr) +
			 sizeof(capabilities));

	pkt_add16(packet, 0x0001);
	pkt_add16(packet, (uint16_t) strlen(idstr));
	pkt_addraw(packet, (uint8_t *) idstr, strlen(idstr));

	if (((IMCOMM *) handle)->profile_str != NULL) {
		pkt_add16(packet, 0x0002);
		pkt_add16(packet,
			  (uint16_t) strlen((char *) ((IMCOMM *) handle)->
					    profile_str));
		pkt_addraw(packet, ((IMCOMM *) handle)->profile_str,
			 strlen((char *) ((IMCOMM *) handle)->profile_str));
	}
	pkt_add16(packet, 0x0003);
	pkt_add16(packet, (uint16_t) strlen(idstr));
	pkt_addraw(packet, (uint8_t *) idstr, strlen(idstr));
	pkt_add16(packet, 0x0004);

	if (((IMCOMM *) handle)->away_msg != NULL) {
		pkt_add16(packet,
			  (uint16_t) strlen((char *) ((IMCOMM *) handle)->
					    away_msg));
		pkt_addraw(packet, ((IMCOMM *) handle)->away_msg,
			   (uint16_t) strlen((char *) ((IMCOMM *) handle)->
					     away_msg));
	} else {
		pkt_add16(packet, 0x0000);
	}

	pkt_add16(packet, 0x0005);
	pkt_add16(packet, (uint16_t) sizeof(capabilities));
	pkt_addraw(packet, capabilities, sizeof(capabilities));
	pkt_add16(packet, 0x0006);
	pkt_add16(packet, 0x0006);
	pkt_add16(packet, 0x0004);
	pkt_add32(packet, 0x00020002);

	snac_sendpkt(handle, 0x02, 0x04, packet, 0);
	pkt_free(packet);
	return IMCOMM_RET_OK;
}
Example #17
0
/* PROTO */
void
imcomm_im_remove_buddy(void *handle, const char *sn)
{
	char           *sname, *snsend = NULL;
	pkt_t          *packet;
	IMCOMM_BUDDYLIST *temp, *trav;
	struct MultiPacket *mpkt;
	uint16_t        buddy_id = 0x00, buddy_group_id = 0x00;

	sname = imcomm_simplify_sn(sn);

	if (((IMCOMM *) handle)->buddylist != NULL) {
		if (strcmp(((IMCOMM *) handle)->buddylist->sn, sname) == 0) {
			temp = ((IMCOMM *) handle)->buddylist;
			((IMCOMM *) handle)->buddylist =
				((IMCOMM *) handle)->buddylist->next;

			buddy_id = temp->ssi_id;
			buddy_group_id = temp->group_id;
			snsend = temp->formattedsn;
			free(temp->sn);
			free(temp);
		} else {
			for (trav = ((IMCOMM *) handle)->buddylist; trav->next != NULL;
			     trav = trav->next) {
				if (strcmp(trav->next->sn, sname) == 0) {
					temp = trav->next;
					trav->next = trav->next->next;

					buddy_id = temp->ssi_id;
					buddy_group_id = temp->group_id;
					snsend = temp->formattedsn;
					free(temp->sn);
					free(temp);
					break;
				}
			}
		}
	}
	imcomm_internal_delete_buddy(handle, sn);

	if (snsend == NULL) {
		free(sname);
		return;
	}
	/*
         * packet = malloc(strlen(sname) + 1); packet[0] = strlen(sname);
         * memcpy(packet + 1, sname, strlen(sname));
         *
         * snac_send(handle, 0x03, 0x05, packet, (uint16_t) (strlen(sname) + 1),
         * 0); free(packet);
         */

	mpkt = MultiPktInit();

	snac_addToMulti(handle, mpkt, 0x13, 0x11, NULL, 0, 0);
	packet = pkt_init(10 + strlen(snsend));
	pkt_add16(packet, (uint16_t) strlen(snsend));
	pkt_addraw(packet, (unsigned char *) snsend, strlen(snsend));
	pkt_add16(packet, buddy_group_id);
	pkt_add16(packet, buddy_id);
	pkt_add16(packet, 0x0000);
	pkt_add16(packet, 0x0000);
	snac_addToMulti(handle, mpkt, 0x13, 0x0a, packet->data, packet->len,
			0);
	pkt_free(packet);

	snac_addToMulti(handle, mpkt, 0x13, 0x012, NULL, 0, 0);

	flap_sendMulti(handle, mpkt);
	MultiPktFree(mpkt);
	free(sname);
	free(snsend);
}
Example #18
0
/* PROTO */
int
connect_socks5(void *handle, char *host, uint16_t port)
{
	IMCOMM         *h = (IMCOMM *) handle;
	struct sockaddr_in sin;
	struct hostent *he = NULL;
	long            addy;
	struct in_addr  ina = {0};
	pkt_t          *sockspkt;
	uint8_t         len;
	unsigned char   sockbuf[512];

#ifdef DEBUG
	printf("Connecting via SOCKS5 to %s/%u\n", host, port);
	printf("SOCKS5 proxy server: %s/%u\n", h->proxyserver, h->proxyport);
#endif

	if ((he = gethostbyname(h->proxyserver)) == NULL) {
		addy = inet_addr(h->proxyserver);
		ina.s_addr = addy;
	}
	if ((h->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		if (h->callbacks[IMCOMM_ERROR])
			h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY,
						    PROXY_ERROR_CONNECT);

		return IMCOMM_RET_ERROR;
	}
	sin.sin_family = AF_INET;
	sin.sin_port = htons(h->proxyport);

	if (he == NULL)
		sin.sin_addr = ina;
	else
		sin.sin_addr = *((struct in_addr *) he->h_addr);

	memset(&(sin.sin_zero), 0, 8);

	if (connect
	    (h->socket, (struct sockaddr *) & sin,
	     sizeof(struct sockaddr)) == -1) {
		if (h->callbacks[IMCOMM_ERROR])
			h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY,
						    PROXY_ERROR_CONNECT);

		return IMCOMM_RET_ERROR;
	}
	sockspkt = pkt_init(3);
	pkt_add8(sockspkt, 0x05);
	pkt_add8(sockspkt, 0x01);
	pkt_add8(sockspkt, 0x00);

	if (send(h->socket, sockspkt->data, sockspkt->len, 0) < 0) {
		pkt_free(sockspkt);
		if (h->callbacks[IMCOMM_ERROR])
			h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_DISCONNECTED,
						    0);

		shutdown(h->socket, 0x02);
		h->socket = -1;
		return IMCOMM_RET_ERROR;
	}
	pkt_free(sockspkt);

	recv(h->socket, sockbuf, 2, 0);
	if (sockbuf[1] != 0x00) {
		if (h->callbacks[IMCOMM_ERROR])
			h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY,
						    PROXY_ERROR_AUTH);
		return IMCOMM_RET_ERROR;
	}
	sockspkt = pkt_init(7 + strlen(host));
	pkt_add8(sockspkt, 0x05);
	pkt_add8(sockspkt, 0x01);
	pkt_add8(sockspkt, 0x00);
	pkt_add8(sockspkt, 0x03);
	pkt_add8(sockspkt, (uint8_t) strlen(host));
	pkt_addraw(sockspkt, (unsigned char *) host, strlen(host));
	pkt_add16(sockspkt, port);

	if (send(h->socket, sockspkt->data, sockspkt->len, 0) < 0) {
		pkt_free(sockspkt);
		if (h->callbacks[IMCOMM_ERROR])
			h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_DISCONNECTED,
						    0);

		shutdown(h->socket, 0x02);
		h->socket = -1;
		return IMCOMM_RET_ERROR;
	}
	pkt_free(sockspkt);

	recv(h->socket, sockbuf, 4, 0);
	if (sockbuf[1] != 0x00) {
		if (h->callbacks[IMCOMM_ERROR])
			h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY,
						  PROXY_ERROR_PROXYCONNECT);
		shutdown(h->socket, 0x02);
		h->socket = -1;

		return IMCOMM_RET_ERROR;
	}
	if (sockbuf[3] == 0x03) {
		recv(h->socket, &len, 1, 0);
		recv(h->socket, sockbuf, len + 2, 0);
	} else if (sockbuf[3] == 0x01) {
		recv(h->socket, sockbuf, 6, 0);
	} else {
		if (h->callbacks[IMCOMM_ERROR])
			h->callbacks[IMCOMM_ERROR] (handle, IMCOMM_ERROR_PROXY,
						    PROXY_ERROR_UNKNOWN);

		shutdown(h->socket, 0x02);
		h->socket = -1;
		return IMCOMM_RET_ERROR;
	}

	/* now we should be set to read the connection */

	return IMCOMM_RET_OK;
}