/* build an ID payload * Note: no memory is allocated for the body of the payload (tl->ptr). * We assume it will end up being a pointer into a sufficiently * stable datastructure. It only needs to last a short time. */ void build_id_payload(struct isakmp_ipsec_id *hd, chunk_t *tl, struct end *end) { const struct id *id = resolve_myid(&end->id); zero(hd); zero(tl); hd->isaiid_idtype = id->kind; switch (id->kind) { case ID_NONE: hd->isaiid_idtype = aftoinfo(addrtypeof(&end->host_addr))->id_addr; tl->len = addrbytesptr(&end->host_addr, &tl->ptr); /* sets tl->ptr too */ break; case ID_FQDN: case ID_USER_FQDN: case ID_DER_ASN1_DN: case ID_KEY_ID: *tl = id->name; break; case ID_IPV4_ADDR: case ID_IPV6_ADDR: tl->len = addrbytesptr(&id->ip_addr, &tl->ptr); /* sets tl->ptr too */ break; case ID_NULL: tl->len = 0; tl->ptr = NULL; break; default: bad_case(id->kind); } }
int ikev2_calc_iprangediff(ip_address low, ip_address high) { unsigned const char *hp; unsigned const char *lp, *t; unsigned char *dp; ip_address diff; size_t n; size_t n2; int i; int carry = 0; /* initialize all the contents to sensible values */ diff = low; if (addrtypeof(&high) != addrtypeof(&low)) return -1; n = addrbytesptr(&high, &hp); if (n == 0) return -1; n2 = addrbytesptr(&low, &lp); if (n != n2) return -1; addrbytesptr_write(&diff, &dp); for(i=0; i<n; i++) { if(hp[i]==lp[i]) { dp[i]=0; continue; } break; } /* two values are the same -- no diff */ if(i==n) return 0; if(hp[i] < lp[i]) { /* need to swap! */ t=hp; hp=lp; lp=t; } for(i=n-1; i>=0; i--) { int val=hp[i]-lp[i]-carry; if(val < 0) { val += 256; carry=1; } else { carry=0; } dp[i]=val; } return ikev2_highorder_zerobits(diff); }
/* * this is stupid implementation, see goodmask.c for ideas * on doing it better, but note that this counts zero bits, not * 1 bits, and it doesn't assume that the mask is properly formed. * */ int ikev2_highorder_zerobits(ip_address b) { unsigned const char *bp; int i, j; u_int32_t mask; size_t n; int zerobits = 0; n = addrbytesptr(&b, &bp); if (n == 0) return -1; zerobits = 0; for(j=0; j<n; j++) { mask = 1UL << 7; if(*bp) { for(i=0; i<8; i++) { if(*bp & mask) return ((8*n)-(zerobits+i)); mask >>= 1; } } bp++; zerobits += 8; } return 0; }
/***************************************************************** *函数名称:addrtot *功能 :2 进制地址转换成字符型 * addrtot - convert binary address to text * (dotted decimal or IPv6 string) * ******************************************************************* * * * ******************************************************************/ size_t addrtot(const ip_address *src, int format, char *dst, size_t dstlen) { const unsigned char *b; size_t n; char buf[1+ADDRTOT_BUF+1]; /* :address: */ char *p; int t = addrtypeof(src); #define TF(t, f) (((t)<<8) | (f)) n = addrbytesptr(src, &b); if (n == 0) { bad: dst[0]='\0'; strncat(dst, "invalid", dstlen); return sizeof("invalid"); } switch (TF(t, format)) { case TF(AF_INET, 0): n = normal4(b, n, buf, &p); break; case TF(AF_INET6, 0): n = normal6(b, n, buf, &p, 1); break; case TF(AF_INET, 'Q'): n = normal4(b, n, buf, &p); break; case TF(AF_INET6, 'Q'): n = normal6(b, n, buf, &p, 0); break; case TF(AF_INET, 'r'): n = reverse4(b, n, buf, &p); break; case TF(AF_INET6, 'r'): n = reverse6(b, n, buf, &p); break; default: /* including (AF_INET, 'R') */ goto bad; break; } if (dstlen > 0) { if (dstlen < n) p[dstlen - 1] = '\0'; strcpy(dst, p); } return n; }