-static struct IPv4NetworkSet *
-parse_ipv4_specification (const char *routeList)
-{
- unsigned int count;
- unsigned int i;
- unsigned int j;
- unsigned int len;
- int cnt;
- unsigned int pos;
- unsigned int temps[8];
- int slash;
- struct IPv4NetworkSet *result;
-
- if (routeList == NULL)
- return NULL;
- len = strlen (routeList);
- if (len == 0)
- return NULL;
- count = 0;
- for (i = 0; i < len; i++)
- if (routeList[i] == ';')
- count++;
- result = GNUNET_malloc (sizeof (struct IPv4NetworkSet) * (count + 1));
- /* add termination */
- memset (result, 0, sizeof (struct IPv4NetworkSet) * (count + 1));
- i = 0;
- pos = 0;
- while (i < count)
- {
- cnt =
- sscanf (&routeList[pos], "%u.%u.%u.%u/%u.%u.%u.%u;", &temps[0],
- &temps[1], &temps[2], &temps[3], &temps[4], &temps[5],
- &temps[6], &temps[7]);
- if (cnt == 8)
- {
- for (j = 0; j < 8; j++)
- if (temps[j] > 0xFF)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
- &routeList[pos]);
- GNUNET_free (result);
- return NULL;
- }
- result[i].network.s_addr =
- htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
- temps[3]);
- result[i].netmask.s_addr =
- htonl ((temps[4] << 24) + (temps[5] << 16) + (temps[6] << 8) +
- temps[7]);
- while (routeList[pos] != ';')
- pos++;
- pos++;
- i++;
- continue;
- }
- /* try second notation */
- cnt =
- sscanf (&routeList[pos], "%u.%u.%u.%u/%u;", &temps[0], &temps[1],
- &temps[2], &temps[3], &slash);
- if (cnt == 5)
- {
- for (j = 0; j < 4; j++)
- if (temps[j] > 0xFF)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
- &routeList[pos]);
- GNUNET_free (result);
- return NULL;
- }
- result[i].network.s_addr =
- htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
- temps[3]);
- if ((slash <= 32) && (slash >= 0))
- {
- result[i].netmask.s_addr = 0;
- while (slash > 0)
- {
- result[i].netmask.s_addr =
- (result[i].netmask.s_addr >> 1) + 0x80000000;
- slash--;
- }
- result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
- while (routeList[pos] != ';')
- pos++;
- pos++;
- i++;
- continue;
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _("Invalid network notation ('/%d' is not legal in IPv4 CIDR)."),
- slash);
- GNUNET_free (result);
- return NULL; /* error */
- }
- }
- /* try third notation */
- slash = 32;
- cnt =
- sscanf (&routeList[pos], "%u.%u.%u.%u;", &temps[0], &temps[1],
- &temps[2], &temps[3]);
- if (cnt == 4)
- {
- for (j = 0; j < 4; j++)
- if (temps[j] > 0xFF)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
- &routeList[pos]);
- GNUNET_free (result);
- return NULL;
- }
- result[i].network.s_addr =
- htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
- temps[3]);
- result[i].netmask.s_addr = 0;
- while (slash > 0)
- {
- result[i].netmask.s_addr = (result[i].netmask.s_addr >> 1) + 0x80000000;
- slash--;
- }
- result[i].netmask.s_addr = htonl (result[i].netmask.s_addr);
- while (routeList[pos] != ';')
- pos++;
- pos++;
- i++;
- continue;
- }
- LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
- &routeList[pos]);
- GNUNET_free (result);
- return NULL; /* error */
- }
- if (pos < strlen (routeList))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _("Invalid format for IP: `%s'\n"),
- &routeList[pos]);
- GNUNET_free (result);
- return NULL; /* oops */
- }
- return result; /* ok */
-}
-