diff -Naur libreswan-3.15-orig/programs/addconn/addconn.c libreswan-3.15/programs/addconn/addconn.c
--- libreswan-3.15-orig/programs/addconn/addconn.c 2015-08-24 16:52:43.000000000 -0400
+++ libreswan-3.15/programs/addconn/addconn.c 2015-09-04 09:21:23.866861084 -0400
@@ -64,6 +64,8 @@
* If DST is not specified, full route table will be returned.
* 16kB was too small for biggish router, so do 32kB.
* TODO: This should be dynamic! Fix it in netlink_read_reply().
+ * Note: due to our hack to dodge a bug in NLMSG_OK,
+ * RTNL_BUFSIZE must be less than or equal to USHRT_MAX.
*/
#define RTNL_BUFSIZE 32768
@@ -139,30 +141,34 @@
static
ssize_t netlink_read_reply(int sock, char *buf, unsigned int seqnum, __u32 pid)
{
- struct nlmsghdr *nlhdr;
- struct sockaddr_nl sa;
- socklen_t salen = sizeof(sa);
- ssize_t readlen = 0;
ssize_t msglen = 0;
/* TODO: use dynamic buf */
- do {
+ for (;;) {
+ struct sockaddr_nl sa;
+ ssize_t readlen;
+
/* Read netlink message, verifying kernel origin. */
do {
+ socklen_t salen = sizeof(sa);
+
readlen = recvfrom(sock, buf, RTNL_BUFSIZE - msglen, 0,
(struct sockaddr *)&sa, &salen);
- if (readlen < 0)
+ if (readlen < 0 || salen != sizeof(sa))
return -1;
} while (sa.nl_pid != 0);
/* Verify it's valid */
- nlhdr = (struct nlmsghdr *) buf;
+ struct nlmsghdr *nlhdr = (struct nlmsghdr *) buf;
+
/*
- * CAST TO unsigned short IS TO AVOID netlink.h:NLMSG_OK error
- * which triggers a GCC warning in recent GCCs:
+ * The cast to unsigned short is to dodge an error in
+ * netlink.h:NLMSG_OK() which triggers a GCC warning in recent
+ * versions of GCC (2014 August):
* error: comparison between signed and unsigned integer expressions
+ * Note: as long as RTNL_BUFSIZE <= USHRT_MAX, this is safe.
*/
- if (NLMSG_OK(nlhdr, (unsigned short)readlen) == 0 ||
+ if (!NLMSG_OK(nlhdr, (unsigned short)readlen) ||
nlhdr->nlmsg_type == NLMSG_ERROR)
return -1;
@@ -174,11 +180,16 @@
buf += readlen;
msglen += readlen;
- /* All done if it's not a multi part */
+ /* all done if it's not a multi part */
if ((nlhdr->nlmsg_flags & NLM_F_MULTI) == 0)
break;
- } while (nlhdr->nlmsg_seq != seqnum ||
- nlhdr->nlmsg_pid != pid);
+
+ /* all done if this is the one we were searching for */
+ if (nlhdr->nlmsg_seq == seqnum &&
+ nlhdr->nlmsg_pid == pid)
+ break;
+ }
+
return msglen;
}
@@ -188,31 +199,33 @@
static
ssize_t netlink_query(char *msgbuf)
{
- struct nlmsghdr *nlmsg;
- int sock;
+ int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
- /* Create socket */
- if ((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) {
+ if (sock < 0) {
int e = errno;
- printf("create netlink socket: (%d: %s)", e, strerror(e));
+
+ printf("create netlink socket failure: (%d: %s)\n", e, strerror(e));
return -1;
}
/* Send request */
- nlmsg = (struct nlmsghdr *)msgbuf;
+ struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf;
+
if (send(sock, nlmsg, nlmsg->nlmsg_len, 0) < 0) {
int e = errno;
- printf("write netlink socket: (%d: %s)", e, strerror(e));
+
+ printf("write netlink socket failure: (%d: %s)\n", e, strerror(e));
return -1;
}
/* Read response */
+ errno = 0; /* in case failure does not set it */
ssize_t len = netlink_read_reply(sock, msgbuf, 1, getpid());
if (len < 0) {
int e = errno;
- printf("read netlink socket: (%d: %s)", e, strerror(e));
+ printf("read netlink socket failure: (%d: %s)\n", e, strerror(e));
return -1;
}
close(sock);
@@ -331,11 +344,9 @@
* 1) find out default gateway
* 2) find out src for that default gateway
*/
- if (!has_dst) {
- if (seeking_src && seeking_gateway) {
- seeking_src = FALSE;
- query_again = 1;
- }
+ if (!has_dst && seeking_src && seeking_gateway) {
+ seeking_src = FALSE;
+ query_again = 1;
}
if (seeking_gateway) {
struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf;
@@ -358,19 +369,17 @@
struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf;
/*
- * CAST TO unsigned short IS TO AVOID netlink.h:NLMSG_OK error
- * which triggers a GCC warning in recent GCCs:
+ * The cast to unsigned short is to dodge an error in
+ * netlink.h:NLMSG_OK() which triggers a GCC warning in recent
+ * versions of GCC (2014 August):
* error: comparison between signed and unsigned integer expressions
+ * Note: as long as RTNL_BUFSIZE <= USHRT_MAX, this is safe.
*/
- for (; NLMSG_OK(nlmsg, (unsigned short)len); nlmsg = NLMSG_NEXT(nlmsg, len)) {
- struct rtmsg *rtmsg;
- struct rtattr *rtattr;
- int rtlen;
+ for (; NLMSG_OK(nlmsg, (unsigned short)len); nlmsg = NLMSG_NEXT(nlmsg, len)) {
char r_interface[IF_NAMESIZE+1];
char r_source[ADDRTOT_BUF];
char r_gateway[ADDRTOT_BUF];
char r_destination[ADDRTOT_BUF];
- bool ignore;
if (nlmsg->nlmsg_type == NLMSG_DONE)
break;
@@ -378,23 +387,23 @@
if (nlmsg->nlmsg_type == NLMSG_ERROR) {
printf("netlink error\n");
return -1;
- break;
}
/* ignore all but IPv4 and IPv6 */
- rtmsg = (struct rtmsg *) NLMSG_DATA(nlmsg);
+ struct rtmsg *rtmsg = (struct rtmsg *) NLMSG_DATA(nlmsg);
+
if (rtmsg->rtm_family != AF_INET &&
rtmsg->rtm_family != AF_INET6)
continue;
/* Parse one route entry */
- r_interface[0] = r_interface[IF_NAMESIZE] = r_source[0] =
- r_gateway[0] = r_destination[0] = '\0';
- rtattr = (struct rtattr *) RTM_RTA(rtmsg);
- rtlen = RTM_PAYLOAD(nlmsg);
- for (;
- RTA_OK(rtattr, rtlen);
- rtattr = RTA_NEXT(rtattr, rtlen)) {
+ zero(&r_interface);
+ r_source[0] = r_gateway[0] = r_destination[0] = '\0';
+
+ struct rtattr *rtattr = (struct rtattr *) RTM_RTA(rtmsg);
+ int rtlen = RTM_PAYLOAD(nlmsg);
+
+ while (RTA_OK(rtattr, rtlen)) {
switch (rtattr->rta_type) {
case RTA_OIF:
if_indextoname(*(int *)RTA_DATA(rtattr),
@@ -417,13 +426,14 @@
sizeof(r_destination));
break;
}
+ rtattr = RTA_NEXT(rtattr, rtlen);
}
/*
* Ignore if not main table.
* Ignore ipsecX or mastX interfaces.
*/
- ignore = rtmsg->rtm_table != RT_TABLE_MAIN ||
+ bool ignore = rtmsg->rtm_table != RT_TABLE_MAIN ||
startswith(r_interface, "ipsec") ||
startswith(r_interface, "mast");
@@ -548,20 +558,23 @@
int main(int argc, char *argv[])
{
int opt = 0;
- int autoall = 0;
+ bool autoall = FALSE;
int configsetup = 0;
int checkconfig = 0;
- char *export = "export"; /* display export before the foo=bar or not */
- int listroute = 0, liststart = 0, listignore = 0, listadd = 0,
- listall = 0, dolist = 0, liststack = 0;
- struct starter_config *cfg = NULL;
- err_t err = NULL;
- char *confdir = NULL;
+ const char *export = "export"; /* display export before the foo=bar or not */
+ bool
+ dolist = FALSE,
+ listadd = FALSE,
+ listroute = FALSE,
+ liststart = FALSE,
+ listignore = FALSE,
+ listall = FALSE,
+ liststack = FALSE;
char *configfile = NULL;
- char *varprefix = "";
+ const char *varprefix = "";
int exit_status = 0;
struct starter_conn *conn = NULL;
- char *ctlbase = NULL;
+ const char *ctlbase = NULL;
bool resolvip = TRUE; /* default to looking up names */
#if 0
@@ -586,7 +599,7 @@
break;
case 'a':
- autoall = 1;
+ autoall = TRUE;
break;
case 'D':
@@ -595,11 +608,11 @@
break;
case 'T':
- configsetup++;
+ configsetup++; /* ??? is this not idempotent? */
break;
case 'K':
- checkconfig++;
+ checkconfig++; /* ??? is this not idempotent? */
break;
case 'N':
@@ -615,33 +628,33 @@
break;
case 'L':
- listadd = 1;
- dolist = 1;
+ listadd = TRUE;
+ dolist = TRUE;
break;
case 'r':
- listroute = 1;
- dolist = 1;
+ listroute = TRUE;
+ dolist = TRUE;
break;
case 's':
- liststart = 1;
- dolist = 1;
+ liststart = TRUE;
+ dolist = TRUE;
break;
case 'S':
- liststack = 1;
- dolist = 1;
+ liststack = TRUE;
+ dolist = TRUE;
break;
case 'i':
- listignore = 1;
- dolist = 1;
+ listignore = TRUE;
+ dolist = TRUE;
break;
case 'A':
- listall = 1;
- dolist = 1;
+ listall = TRUE;
+ dolist = TRUE;
break;
case 'P':
@@ -672,9 +685,7 @@
yydebug = 1;
}
- /* find config file */
- if (confdir == NULL)
- confdir = IPSEC_CONFDIR;
+ char *confdir = IPSEC_CONFDIR;
if (configfile == NULL) {
/* ??? see code clone in programs/readwriteconf/readwriteconf.c */
@@ -694,29 +705,32 @@
starter_use_log(verbose != 0, TRUE, verbose == 0);
- err = NULL; /* reset to no error */
-
if (configsetup || checkconfig || dolist) {
/* skip if we have no use for them... causes delays */
resolvip = FALSE;
}
- cfg = confread_load(configfile, &err, resolvip, ctlbase, configsetup);
+ struct starter_config *cfg = NULL;
- if (cfg == NULL) {
- fprintf(stderr, "cannot load config '%s': %s\n",
- configfile, err);
- exit(3);
- } else if (checkconfig) {
- confread_free(cfg);
- exit(0);
+ {
+ err_t err = NULL;
+
+ cfg = confread_load(configfile, &err, resolvip, ctlbase, configsetup);
+
+ if (cfg == NULL) {
+ fprintf(stderr, "cannot load config '%s': %s\n",
+ configfile, err);
+ exit(3);
+ } else if (checkconfig) {
+ confread_free(cfg);
+ exit(0);
+ }
}
if (autoall) {
if (verbose)
printf("loading all conns according to their auto= settings\n");
-
/*
* Load all conns marked as auto=add or better.
* First, do the auto=route and auto=add conns to quickly
@@ -727,7 +741,6 @@
if (verbose)
printf(" Pass #1: Loading auto=add, auto=route and auto=start connections\n");
-
for (conn = cfg->conns.tqh_first;
conn != NULL;
conn = conn->link.tqe_next) {
@@ -828,7 +841,6 @@
conn->
strings[KSF_CONNALIAS]
)) {
-
if (conn->state ==
STATE_ADDED) {
printf("\nalias: %s conn %s already added\n",
@@ -875,12 +887,10 @@
printf("%s ", conn->name);
printf("\n");
} else {
-
if (listadd) {
if (verbose)
printf("listing all conns marked as auto=add\n");
-
/* list all conns marked as auto=add */
for (conn = cfg->conns.tqh_first;
conn != NULL;
@@ -893,7 +903,6 @@
if (verbose)
printf("listing all conns marked as auto=route and auto=start\n");
-
/*
* list all conns marked as auto=route or start or
* better
@@ -911,7 +920,6 @@
if (verbose)
printf("listing all conns marked as auto=start\n");
-
/* list all conns marked as auto=start */
for (conn = cfg->conns.tqh_first;
conn != NULL;
@@ -925,7 +933,6 @@
if (verbose)
printf("listing all conns marked as auto=ignore\n");
-
/* list all conns marked as auto=start */
for (conn = cfg->conns.tqh_first;
conn != NULL;
@@ -942,14 +949,14 @@
for (kd = ipsec_conf_keywords_v2; kd->keyname != NULL; kd++) {
if (strstr(kd->keyname, "protostack")) {
- if (cfg->setup.strings[kd->field])
+ if (cfg->setup.strings[kd->field]) {
printf("%s\n",
cfg->setup.strings[kd->field]);
- else
+ } else {
/* implicit default */
printf("netkey\n");
+ }
}
-
}
confread_free(cfg);
exit(0);
@@ -1008,7 +1015,6 @@
}
confread_free(cfg);
exit(0);
-
}
confread_free(cfg);