/*! \brief * Calculate the length of buffer needed to * print contacts */ static inline unsigned int calc_buf_len(impurecord_t* impurec) { unsigned int len; int qlen; int i=0; ucontact_t* c; len = 0; while (i<MAX_CONTACTS_PER_IMPU && (c=impurec->newcontacts[i])) { if (VALID_CONTACT(c, act_time)) { if (len) len += CONTACT_SEP_LEN; len += 2 /* < > */ + c->c.len; qlen = len_q(c->q); if (qlen) len += Q_PARAM_LEN + qlen; len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN; if (c->received.s) { len += 1 /* ; */ + rcv_param.len + 1 /* = */ + 1 /* dquote */ + c->received.len + 1 /* dquote */ ; } } i++; } if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN; return len; }
/*! \brief * Calculate the length of buffer needed to * print contacts */ static inline unsigned int calc_buf_len(ucontact_t* c) { unsigned int len; int qlen; len = 0; while(c) { if (VALID_CONTACT(c, act_time)) { if (len) len += CONTACT_SEP_LEN; len += 2 /* < > */ + c->c.len; qlen = len_q(c->q); if (qlen) len += Q_PARAM_LEN + qlen; len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN; if (c->received.s) { len += 1 /* ; */ + rcv_param.len + 1 /* = */ + 1 /* dquote */ + c->received.len + 1 /* dquote */ ; } } c = c->next; } if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN; return len; }
/* Execute random quench algorithm on an interface's output queue */ void rquench( struct iface *ifp, int drop ){ struct mbuf *bp,*bplast; int i; struct qhdr qhdr; struct ip ip; struct mbuf *bpdup; if((i = len_q(ifp->outq)) == 0) return; /* Queue is empty */ i = urandom(i); /* Select a victim */ /* Search for i-th message on queue */ bplast = NULL; for(bp = ifp->outq;bp != NULL && i>0;i--,bplast=bp,bp=bp->anext) ; if(bp == NULL) return; /* "Can't happen" */ /* Send a source quench */ dup_p(&bpdup,bp,0,len_p(bp)); pullup(&bpdup,&qhdr,sizeof(qhdr)); ntohip(&ip,&bpdup); icmp_output(&ip,bpdup,ICMP_QUENCH,0,NULL); free_p(&bpdup); if(!drop) return; /* All done */ /* Drop the packet */ if(bplast != NULL) bplast->anext = bp->anext; else ifp->outq = bp->anext; /* First on list */ free_p(&bp); }
/* Dump ARP table */ static void dumparp(void) { int i; struct arp_tab *ap; char e[128]; arp_loadfile(); printf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n", Arp_stat.recv,Arp_stat.badtype,Arp_stat.badaddr,Arp_stat.inreq, Arp_stat.replies,Arp_stat.outreq); printf("IP addr Type Time Q Addr\n"); for(i=0;i<HASHMOD;i++){ for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next){ printf("%-18.18s ",inet_ntoa(ap->ip_addr)); printf("%-15s",smsg(Arptypes,NHWTYPES,ap->hardware)); printf("%7ld ",read_timer(&ap->timer)/1000L); if(ap->state == ARP_PENDING) printf("%-2u",len_q(ap->pending)); else printf(" "); if(ap->state == ARP_VALID){ if(Arp_type[ap->hardware].format != NULL){ (*Arp_type[ap->hardware].format)(e,ap->hw_addr); } else { e[0] = '\0'; } printf("%s",e); } else { printf("[unknown]"); } if(ap->pub) printf(" (published)"); printf("\n"); } } }
/*! \brief * Calculate the length of buffer needed to * print contacts * - mode specifies if GRUU header params are added */ static inline unsigned int calc_buf_len(ucontact_t* c, str *host, int mode) { unsigned int len; int qlen; len = 0; while(c) { if (VALID_CONTACT(c, act_time)) { if (len) len += CONTACT_SEP_LEN; len += 2 /* < > */ + c->c.len; qlen = len_q(c->q); if (qlen) len += Q_PARAM_LEN + qlen; len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN; if (rcv_param.len>0 && c->received.s) { len += 1 /* ; */ + rcv_param.len + 1 /* = */ + 1 /* dquote */ + c->received.len + 1 /* dquote */ ; } if (reg_gruu_enabled==1 && c->instance.len>0 && mode==1) { /* pub-gruu */ len += PUB_GRUU_PARAM_LEN + 1 /* " */ + 4 /* sip: */ + c->aor->len + 1 /* @ */ + host->len + GR_PARAM_LEN + c->instance.len + 1 /* " */ ; /* temp-gruu */ len += TMP_GRUU_PARAM_LEN + 1 /* " */ + 4 /* sip: */ + c->ruid.len + 1 /* 'sep' */ + 8 /* max hex int */ + 1 /* @ */ + host->len + GR_PARAM_LEN - 1 /* = */ + 1 /* " */ ; } if (c->instance.len>0) { /* +sip-instance */ len += SIP_INSTANCE_PARAM_LEN + 1 /* " */ + c->instance.len + 1 /* " */ ; } if (c->reg_id>0) { /* reg-id */ len += REG_ID_PARAM_LEN + INT2STR_MAX_LEN; } } c = c->next; } if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN; return len; }
/*! \brief * Allocate a memory buffer and print Contact * header fields into it */ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host) { char *p, *cp; char *a; int fl, len; str user; str inst; unsigned int ahash; unsigned short digit; int mode; sr_xavp_t *xavp=NULL; sr_xavp_t *list=NULL; str xname = {"ruid", 4}; sr_xval_t xval; if(msg!=NULL && parse_supported(msg)==0 && (get_supported(msg) & F_OPTION_TAG_GRUU)) mode = 1; else mode = 0; contact.data_len = calc_buf_len(c, host, mode); if (!contact.data_len) return 0; if (!contact.buf || (contact.buf_len < contact.data_len)) { if (contact.buf) pkg_free(contact.buf); contact.buf = (char*)pkg_malloc(contact.data_len); if (!contact.buf) { contact.data_len = 0; contact.buf_len = 0; LM_ERR("no pkg memory left\n"); return -1; } else { contact.buf_len = contact.data_len; } } p = contact.buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; /* add xavp with details of the record (ruid, ...) */ if(reg_xavp_rcd.s!=NULL) { list = xavp_get(®_xavp_rcd, NULL); xavp = list; } fl = 0; while(c) { if (VALID_CONTACT(c, act_time)) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int)(c->expires - act_time), &len); memcpy(p, cp, len); p += len; if (rcv_param.len>0 && c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } if (reg_gruu_enabled==1 && c->instance.len>0 && mode==1) { user.s = c->aor->s; a = memchr(c->aor->s, '@', c->aor->len); if(a!=NULL) { user.len = a - user.s; } else { user.len = c->aor->len; } /* pub-gruu */ memcpy(p, PUB_GRUU_PARAM, PUB_GRUU_PARAM_LEN); p += PUB_GRUU_PARAM_LEN; *p++ = '\"'; memcpy(p, "sip:", 4); p += 4; if(a!=NULL) { memcpy(p, c->aor->s, c->aor->len); p += c->aor->len; } else { memcpy(p, user.s, user.len); p += user.len; *p++ = '@'; memcpy(p, host->s, host->len); p += host->len; } memcpy(p, GR_PARAM, GR_PARAM_LEN); p += GR_PARAM_LEN; inst = c->instance; if(inst.s[0]=='<' && inst.s[inst.len-1]=='>') { inst.s++; inst.len -= 2; } memcpy(p, inst.s, inst.len); p += inst.len; *p++ = '\"'; /* temp-gruu */ memcpy(p, TMP_GRUU_PARAM, TMP_GRUU_PARAM_LEN); p += TMP_GRUU_PARAM_LEN; *p++ = '\"'; memcpy(p, "sip:", 4); p += 4; memcpy(p, c->ruid.s, c->ruid.len); p += c->ruid.len; *p++ = '-'; ahash = ul.get_aorhash(c->aor); while(ahash!=0) { digit = ahash & 0x0f; *p++ = (digit >= 10) ? digit + 'a' - 10 : digit + '0'; ahash >>= 4; } *p++ = '@'; memcpy(p, host->s, host->len); p += host->len; memcpy(p, GR_PARAM, GR_PARAM_LEN); p += GR_PARAM_LEN - 1; *p++ = '\"'; } if (c->instance.len>0) { /* +sip-instance */ memcpy(p, SIP_INSTANCE_PARAM, SIP_INSTANCE_PARAM_LEN); p += SIP_INSTANCE_PARAM_LEN; *p++ = '\"'; memcpy(p, c->instance.s, c->instance.len); p += c->instance.len; *p++ = '\"'; } if (c->reg_id>0) { /* reg-id */ memcpy(p, REG_ID_PARAM, REG_ID_PARAM_LEN); p += REG_ID_PARAM_LEN; cp = int2str(c->reg_id, &len); memcpy(p, cp, len); p += len; } if(reg_xavp_rcd.s!=NULL) { memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_STR; xval.v.s = c->ruid; if(xavp_add_value(&xname, &xval, &xavp)==NULL) { LM_ERR("cannot add ruid value to xavp\n"); } } } c = c->next; }
/* * Create a Contact header field from the dset * array */ char* print_dset(struct sip_msg* msg, int* len) { int cnt, i; unsigned int qlen; qvalue_t q; str uri; char* p, *qbuf; static char dset[MAX_REDIRECTION_LEN]; if (msg->new_uri.s) { cnt = 1; *len = msg->new_uri.len; if (ruri_q != Q_UNSPECIFIED) { *len += 1 + Q_PARAM_LEN + len_q(ruri_q); } } else { cnt = 0; *len = 0; } init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) { cnt++; *len += uri.len; if (q != Q_UNSPECIFIED) { *len += 1 + Q_PARAM_LEN + len_q(q); } } if (cnt == 0) return 0; *len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN; if (*len + 1 > MAX_REDIRECTION_LEN) { LOG(L_ERR, "ERROR: redirection buffer length exceed\n"); return 0; } memcpy(dset, CONTACT, CONTACT_LEN); p = dset + CONTACT_LEN; if (msg->new_uri.s) { if (ruri_q != Q_UNSPECIFIED) { *p++ = '<'; } memcpy(p, msg->new_uri.s, msg->new_uri.len); p += msg->new_uri.len; if (ruri_q != Q_UNSPECIFIED) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; qbuf = q2str(ruri_q, &qlen); memcpy(p, qbuf, qlen); p += qlen; } i = 1; } else { i = 0; } init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0, 0))) { if (i) { memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN); p += CONTACT_DELIM_LEN; } if (q != Q_UNSPECIFIED) { *p++ = '<'; } memcpy(p, uri.s, uri.len); p += uri.len; if (q != Q_UNSPECIFIED) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; qbuf = q2str(q, &qlen); memcpy(p, qbuf, qlen); p += qlen; } i++; } memcpy(p, CRLF " ", CRLF_LEN + 1); return dset; }
/*! \brief * Allocate a memory buffer and print Contact * header fields into it */ int build_contact(ucontact_t* c) { char *p, *cp; int fl, len; contact.data_len = calc_buf_len(c); if (!contact.data_len) return 0; if (!contact.buf || (contact.buf_len < contact.data_len)) { if (contact.buf) pkg_free(contact.buf); contact.buf = (char*)pkg_malloc(contact.data_len); if (!contact.buf) { contact.data_len = 0; contact.buf_len = 0; LM_ERR("no pkg memory left\n"); return -1; } else { contact.buf_len = contact.data_len; } } p = contact.buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; fl = 0; while(c) { if (VALID_CONTACT(c, act_time)) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int)(c->expires - act_time), &len); memcpy(p, cp, len); p += len; if (c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } } c = c->next; } memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN; contact.data_len = p - contact.buf; LM_DBG("created Contact HF: %.*s\n", contact.data_len, contact.buf); return 0; }
int build_contact(ucontact_t* c, contact_for_header_t** contact_header) { char *p, *cp; int fl, len; *contact_header = 0; contact_for_header_t* tmp_contact_header = shm_malloc(sizeof (contact_for_header_t)); if (!tmp_contact_header) { LM_ERR("no more memory\n"); return -1; } memset(tmp_contact_header, 0, sizeof (contact_for_header_t)); tmp_contact_header->data_len = calc_buf_len(c); tmp_contact_header->buf = (char*)shm_malloc(tmp_contact_header->data_len); p = tmp_contact_header->buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; fl = 0; while (c) { if (VALID_CONTACT(c, act_time)) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int) (c->expires - act_time), &len); memcpy(p, cp, len); p += len; if (c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } } c = c->next; } memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN; tmp_contact_header->data_len = p - tmp_contact_header->buf; LM_DBG("created Contact HF: %.*s\n", tmp_contact_header->data_len, tmp_contact_header->buf); *contact_header = tmp_contact_header; return 0; }
static int xl_get_branches(struct sip_msg *msg, str *res, str *hp, int hi, int hf) { str uri; qvalue_t q; int len, cnt, i; unsigned int qlen; char *p, *qbuf; if(msg==NULL || res==NULL) return -1; if(msg->first_line.type == SIP_REPLY) return xl_get_null(msg, res, hp, hi, hf); cnt = len = 0; init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) { cnt++; len += uri.len; if (q != Q_UNSPECIFIED) { len += 1 + Q_PARAM_LEN + len_q(q); } } if (cnt == 0) return xl_get_empty(msg, res, hp, hi, hf); len += (cnt - 1) * XLOG_FIELD_DELIM_LEN; if (len + 1 > LOCAL_BUF_SIZE) { LOG(L_ERR, "ERROR:xl_get_branches: local buffer length exceeded\n"); return xl_get_null(msg, res, hp, hi, hf); } i = 0; p = local_buf; init_branch_iterator(); while ((uri.s = next_branch(&uri.len, &q, 0, 0, 0))) { if (i) { memcpy(p, XLOG_FIELD_DELIM, XLOG_FIELD_DELIM_LEN); p += XLOG_FIELD_DELIM_LEN; } if (q != Q_UNSPECIFIED) { *p++ = '<'; } memcpy(p, uri.s, uri.len); p += uri.len; if (q != Q_UNSPECIFIED) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; qbuf = q2str(q, &qlen); memcpy(p, qbuf, qlen); p += qlen; } i++; } res->s = &(local_buf[0]); res->len = len; return 0; }
/*! \brief * Allocate a memory buffer and print Contact * header fields into it */ int build_contact(ucontact_t* c,struct sip_msg *_m) { char *p, *cp, *tmpgr; int fl, len,grlen; int build_gruu = 0; struct socket_info *sock; if (!disable_gruu && _m->supported && parse_supported(_m) == 0 && (get_supported(_m) & F_SUPPORTED_GRUU)) build_gruu=1; contact.data_len = calc_buf_len(c,build_gruu,_m); if (!contact.data_len) return 0; if (!contact.buf || (contact.buf_len < contact.data_len)) { if (contact.buf) pkg_free(contact.buf); contact.buf = (char*)pkg_malloc(contact.data_len); if (!contact.buf) { contact.data_len = 0; contact.buf_len = 0; LM_ERR("no pkg memory left\n"); return -1; } else { contact.buf_len = contact.data_len; } } p = contact.buf; memcpy(p, CONTACT_BEGIN, CONTACT_BEGIN_LEN); p += CONTACT_BEGIN_LEN; fl = 0; while(c) { if (VALID_CONTACT(c, get_act_time())) { if (fl) { memcpy(p, CONTACT_SEP, CONTACT_SEP_LEN); p += CONTACT_SEP_LEN; } else { fl = 1; } *p++ = '<'; memcpy(p, c->c.s, c->c.len); p += c->c.len; *p++ = '>'; len = len_q(c->q); if (len) { memcpy(p, Q_PARAM, Q_PARAM_LEN); p += Q_PARAM_LEN; memcpy(p, q2str(c->q, 0), len); p += len; } memcpy(p, EXPIRES_PARAM, EXPIRES_PARAM_LEN); p += EXPIRES_PARAM_LEN; cp = int2str((int)(c->expires - get_act_time()), &len); memcpy(p, cp, len); p += len; if (c->received.s) { *p++ = ';'; memcpy(p, rcv_param.s, rcv_param.len); p += rcv_param.len; *p++ = '='; *p++ = '\"'; memcpy(p, c->received.s, c->received.len); p += c->received.len; *p++ = '\"'; } if (build_gruu && c->instance.s) { sock = (c->sock)?(c->sock):(_m->rcv.bind_address); /* build pub GRUU */ memcpy(p,PUB_GRUU,PUB_GRUU_SIZE); p += PUB_GRUU_SIZE; *p++ = '\"'; memcpy(p,SIP_PROTO,SIP_PROTO_SIZE); p += SIP_PROTO_SIZE; memcpy(p,c->aor->s,c->aor->len); p += c->aor->len; if (!reg_use_domain) { *p++ = '@'; memcpy(p,sock->name.s,sock->name.len); p += sock->name.len; *p++ = ':'; memcpy(p,sock->port_no_str.s,sock->port_no_str.len); p += sock->port_no_str.len; } memcpy(p,GR_PARAM,GR_PARAM_SIZE); p += GR_PARAM_SIZE; memcpy(p,c->instance.s+1,c->instance.len-2); p += c->instance.len-2; *p++ = '\"'; /* build temp GRUU */ memcpy(p,TEMP_GRUU,TEMP_GRUU_SIZE); p += TEMP_GRUU_SIZE; *p++ = '\"'; memcpy(p,SIP_PROTO,SIP_PROTO_SIZE); p += SIP_PROTO_SIZE; memcpy(p,TEMP_GRUU_HEADER,TEMP_GRUU_HEADER_SIZE); p += TEMP_GRUU_HEADER_SIZE; tmpgr = build_temp_gruu(c->aor,&c->instance,&c->callid,&grlen); base64encode((unsigned char *)p, (unsigned char *)tmpgr,grlen); p += calc_temp_gruu_len(c->aor,&c->instance,&c->callid); *p++ = '@'; memcpy(p,sock->name.s,sock->name.len); p += sock->name.len; *p++ = ':'; memcpy(p,sock->port_no_str.s,sock->port_no_str.len); p += sock->port_no_str.len; memcpy(p,GR_NO_VAL,GR_NO_VAL_SIZE); p += GR_NO_VAL_SIZE; *p++ = '\"'; /* build +sip.instance */ memcpy(p,SIP_INSTANCE,SIP_INSTANCE_SIZE); p += SIP_INSTANCE_SIZE; *p++ = '\"'; memcpy(p,c->instance.s+1,c->instance.len-2); p += c->instance.len-2; *p++ = '\"'; } } c = c->next; } memcpy(p, CRLF, CRLF_LEN); p += CRLF_LEN; contact.data_len = p - contact.buf; LM_DBG("created Contact HF: %.*s\n", contact.data_len, contact.buf); return 0; }
/*! \brief * Calculate the length of buffer needed to * print contacts */ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, struct sip_msg *_m) { unsigned int len; int qlen; struct socket_info *sock; len = 0; while(c) { if (VALID_CONTACT(c, get_act_time())) { if (len) len += CONTACT_SEP_LEN; len += 2 /* < > */ + c->c.len; qlen = len_q(c->q); if (qlen) len += Q_PARAM_LEN + qlen; len += EXPIRES_PARAM_LEN + INT2STR_MAX_LEN; if (c->received.s) { len += 1 /* ; */ + rcv_param.len + 1 /* = */ + 1 /* dquote */ + c->received.len + 1 /* dquote */ ; } if (build_gruu && c->instance.s) { sock = (c->sock)?(c->sock):(_m->rcv.bind_address); /* pub gruu */ len += PUB_GRUU_SIZE + 1 /* quote */ + SIP_PROTO_SIZE + c->aor->len + (reg_use_domain ?0:(1 /* @ */ + sock->name.len + 1 /* : */ + sock->port_no_str.len)) + GR_PARAM_SIZE + (c->instance.len - 2) + 1 /* quote */ ; /* temp gruu */ len += TEMP_GRUU_SIZE + 1 /* quote */ + SIP_PROTO_SIZE + TEMP_GRUU_HEADER_SIZE + calc_temp_gruu_len(c->aor,&c->instance,&c->callid) + 1 /* @ */ + sock->name.len + 1 /* : */ + sock->port_no_str.len + GR_NO_VAL_SIZE + 1 /* quote */ ; /* sip.instance */ len += SIP_INSTANCE_SIZE + 1 /* quote */ + (c->instance.len - 2) + 1 /* quote */ ; } } c = c->next; } if (len) len += CONTACT_BEGIN_LEN + CRLF_LEN; return len; }