]> The Tcpdump Group git mirrors - libpcap/commitdiff
Move URL parsing and construction to pcap.c.
authorGuy Harris <[email protected]>
Mon, 4 Sep 2017 18:51:23 +0000 (11:51 -0700)
committerGuy Harris <[email protected]>
Mon, 4 Sep 2017 18:51:23 +0000 (11:51 -0700)
Eventually, there will be new APIs allowing opening of remote interfaces
in a create/activate style; they will do URL parsing and will be in
pcap.c.  This is part of that, as well as part of a shorter-term project
to replace pcap_parsesrcstr()'s sscanf-based URL parsing with something
not using sscanf(), because we want to avoid MSVC complaints about
sscanf's insecurity without just replacing sscanf with sscanf_s(), as
their APIs are not the same.

pcap-new.c
pcap.c

index 5625317a526c136374107c91f92d35616bbcf4b1..d8fcd69343d1d9699a12f2751e0689c9f02ccbed 100644 (file)
@@ -321,231 +321,6 @@ int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **all
        }
 }
 
-int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf)
-{
-       switch (type)
-       {
-       case PCAP_SRC_FILE:
-       {
-               strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
-               if ((name) && (*name))
-               {
-                       strlcat(source, name, PCAP_BUF_SIZE);
-                       return 0;
-               }
-               else
-               {
-                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name cannot be NULL.");
-                       return -1;
-               }
-       }
-
-       case PCAP_SRC_IFREMOTE:
-       {
-               strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
-               if ((host) && (*host))
-               {
-                       if ((strcspn(host, "aAbBcCdDeEfFgGhHjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ")) == strlen(host))
-                       {
-                               /* the host name does not contains alphabetic chars. So, it is a numeric address */
-                               /* In this case we have to include it between square brackets */
-                               strlcat(source, "[", PCAP_BUF_SIZE);
-                               strlcat(source, host, PCAP_BUF_SIZE);
-                               strlcat(source, "]", PCAP_BUF_SIZE);
-                       }
-                       else
-                               strlcat(source, host, PCAP_BUF_SIZE);
-
-                       if ((port) && (*port))
-                       {
-                               strlcat(source, ":", PCAP_BUF_SIZE);
-                               strlcat(source, port, PCAP_BUF_SIZE);
-                       }
-
-                       strlcat(source, "/", PCAP_BUF_SIZE);
-               }
-               else
-               {
-                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host name cannot be NULL.");
-                       return -1;
-               }
-
-               if ((name) && (*name))
-                       strlcat(source, name, PCAP_BUF_SIZE);
-
-               return 0;
-       }
-
-       case PCAP_SRC_IFLOCAL:
-       {
-               strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
-
-               if ((name) && (*name))
-                       strlcat(source, name, PCAP_BUF_SIZE);
-
-               return 0;
-       }
-
-       default:
-       {
-               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface type is not valid.");
-               return -1;
-       }
-       }
-}
-
-int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf)
-{
-       char *ptr;
-       int ntoken;
-       char tmpname[PCAP_BUF_SIZE];
-       char tmphost[PCAP_BUF_SIZE];
-       char tmpport[PCAP_BUF_SIZE];
-       int tmptype;
-
-       /* Initialization stuff */
-       tmpname[0] = 0;
-       tmphost[0] = 0;
-       tmpport[0] = 0;
-
-       if (host)
-               *host = 0;
-       if (port)
-               *port = 0;
-       if (name)
-               *name = 0;
-
-       /* Look for a 'rpcap://' identifier */
-       if ((ptr = strstr(source, PCAP_SRC_IF_STRING)) != NULL)
-       {
-               if (strlen(PCAP_SRC_IF_STRING) == strlen(source))
-               {
-                       /* The source identifier contains only the 'rpcap://' string. */
-                       /* So, this is a local capture. */
-                       *type = PCAP_SRC_IFLOCAL;
-                       return 0;
-               }
-
-               ptr += strlen(PCAP_SRC_IF_STRING);
-
-               if (strchr(ptr, '[')) /* This is probably a numeric address */
-               {
-                       ntoken = sscanf(ptr, "[%[1234567890:.]]:%[^/]/%s", tmphost, tmpport, tmpname);
-
-                       if (ntoken == 1)        /* probably the port is missing */
-                               ntoken = sscanf(ptr, "[%[1234567890:.]]/%s", tmphost, tmpname);
-
-                       tmptype = PCAP_SRC_IFREMOTE;
-               }
-               else
-               {
-                       ntoken = sscanf(ptr, "%[^/:]:%[^/]/%s", tmphost, tmpport, tmpname);
-
-                       if (ntoken == 1)
-                       {
-                               /*
-                                * This can be due to two reasons:
-                                * - we want a remote capture, but the network port is missing
-                                * - we want to do a local capture
-                                * To distinguish between the two, we look for the '/' char
-                                */
-                               if (strchr(ptr, '/'))
-                               {
-                                       /* We're on a remote capture */
-                                       sscanf(ptr, "%[^/]/%s", tmphost, tmpname);
-                                       tmptype = PCAP_SRC_IFREMOTE;
-                               }
-                               else
-                               {
-                                       /* We're on a local capture */
-                                       if (*ptr)
-                                               strlcpy(tmpname, ptr, PCAP_BUF_SIZE);
-
-                                       /* Clean the host name, since it is a remote capture */
-                                       /* NOTE: the host name has been assigned in the previous "ntoken= sscanf(...)" line */
-                                       tmphost[0] = 0;
-
-                                       tmptype = PCAP_SRC_IFLOCAL;
-                               }
-                       }
-                       else
-                               tmptype = PCAP_SRC_IFREMOTE;
-               }
-
-               if (host)
-                       strlcpy(host, tmphost, PCAP_BUF_SIZE);
-               if (port)
-                       strlcpy(port, tmpport, PCAP_BUF_SIZE);
-               if (type)
-                       *type = tmptype;
-
-               if (name)
-               {
-                       /*
-                        * If the user wants the host name, but it cannot be located into the source string, return error
-                        * However, if the user is not interested in the interface name (e.g. if we're called by
-                        * pcap_findalldevs_ex(), which does not have interface name, do not return error
-                        */
-                       if (tmpname[0])
-                       {
-                               strlcpy(name, tmpname, PCAP_BUF_SIZE);
-                       }
-                       else
-                       {
-                               if (errbuf)
-                                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string.");
-
-                               return -1;
-                       }
-               }
-
-               return 0;
-       }
-
-       /* Look for a 'file://' identifier */
-       if ((ptr = strstr(source, PCAP_SRC_FILE_STRING)) != NULL)
-       {
-               ptr += strlen(PCAP_SRC_FILE_STRING);
-               if (*ptr)
-               {
-                       if (name)
-                               strlcpy(name, ptr, PCAP_BUF_SIZE);
-
-                       if (type)
-                               *type = PCAP_SRC_FILE;
-
-                       return 0;
-               }
-               else
-               {
-                       if (errbuf)
-                               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name has not been specified in the source string.");
-
-                       return -1;
-               }
-
-       }
-
-       /* Backward compatibility; the user didn't use the 'rpcap://, file://'  specifiers */
-       if ((source) && (*source))
-       {
-               if (name)
-                       strlcpy(name, source, PCAP_BUF_SIZE);
-
-               if (type)
-                       *type = PCAP_SRC_IFLOCAL;
-
-               return 0;
-       }
-       else
-       {
-               if (errbuf)
-                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string.");
-
-               return -1;
-       }
-}
-
 pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
 {
        char name[PCAP_BUF_SIZE];
diff --git a/pcap.c b/pcap.c
index 98e06e5ba2f6761ebcab01cd0da4ae9b98d94bbc..ccf82f1559c159eadcceccc732e9837d0f1d06aa 100644 (file)
--- a/pcap.c
+++ b/pcap.c
@@ -1306,6 +1306,235 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
        return (p);
 }
 
