]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
branches/winverbs: implement some useful ip helper functions not available pre-vista
authorshefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Thu, 16 Apr 2009 23:34:44 +0000 (23:34 +0000)
committershefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Thu, 16 Apr 2009 23:34:44 +0000 (23:34 +0000)
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1@2110 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/winverbs/etc/user/inet.c [new file with mode: 0644]

diff --git a/branches/winverbs/etc/user/inet.c b/branches/winverbs/etc/user/inet.c
new file mode 100644 (file)
index 0000000..28e3d5b
--- /dev/null
@@ -0,0 +1,158 @@
+/*\r
+ * Copyright (c) 2009 Intel Corp., Inc.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses.  You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ */\r
+\r
+#include <arpa/inet.h>\r
+\r
+static int inet_pton4(const char *src, struct in_addr *addr)\r
+{\r
+       unsigned long ip;\r
+\r
+       ip = inet_addr(src);\r
+       if (ip == INADDR_NONE)\r
+               return 0;\r
+\r
+       addr->S_un.S_addr = ip;\r
+       return 1;\r
+}\r
+\r
+enum in6_addr_format_state\r
+{\r
+       in6_fs_num,\r
+       in6_fs_colon,\r
+       in6_fs_0_colon,\r
+       in6_fs_0_num\r
+};\r
+\r
+static int inet_check_groups(const char *src)\r
+{\r
+       int i;\r
+       int digits = 0, groups = 0;\r
+       enum in6_addr_format_state state;\r
+\r
+       if (src[0] == ':') {\r
+               if (src[1] == ':') {\r
+                       i = 2;\r
+                       state = in6_fs_0_colon;\r
+               } else {\r
+                       return -1;\r
+               }\r
+       } else {\r
+               i = 0;\r
+               state = in6_fs_num;\r
+       }\r
+\r
+       for (; src[i] != '\0'; i++) {\r
+               if (src[i] == ':') {\r
+\r
+                       switch (state) {\r
+                       case in6_fs_num:\r
+                               state = in6_fs_colon;\r
+                               break;\r
+                       case in6_fs_colon:\r
+                       case in6_fs_0_num:\r
+                               state = in6_fs_0_colon;\r
+                               break;\r
+                       default:\r
+                               return -1;\r
+                       }\r
+                       digits = 0;\r
+\r
+               } else if (isxdigit(src[i]) && digits++ < 4) {\r
+\r
+                       switch (state) {\r
+                       case in6_fs_colon:\r
+                               state = in6_fs_num;\r
+                               groups++;\r
+                               break;\r
+                       case in6_fs_0_colon:\r
+                               state = in6_fs_0_num;\r
+                               groups++;\r
+                               break;\r
+                       default:\r
+                               break;\r
+                       }\r
+               } else {\r
+                       return -1;\r
+               }\r
+       }\r
+\r
+       if (groups > 8 || state == in6_fs_colon)\r
+               return -1;\r
+       \r
+       return groups;\r
+}\r
+\r
+/*\r
+ * We don't handle the format x:x:x:x:x:x:d.d.d.d\r
+ */\r
+static int inet_pton6(const char *src, struct in6_addr *addr)\r
+{\r
+       const char *pos;\r
+       int i, skip;\r
+\r
+       skip = 8 - inet_check_groups(src);\r
+       if (skip > 8)\r
+               return -1;\r
+\r
+       memset(addr, 0, sizeof(*addr));\r
+       if (src[0] == ':') {\r
+               pos = src + 2;\r
+               i = skip;\r
+       } else {\r
+               pos = src;\r
+               i = 0;\r
+       }\r
+\r
+       for (; i < 8; i++) {\r
+               addr->u.Word[i] = htons((u_short) strtoul(pos, (char **) &pos, 16));\r
+               pos++;\r
+               if (*pos == ':') {\r
+                       pos++;\r
+                       i += skip;\r
+               }\r
+       }\r
+\r
+       return 1;\r
+}\r
+\r
+int inet_pton(int af, const char *src, void *dst)\r
+{\r
+       switch (af) {\r
+       case AF_INET:\r
+               return inet_pton4(src, dst);\r
+       case AF_INET6:\r
+               return inet_pton6(src, dst);\r
+       default:\r
+               return -1;\r
+       }\r
+}\r