+static int hostaccessvol(type, volname, args, obj)
+int type;
+char *volname;
+const char *args;
+const AFPObj *obj;
+{
+ char buf[MAXPATHLEN + 1], *p, *b;
+ DSI *dsi = obj->handle;
+
+ if (!args)
+ return -1;
+
+ strlcpy(buf, args, sizeof(buf));
+ if ((p = strtok_r(buf, ",", &b)) == NULL) /* nothing, return okay */
+ return -1;
+
+ while (p) {
+ if (obj->proto == AFPPROTO_DSI) {
+ struct in_addr mask, net;
+ char *net_char, *mask_char;
+ int mask_int;
+
+ net_char = strtok(p, "/");
+ mask_char = strtok(NULL,"/");
+ if (mask_char == NULL) {
+ mask_int = 32;
+ } else {
+ mask_int = atoi(mask_char);
+ }
+
+ // convert the integer netmask to a bitmask in network order
+ mask.s_addr = htonl(-1 - ((1 << (32 - mask_int)) - 1));
+ net.s_addr = inet_addr(net_char) & mask.s_addr;
+
+ if ((dsi->client.sin_addr.s_addr & mask.s_addr) == net.s_addr) {
+ if (type == VOLOPT_DENIED_HOSTS)
+ LOG(log_info, logtype_afpd, "AFP access denied for client IP '%s' to volume '%s' by denied list",
+ inet_ntoa(dsi->client.sin_addr), volname);
+ return 1;
+ }
+ }
+ p = strtok_r(NULL, ",", &b);
+ }
+ if (type == VOLOPT_ALLOWED_HOSTS)
+ LOG(log_info, logtype_afpd, "AFP access denied for client IP '%s' to volume '%s', not in allowed list",
+ inet_ntoa(dsi->client.sin_addr), volname);
+ return 0;
+}
+