aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/ppp/iplist.c
diff options
context:
space:
mode:
authorBrian Somers <brian@FreeBSD.org>1997-12-13 02:37:33 +0000
committerBrian Somers <brian@FreeBSD.org>1997-12-13 02:37:33 +0000
commitbcc332bdb0fffe5e7900c7e26954f062c95b0c23 (patch)
tree8c08cf70d8453da3f030ecdaafd1a8d430065d98 /usr.sbin/ppp/iplist.c
parent80db913bd66e53ac6d80b3958cc3aa09c6d72a6f (diff)
downloadsrc-bcc332bdb0fffe5e7900c7e26954f062c95b0c23.tar.gz
src-bcc332bdb0fffe5e7900c7e26954f062c95b0c23.zip
Allow random IP number allocation to peer.
Validate the peers suggested IP by attempting to make a routing table entry. Give up IPCP negotiation if the peer NAKs us with an unusable IP. Always SIOCDIFADDR then SIOCAIFADDR when configuring the tun device. Using SIOCSIFDSTADDR allows duplicate dst addresses (which we don't want)!!! Allow up to 200 interface names (was 50) (now that ppp can play server properly). Up the version number (1.5 -> 1.6). Cosmetic: Log unexpected CCP packets in the CCP log rather than the ERROR log. Log unexpected Config Reqs in the appropriate LCP/IPCP/CCP log rather than the ERROR log. Log failed route additions and deletions with WARN, not TCPIP. Log the option id and length for unrecognised IPCP options. Change some .Sq to .Ar in the man page.
Notes
Notes: svn path=/head/; revision=31690
Diffstat (limited to 'usr.sbin/ppp/iplist.c')
-rw-r--r--usr.sbin/ppp/iplist.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/usr.sbin/ppp/iplist.c b/usr.sbin/ppp/iplist.c
new file mode 100644
index 000000000000..dce202a5b987
--- /dev/null
+++ b/usr.sbin/ppp/iplist.c
@@ -0,0 +1,200 @@
+/*
+ * $Id:$
+ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "command.h"
+#include "mbuf.h"
+#include "log.h"
+#include "defs.h"
+#include "iplist.h"
+
+static int
+do_inet_aton(const char *start, const char *end, struct in_addr *ip)
+{
+ static char ipstr[16];
+
+ if (end - start > 15) {
+ LogPrintf(LogWARN, "%.*s: Invalid IP address\n", end-start, start);
+ return 0;
+ }
+ strncpy(ipstr, start, end-start);
+ ipstr[end-start] = '\0';
+ return inet_aton(ipstr, ip);
+}
+
+static void
+iplist_first(struct iplist *list)
+{
+ list->cur.pos = -1;
+}
+
+static int
+iplist_setrange(struct iplist *list, char *range)
+{
+ char *ptr, *to;
+
+ if ((ptr = strpbrk(range, ",-")) == NULL) {
+ if (!inet_aton(range, &list->cur.ip))
+ return 0;
+ list->cur.lstart = ntohl(list->cur.ip.s_addr);
+ list->cur.nItems = 1;
+ } else {
+ if (!do_inet_aton(range, ptr, &list->cur.ip))
+ return 0;
+ if (*ptr == ',') {
+ list->cur.lstart = ntohl(list->cur.ip.s_addr);
+ list->cur.nItems = 1;
+ } else {
+ struct in_addr endip;
+
+ to = ptr+1;
+ if ((ptr = strpbrk(to, ",-")) == NULL)
+ ptr = to + strlen(to);
+ if (*to == '-')
+ return 0;
+ if (!do_inet_aton(to, ptr, &endip))
+ return 0;
+ list->cur.lstart = ntohl(list->cur.ip.s_addr);
+ list->cur.nItems = ntohl(endip.s_addr) - list->cur.lstart + 1;
+ if (list->cur.nItems < 1)
+ return 0;
+ }
+ }
+ list->cur.srcitem = 0;
+ list->cur.srcptr = range;
+ return 1;
+}
+
+static int
+iplist_nextrange(struct iplist *list)
+{
+ char *ptr, *to, *end;
+
+ ptr = list->cur.srcptr;
+ if (ptr != NULL && (ptr = strchr(ptr, ',')) != NULL)
+ ptr++;
+ else
+ ptr = list->src;
+
+ while (*ptr != '\0' && !iplist_setrange(list, ptr)) {
+ if ((end = strchr(ptr, ',')) == NULL)
+ end = ptr + strlen(ptr);
+ if (end == ptr)
+ return 0;
+ LogPrintf(LogWARN, "%.*s: Invalid IP range (skipping)\n", end - ptr, ptr);
+ to = ptr;
+ do
+ *to = *end++;
+ while (*to++ != '\0');
+ if (*ptr == '\0')
+ ptr = list->src;
+ }
+
+ return 1;
+}
+
+struct in_addr
+iplist_next(struct iplist *list)
+{
+ if (list->cur.pos == -1) {
+ list->cur.srcptr = NULL;
+ if (!iplist_nextrange(list)) {
+ list->cur.ip.s_addr = INADDR_ANY;
+ return list->cur.ip;
+ }
+ } else if (++list->cur.srcitem == list->cur.nItems) {
+ if (!iplist_nextrange(list)) {
+ list->cur.ip.s_addr = INADDR_ANY;
+ list->cur.pos = -1;
+ return list->cur.ip;
+ }
+ } else
+ list->cur.ip.s_addr = htonl(list->cur.lstart + list->cur.srcitem);
+ list->cur.pos++;
+
+ return list->cur.ip;
+}
+
+int
+iplist_setsrc(struct iplist *list, const char *src)
+{
+ strncpy(list->src, src, sizeof(list->src));
+ list->src[sizeof(list->src)-1] = '\0';
+ list->cur.srcptr = list->src;
+ do {
+ if (iplist_nextrange(list))
+ list->nItems += list->cur.nItems;
+ else
+ return 0;
+ } while (list->cur.srcptr != list->src);
+ return 1;
+}
+
+void
+iplist_reset(struct iplist *list)
+{
+ list->src[0] = '\0';
+ list->nItems = 0;
+ list->cur.pos = -1;
+}
+
+struct in_addr
+iplist_setcurpos(struct iplist *list, int pos)
+{
+ if (pos < 0 || pos >= list->nItems) {
+ list->cur.pos = -1;
+ list->cur.ip.s_addr = INADDR_ANY;
+ return list->cur.ip;
+ }
+
+ list->cur.srcptr = NULL;
+ list->cur.pos = 0;
+ while (1) {
+ iplist_nextrange(list);
+ if (pos < list->cur.nItems) {
+ if (pos) {
+ list->cur.srcitem = pos;
+ list->cur.pos += pos;
+ list->cur.ip.s_addr = htonl(list->cur.lstart + list->cur.srcitem);
+ }
+ break;
+ }
+ pos -= list->cur.nItems;
+ list->cur.pos += list->cur.nItems;
+ }
+
+ return list->cur.ip;
+}
+
+struct in_addr
+iplist_setrandpos(struct iplist *list)
+{
+ randinit();
+ return iplist_setcurpos(list, random() % list->nItems);
+}
+
+int
+iplist_ip2pos(struct iplist *list, struct in_addr ip)
+{
+ struct iplist_cur cur;
+ int f, result;
+
+ result = -1;
+ memcpy(&cur, &list->cur, sizeof(cur));
+
+ for (iplist_first(list), f = 0; f < list->nItems; f++)
+ if (iplist_next(list).s_addr == ip.s_addr) {
+ result = list->cur.pos;
+ break;
+ }
+
+ memcpy(&list->cur, &cur, sizeof(list->cur));
+ return result;
+}