Index: src/racoon/admin.c =================================================================== RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/admin.c,v retrieving revision 1.35 diff -u -r1.35 admin.c --- a/src/racoon/admin.c 21 Oct 2010 06:15:28 -0000 1.35 +++ b/src/racoon/admin.c 29 Oct 2010 10:51:28 -0000 @@ -638,9 +638,15 @@ } combuf = (struct admin_com *) retbuf; - combuf->ac_len = tlen; + combuf->ac_len = (u_int16_t) tlen; combuf->ac_cmd = req->ac_cmd & ~ADMIN_FLAG_VERSION; - combuf->ac_errno = l_ac_errno; + if (tlen != (u_int32_t) combuf->ac_len && + l_ac_errno == 0) { + combuf->ac_len_high = tlen >> 16; + combuf->ac_cmd |= ADMIN_FLAG_LONG_REPLY; + } else { + combuf->ac_errno = l_ac_errno; + } combuf->ac_proto = req->ac_proto; if (buf != NULL) Index: src/racoon/admin.h =================================================================== RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/admin.h,v retrieving revision 1.7 diff -u -r1.7 admin.h --- a/src/racoon/admin.h 29 Aug 2008 00:30:15 -0000 1.7 +++ b/src/racoon/admin.h 29 Oct 2010 10:51:28 -0000 @@ -49,16 +49,19 @@ union { int16_t ac_un_errno; uint16_t ac_un_version; + uint16_t ac_un_len_high; } u; u_int16_t ac_proto; }; #define ac_errno u.ac_un_errno #define ac_version u.ac_un_version +#define ac_len_high u.ac_un_len_high /* * Version field in request is valid. */ #define ADMIN_FLAG_VERSION 0x8000 +#define ADMIN_FLAG_LONG_REPLY 0x8000 /* * No data follows as the data. Index: src/racoon/kmpstat.c =================================================================== RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/kmpstat.c,v retrieving revision 1.6 diff -u -r1.6 kmpstat.c --- a/src/racoon/kmpstat.c 2 Oct 2007 09:47:45 -0000 1.6 +++ b/src/racoon/kmpstat.c 29 Oct 2010 10:51:29 -0000 @@ -138,7 +138,7 @@ { struct admin_com h, *com; caddr_t buf; - int len; + int len, rlen; int l = 0; caddr_t p; @@ -153,19 +153,25 @@ if (len < sizeof(h)) goto bad1; - if (h.ac_errno) { + if (h.ac_errno && !(h.ac_cmd & ADMIN_FLAG_LONG_REPLY)) { errno = h.ac_errno; goto bad1; } + /* real length */ + if (h.ac_cmd & ADMIN_FLAG_LONG_REPLY) + rlen = ((u_int32_t)h.ac_len) + (((u_int32_t)h.ac_len_high) << 16); + else + rlen = h.ac_len; + /* allocate buffer */ - if ((*combufp = vmalloc(h.ac_len)) == NULL) + if ((*combufp = vmalloc(rlen)) == NULL) goto bad1; /* read real message */ p = (*combufp)->v; - while (l < len) { - if ((len = recv(so, p, h.ac_len, 0)) < 0) { + while (l < rlen) { + if ((len = recv(so, p, rlen - l, 0)) < 0) { perror("recv"); goto bad2; } Index: src/racoon/racoonctl.c =================================================================== RCS file: /cvsroot/src/crypto/dist/ipsec-tools/src/racoon/racoonctl.c,v retrieving revision 1.17 diff -u -r1.17 racoonctl.c --- a/src/racoon/racoonctl.c 20 Apr 2009 13:22:00 -0000 1.17 +++ b/src/racoon/racoonctl.c 29 Oct 2010 10:51:29 -0000 @@ -1426,10 +1426,14 @@ int len; com = (struct admin_com *)combuf->v; - len = com->ac_len - sizeof(*com); + if (com->ac_cmd & ADMIN_FLAG_LONG_REPLY) + len = ((u_int32_t)com->ac_len) + (((u_int32_t)com->ac_len_high) << 16); + else + len = com->ac_len; + len -= sizeof(*com); buf = combuf->v + sizeof(*com); - switch (com->ac_cmd) { + switch (com->ac_cmd & ~ADMIN_FLAG_LONG_REPLY) { case ADMIN_SHOW_SCHED: print_schedule(buf, len); break;