/* 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); }
/* * udp_exec_pkt: passes the received udp packet to pkt_exec(). * `passed_argv' is a pointer to a udp_exec_pkt_argv struct */ void * udp_exec_pkt(void *passed_argv) { struct udp_exec_pkt_argv argv; PACKET rpkt; const char *ntop; memcpy(&argv, passed_argv, sizeof(struct udp_exec_pkt_argv)); memcpy(&rpkt, argv.recv_pkt, sizeof(PACKET)); if (argv.flags & UDP_THREAD_FOR_EACH_PKT) pthread_mutex_unlock(&udp_exec_lock); /* Drop any packet we sent in broadcast */ if (!memcmp(rpkt.from.data, me.cur_ip.data, MAX_IP_SZ)) { pkt_free(&rpkt, 0); return 0; } if (add_accept(rpkt.from, 1)) { ntop = inet_to_str(rpkt.from); debug(DBG_NORMAL, "ACPT: dropped UDP pkt from %s: " "Accept table full.", ntop); return 0; } pkt_exec(rpkt, argv.acpt_idx); pkt_free(&rpkt, 0); return 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); }
/* drop incoming presence if the user isn't around, * so we don't have to load them during broadcasts */ mod_ret_t _presence_in_router(mod_instance_t mi, pkt_t pkt) { user_t user; sess_t sess; /* only check presence to users, pass presence to sm and probes */ if(!(pkt->type & pkt_PRESENCE) || pkt->to->node[0] == '\0' || pkt->type == pkt_PRESENCE_PROBE) return mod_PASS; /* get the user _without_ doing a load */ user = xhash_get(mi->mod->mm->sm->users, jid_user(pkt->to)); /* no user, or no sessions, bail */ if(user == NULL || user->sessions == NULL) { pkt_free(pkt); return mod_HANDLED; } /* only pass if there's at least one available session */ for(sess = user->sessions; sess != NULL; sess = sess->next) if(sess->available) return mod_PASS; /* no available sessions, drop */ pkt_free(pkt); return mod_HANDLED; }
void * tcp_recv_loop(void *recv_pkt) { PACKET rpkt; int acpt_idx, acpt_sidx; acpt_idx = accept_idx; acpt_sidx = accept_sidx; memcpy(&rpkt, recv_pkt, sizeof(PACKET)); pthread_mutex_unlock(&tcp_exec_lock); #if 0 add_accept_pid(getpid(), acpt_idx, acpt_sidx); #endif while (pkt_recv(&rpkt) != -1) { if (pkt_exec(rpkt, acpt_idx) < 0) { goto close; break; } else pkt_free(&rpkt, 0); } close: pkt_free(&rpkt, 1); close_accept(acpt_idx, acpt_sidx); return NULL; }
/* 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); }
/**************************************************************************** * ow_write_big_block_depot(struct owctx *ow) * * Write big block depot. */ void ow_write_big_block_depot(struct owctx *ow) { int num_blocks = ow->big_blocks; int num_lists = ow->list_blocks; int total_blocks = num_lists * 128; int used_blocks = num_blocks + num_lists + 2; struct pkt *pkt; int i; pkt = pkt_init(0, VARIABLE_PACKET); for (i = 1; i <= num_blocks - 1; i++) { pkt_add32_le(pkt, i); } /* End of chain */ pkt_add32_le(pkt, -2); pkt_add32_le(pkt, -2); for (i = 1; i <= num_lists; i++) { pkt_add32_le(pkt, -3); } for (i = used_blocks; i <= total_blocks; i++) { pkt_add32_le(pkt, -1); } ow->io_handler.write(ow->io_handle,pkt->data, pkt->len); pkt_free(pkt); }
/* 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; }
/**************************************************************************** * bw_store_bof(struct bwctx *bw, uint16_t type) * * type = 0x0005, Workbook * type = 0x0010, Worksheet * * Writes Excel BOF (Beginning of File) record to indicate the beginning of * a stream or substream in the BIFF file */ void bw_store_bof(struct bwctx *bw, uint16_t type) { uint16_t name = 0x0809; /* Record identifier */ uint16_t length = 0x0008; /* Number of bytes to follow */ /* According to the SDK "build" and "year" should be set to zero. * However, this throws a warning in Excel 5. So, use these * magic umbers */ uint16_t build = 0x096C; uint16_t year = 0x07C9; struct pkt *pkt; pkt = pkt_init(12, FIXED_PACKET); /* Construct header */ pkt_add16_le(pkt, name); pkt_add16_le(pkt, length); /* Construct data */ pkt_add16_le(pkt, g_BIFF_version); pkt_add16_le(pkt, type); pkt_add16_le(pkt, build); pkt_add16_le(pkt, year); bw_prepend(bw, pkt->data, pkt->len); pkt_free(pkt); }
/* 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; }
static mod_ret_t _vacation_pkt_user(mod_instance_t mi, user_t user, pkt_t pkt) { module_t mod = mi->mod; vacation_t v = user->module_data[mod->index]; time_t t; pkt_t res; if(v->msg == NULL) return mod_PASS; /* only want messages, and only if they're offline */ if(!(pkt->type & pkt_MESSAGE) || user->top != NULL) return mod_PASS; /* reply only to real, human users - they always have full JIDs in 'from' */ jid_expand(pkt->from); if(pkt->from->node[0] == '\0' || pkt->from->resource[0] == '\0') { pkt_free(pkt); return mod_HANDLED; } t = time(NULL); if(v->start < t && (t < v->end || v->end == 0)) { res = pkt_create(mod->mm->sm, "message", NULL, jid_full(pkt->from), mod->mm->sm->id); nad_insert_elem(res->nad, 1, NAD_ENS(res->nad, 1), "subject", "Automated reply"); nad_insert_elem(res->nad, 1, NAD_ENS(res->nad, 1), "body", v->msg); pkt_router(res); /* !!! remember that we sent this */ } return mod_PASS; }
/* Writes Excel BIFF BOUNDSHEET record */ void wbook_store_boundsheet(struct wbookctx *wbook, char *sname, int offset) { uint16_t name = 0x0085; /* Record identifier */ uint16_t length; uint16_t grbit = 0x0000; int cch; struct pkt *pkt; length = 0x07 + strlen(sname); /* Number of bytes to follow */ cch = strlen(sname); pkt = pkt_init(0, VARIABLE_PACKET); /* Write header */ pkt_add16_le(pkt, name); pkt_add16_le(pkt, length); /* Write data */ pkt_add32_le(pkt, offset); /* Location of worksheet BOF */ pkt_add16_le(pkt, grbit); /* Sheet identifier */ pkt_add8(pkt, cch); /* Length of sheet name */ pkt_addraw(pkt, (unsigned char *)sname, cch); bw_append(wbook->biff, pkt->data, pkt->len); pkt_free(pkt); }
/** presence to a user */ static mod_ret_t _presence_pkt_user(mod_instance_t mi, user_t user, pkt_t pkt) { sess_t sess; /* only handle presence */ if(!(pkt->type & pkt_PRESENCE)) return mod_PASS; /* errors get tracked, but still delivered (T6) */ if(pkt->type & pkt_ERROR) { /* find the session */ sess = sess_match(user, pkt->to->resource); if(sess == NULL) { log_debug(ZONE, "bounced presence, but no corresponding session anymore, dropping"); pkt_free(pkt); return mod_HANDLED; } log_debug(ZONE, "bounced presence, tracking"); pres_error(sess, pkt->from); /* bounced probes get dropped */ if((pkt->type & pkt_PRESENCE_PROBE) == pkt_PRESENCE_PROBE) { pkt_free(pkt); return mod_HANDLED; } } /* if there's a resource, send it direct */ if(pkt->to->resource[0] != '\0') { sess = sess_match(user, pkt->to->resource); if(sess == NULL) { /* resource isn't online - XMPP-IM 11.3 requires we ignore it*/ pkt_free(pkt); return mod_HANDLED; } pkt_sess(pkt, sess); return mod_HANDLED; } /* remote presence updates (T4, T5) */ pres_in(user, pkt); return mod_HANDLED; }
static int send_pkt(struct pkt *pkt) { int i; i = ip_send(ctx.ip, pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); pkt_free(pkt); return (i); }
/* presence packets to the sm */ static mod_ret_t _presence_pkt_sm(mod_instance_t mi, pkt_t pkt) { module_t mod = mi->mod; jid_t smjid; /* only check presence/subs to server JID */ if(!(pkt->type & pkt_PRESENCE || pkt->type & pkt_S10N)) return mod_PASS; smjid = jid_new(jid_user(pkt->to), -1); /* handle subscription requests */ if(pkt->type == pkt_S10N) { log_debug(ZONE, "accepting subscription request from %s", jid_full(pkt->from)); /* accept request */ pkt_router(pkt_create(mod->mm->sm, "presence", "subscribed", jid_user(pkt->from), jid_user(smjid))); /* and subscribe back to theirs */ pkt_router(pkt_create(mod->mm->sm, "presence", "subscribe", jid_user(pkt->from), jid_user(smjid))); pkt_free(pkt); jid_free(smjid); return mod_HANDLED; } /* handle unsubscribe requests */ if(pkt->type == pkt_S10N_UN) { log_debug(ZONE, "accepting unsubscribe request from %s", jid_full(pkt->from)); /* ack the request */ pkt_router(pkt_create(mod->mm->sm, "presence", "unsubscribed", jid_user(pkt->from), jid_user(smjid))); pkt_free(pkt); jid_free(smjid); return mod_HANDLED; } /* drop the rest */ log_debug(ZONE, "dropping presence from %s", jid_full(pkt->from)); pkt_free(pkt); jid_free(smjid); return mod_HANDLED; }
static int test_frag(char *overlap, int drop) { struct timeval tv, save_tv = read_tv; struct pkt *pkt; struct icmp_msg_echo *echo; char *frag_argv[4]; if (overlap != NULL) printf("frag-%s: ", overlap); else if (drop) printf("frag-timeout (please wait): "); else printf("frag: "); fflush(stdout); ping->pkt_ip->ip_id = rand_uint16(ctx.rnd); ping->pkt_icmp_msg->echo.icmp_id = rand_uint16(ctx.rnd); pkt = pkt_dup(ping); ip_checksum(pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); TAILQ_INSERT_TAIL(&ctx.pktq, pkt, pkt_next); frag_argv[0] = "ip_frag"; frag_argv[1] = "8"; frag_argv[2] = overlap; frag_argv[3] = NULL; mod_ip_frag.open(overlap ? 3 : 2, frag_argv, NULL); mod_ip_frag.apply(NULL, &ctx.pktq, NULL); if (drop) { pkt = TAILQ_LAST(&ctx.pktq, pktq); TAILQ_REMOVE(&ctx.pktq, pkt, pkt_next); pkt_free(pkt); save_tv.tv_sec = FRAG_TIMEOUT; } pcap_filter(ctx.pcap, "icmp[0] = %d and src %s and dst %s", drop ? 11 : 0, addr_ntoa(&ctx.dst), addr_ntoa(&ctx.src)); send_pktq(&ctx.pktq); for (tv = save_tv; (pkt = recv_pkt(&tv)) != NULL; tv = save_tv) { if (drop) { echo = (struct icmp_msg_echo *) (pkt->pkt_icmp_msg->timexceed.icmp_ip + IP_HDR_LEN + ICMP_HDR_LEN); } else { echo = &pkt->pkt_icmp_msg->echo; } if (echo->icmp_id == ping->pkt_icmp_msg->echo.icmp_id) break; } printf("%s\n", pkt ? timeval_ntoa(&tv) : "no reply"); return (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); }
/* 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); }
/**************************************************************************** * 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); }
/* Write all FONT records. */ void wbook_store_all_fonts(struct wbookctx *wbook) { int i; struct pkt *font; struct htbl *fonts; int key; int index; font = fmt_get_font(wbook->tmp_format); for (i = 1; i < 6; i++) { bw_append(wbook->biff, font->data, font->len); } pkt_free(font); fonts = hashtbl_new(wbook->formatcount + 1); /* For tmp_format */ index = 6; /* First user defined FONT */ key = fmt_gethash(wbook->tmp_format); hashtbl_insert(fonts, key, 0); /* Index of the default font */ /* User defined fonts */ for (i = 0; i < wbook->formatcount; i++) { int data; key = fmt_gethash(wbook->formats[i]); data = hashtbl_get(fonts, key); if (data >= 0) { /* FONT has already been used */ wbook->formats[i]->font_index = data; } else { /* Add a new FONT record */ hashtbl_insert(fonts, key, index); wbook->formats[i]->font_index = index; index++; font = fmt_get_font(wbook->formats[i]); bw_append(wbook->biff, font->data, font->len); pkt_free(font); } } hashtbl_destroy(fonts); }
/* Write all XF records */ void wbook_store_all_xfs(struct wbookctx *wbook) { int i; struct pkt *xf; xf = fmt_get_xf(wbook->tmp_format, 0xFFF5); /* Style XF */ for (i = 0; i <= 14; i++) { bw_append(wbook->biff, xf->data, xf->len); } pkt_free(xf); xf = fmt_get_xf(wbook->tmp_format, 0x0001); /* Cell XF */ bw_append(wbook->biff, xf->data, xf->len); pkt_free(xf); /* User defined formats */ for (i = 0; i < wbook->formatcount; i++) { xf = fmt_get_xf(wbook->formats[i], 0x0001); bw_append(wbook->biff, xf->data, xf->len); pkt_free(xf); } }
/* PROTO */ ssize_t send_cmdpkt(void *handle, pkt_t *packet) { pkt_t *n; ssize_t ret; n = pkt_init(2+packet->len); pkt_addraw(n, packet->data, packet->len); pkt_addraw(n, (unsigned char *)"\r\n", 2); ret = sendPkt(handle, n); pkt_free(n); return ret; }
/* 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); }
/**************************************************************************** * bw_store_eof(struct bwctx *bw) * * Writes Excel EOF (End of File) record to indicate the end of a BIFF stream. */ void bw_store_eof(struct bwctx *bw) { struct pkt *pkt; uint16_t name = 0x000A; /* Record identifier */ uint16_t length = 0x0000; /* Number of bytes to follow */ pkt = pkt_init(4, FIXED_PACKET); /* Construct header */ pkt_add16_le(pkt, name); pkt_add16_le(pkt, length); bw->append(bw, pkt->data, pkt->len); pkt_free(pkt); }
/* Write Excel 1904 record to indicate the date system in use. */ static void wbook_store_1904(struct wbookctx *wbook) { struct pkt *pkt; pkt = pkt_init(6, FIXED_PACKET); /* Write header */ pkt_add16_le(pkt, 0x0022); /* Record identifier */ pkt_add16_le(pkt, 0x0002); /* Write data */ pkt_add16_le(pkt, wbook->epoch1904); /* Flag for 1904 date system */ bw_append(wbook->biff, pkt->data, pkt->len); pkt_free(pkt); }
/* Stores the CODEPAGE biff record */ static void wbook_store_codepage(struct wbookctx *wbook) { struct pkt *pkt; pkt = pkt_init(6, FIXED_PACKET); /* Write header */ pkt_add16_le(pkt, 0x0042); /* Record identifier */ pkt_add16_le(pkt, 0x0002); /* Write data */ pkt_add16_le(pkt, wbook->codepage); bw_append(wbook->biff, pkt->data, pkt->len); pkt_free(pkt); }
/**************************************************************************** * ow_write_pps(struct owctx *ow, char *name) * * Write property sheet in property storage */ void ow_write_pps(struct owctx *ow, char *name, int pps_type, int pps_dir, int pps_start, int pps_size) { unsigned char header[64]; int length; struct pkt *pkt; memset(header, 0, sizeof(header)); length = 0; if (name != NULL) { /* Simulate a unicode string */ char *p = name; int i = 0; while (*p != '\0') { header[i] = *p++; i += 2; } length = (strlen(name) * 2) + 2; } pkt = pkt_init(0, VARIABLE_PACKET); pkt_addraw(pkt, header, sizeof(header)); pkt_add16_le(pkt, length); /* pps_sizeofname 0x40 */ pkt_add16_le(pkt, pps_type); /* 0x42 */ pkt_add32_le(pkt, -1); /* pps_prev 0x44 */ pkt_add32_le(pkt, -1); /* pps_next 0x48 */ pkt_add32_le(pkt, pps_dir); /* pps_dir 0x4C */ pkt_add32_le(pkt, 0); /* unknown 0x50 */ pkt_add32_le(pkt, 0); /* unknown 0x54 */ pkt_add32_le(pkt, 0); /* unknown 0x58 */ pkt_add32_le(pkt, 0); /* unknown 0x5C */ pkt_add32_le(pkt, 0); /* unknown 0x60 */ pkt_add32_le(pkt, 0); /* pps_ts1s 0x64 */ pkt_add32_le(pkt, 0); /* pps_ts1d 0x68 */ pkt_add32_le(pkt, 0); /* pps_ts2s 0x6C */ pkt_add32_le(pkt, 0); /* pps_ts2d 0x70 */ pkt_add32_le(pkt, pps_start); /* pps_start 0x74 */ pkt_add32_le(pkt, pps_size); /* pps_size 0x78 */ pkt_add32_le(pkt, 0); /* unknown 0x7C */ ow->io_handler.write(ow->io_handle,pkt->data, pkt->len); pkt_free(pkt); }
/* 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); }
/* 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; }
/* 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); }