summaryrefslogtreecommitdiffstats
path: root/main/ipsec-tools/80-admin-big-reply-fix.patch
blob: d3e4b5d570dc625e488ab849ca1c861aff2b2854 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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;