+#ifdef HAVE_REMOTE
+int
+pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf)
+{
+       switch (type)
+       {
+       case PCAP_SRC_FILE:
+       {
+               strlcpy(source, PCAP_SRC_FILE_STRING, PCAP_BUF_SIZE);
+               if ((name) && (*name))
+               {
+                       strlcat(source, name, PCAP_BUF_SIZE);
+                       return 0;
+               }
+               else
+               {
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name cannot be NULL.");
+                       return -1;
+               }
+       }
+
+       case PCAP_SRC_IFREMOTE:
+       {
+               strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+               if ((host) && (*host))
+               {
+                       if ((strcspn(host, "aAbBcCdDeEfFgGhHjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ")) == strlen(host))
+                       {
+                               /* the host name does not contains alphabetic chars. So, it is a numeric address */
+                               /* In this case we have to include it between square brackets */
+                               strlcat(source, "[", PCAP_BUF_SIZE);
+                               strlcat(source, host, PCAP_BUF_SIZE);
+                               strlcat(source, "]", PCAP_BUF_SIZE);
+                       }
+                       else
+                               strlcat(source, host, PCAP_BUF_SIZE);
+
+                       if ((port) && (*port))
+                       {
+                               strlcat(source, ":", PCAP_BUF_SIZE);
+                               strlcat(source, port, PCAP_BUF_SIZE);
+                       }
+
+                       strlcat(source, "/", PCAP_BUF_SIZE);
+               }
+               else
+               {
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The host name cannot be NULL.");
+                       return -1;
+               }
+
+               if ((name) && (*name))
+                       strlcat(source, name, PCAP_BUF_SIZE);
+
+               return 0;
+       }
+
+       case PCAP_SRC_IFLOCAL:
+       {
+               strlcpy(source, PCAP_SRC_IF_STRING, PCAP_BUF_SIZE);
+
+               if ((name) && (*name))
+                       strlcat(source, name, PCAP_BUF_SIZE);
+
+               return 0;
+       }
+
+       default:
+       {
+               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface type is not valid.");
+               return -1;
+       }
+       }
+}
+
+int
+pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf)
+{
+       char *ptr;
+       int ntoken;
+       char tmpname[PCAP_BUF_SIZE];
+       char tmphost[PCAP_BUF_SIZE];
+       char tmpport[PCAP_BUF_SIZE];
+       int tmptype;
+
+       /* Initialization stuff */
+       tmpname[0] = 0;
+       tmphost[0] = 0;
+       tmpport[0] = 0;
+
+       if (host)
+               *host = 0;
+       if (port)
+               *port = 0;
+       if (name)
+               *name = 0;
+
+       /* Look for a 'rpcap://' identifier */
+       if ((ptr = strstr(source, PCAP_SRC_IF_STRING)) != NULL)
+       {
+               if (strlen(PCAP_SRC_IF_STRING) == strlen(source))
+               {
+                       /* The source identifier contains only the 'rpcap://' string. */
+                       /* So, this is a local capture. */
+                       *type = PCAP_SRC_IFLOCAL;
+                       return 0;
+               }
+
+               ptr += strlen(PCAP_SRC_IF_STRING);
+
+               if (strchr(ptr, '[')) /* This is probably a numeric address */
+               {
+                       ntoken = sscanf(ptr, "[%[1234567890:.]]:%[^/]/%s", tmphost, tmpport, tmpname);
+
+                       if (ntoken == 1)        /* probably the port is missing */
+                               ntoken = sscanf(ptr, "[%[1234567890:.]]/%s", tmphost, tmpname);
+
+                       tmptype = PCAP_SRC_IFREMOTE;
+               }
+               else
+               {
+                       ntoken = sscanf(ptr, "%[^/:]:%[^/]/%s", tmphost, tmpport, tmpname);
+
+                       if (ntoken == 1)
+                       {
+                               /*
+                                * This can be due to two reasons:
+                                * - we want a remote capture, but the network port is missing
+                                * - we want to do a local capture
+                                * To distinguish between the two, we look for the '/' char
+                                */
+                               if (strchr(ptr, '/'))
+                               {
+                                       /* We're on a remote capture */
+                                       sscanf(ptr, "%[^/]/%s", tmphost, tmpname);
+                                       tmptype = PCAP_SRC_IFREMOTE;
+                               }
+                               else
+                               {
+                                       /* We're on a local capture */
+                                       if (*ptr)
+                                               strlcpy(tmpname, ptr, PCAP_BUF_SIZE);
+
+                                       /* Clean the host name, since it is a remote capture */
+                                       /* NOTE: the host name has been assigned in the previous "ntoken= sscanf(...)" line */
+                                       tmphost[0] = 0;
+
+                                       tmptype = PCAP_SRC_IFLOCAL;
+                               }
+                       }
+                       else
+                               tmptype = PCAP_SRC_IFREMOTE;
+               }
+
+               if (host)
+                       strlcpy(host, tmphost, PCAP_BUF_SIZE);
+               if (port)
+                       strlcpy(port, tmpport, PCAP_BUF_SIZE);
+               if (type)
+                       *type = tmptype;
+
+               if (name)
+               {
+                       /*
+                        * If the user wants the host name, but it cannot be located into the source string, return error
+                        * However, if the user is not interested in the interface name (e.g. if we're called by
+                        * pcap_findalldevs_ex(), which does not have interface name, do not return error
+                        */
+                       if (tmpname[0])
+                       {
+                               strlcpy(name, tmpname, PCAP_BUF_SIZE);
+                       }
+                       else
+                       {
+                               if (errbuf)
+                                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string.");
+
+                               return -1;
+                       }
+               }
+
+               return 0;
+       }
+
+       /* Look for a 'file://' identifier */
+       if ((ptr = strstr(source, PCAP_SRC_FILE_STRING)) != NULL)
+       {
+               ptr += strlen(PCAP_SRC_FILE_STRING);
+               if (*ptr)
+               {
+                       if (name)
+                               strlcpy(name, ptr, PCAP_BUF_SIZE);
+
+                       if (type)
+                               *type = PCAP_SRC_FILE;
+
+                       return 0;
+               }
+               else
+               {
+                       if (errbuf)
+                               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The file name has not been specified in the source string.");
+
+                       return -1;
+               }
+
+       }
+
+       /* Backward compatibility; the user didn't use the 'rpcap://, file://'  specifiers */
+       if ((source) && (*source))
+       {
+               if (name)
+                       strlcpy(name, source, PCAP_BUF_SIZE);
+
+               if (type)
+                       *type = PCAP_SRC_IFLOCAL;
+
+               return 0;
+       }
+       else
+       {
+               if (errbuf)
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "The interface name has not been specified in the source string.");
+
+               return -1;
+       }
+}
+#endif
+
 pcap_t *
 pcap_create_common(char *ebuf, size_t size)
 {