aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRobert Pluim2018-07-16 19:43:41 +0200
committerRobert Pluim2018-07-16 19:44:54 +0200
commite89c06e8cea429620bc2cf4a98b9b741861b811a (patch)
treefbd168a342c20512c982bc7641b5bbbf870818d8 /src
parentfab6139b8954c4d33c4430a722337e09939aa777 (diff)
downloademacs-e89c06e8cea429620bc2cf4a98b9b741861b811a.tar.gz
emacs-e89c06e8cea429620bc2cf4a98b9b741861b811a.zip
Implement hostname->ip lookup function
* src/process.c (conv_sockaddr_to_lisp): Add include_port argument. Don't put a port in the result if this is false. (conv_addrinfo_to_lisp, Fprocess_datagram_address) (connect_network_socket, network_interface_list) (network_interface_info, server_accept_connection) (init_process_emacs): Update callers. (Fnetwork_lookup_address_info): New function. Performs hostname to ip address lookups. * src/w32.c (network_interface_get_info): Update callers of conv_sockaddr_to_lisp * etc/NEWS : mention addition of 'network-lookup-address-info'
Diffstat (limited to 'src')
-rw-r--r--src/process.c100
-rw-r--r--src/process.h2
-rw-r--r--src/w32.c24
3 files changed, 102 insertions, 24 deletions
diff --git a/src/process.c b/src/process.c
index 3fccd962da6..2025398c22d 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2484,7 +2484,7 @@ usage: (make-pipe-process &rest ARGS) */)
2484 The address family of sa is not included in the result. */ 2484 The address family of sa is not included in the result. */
2485 2485
2486Lisp_Object 2486Lisp_Object
2487conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len) 2487conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len, bool include_port)
2488{ 2488{
2489 Lisp_Object address; 2489 Lisp_Object address;
2490 ptrdiff_t i; 2490 ptrdiff_t i;
@@ -2503,9 +2503,12 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len)
2503 { 2503 {
2504 DECLARE_POINTER_ALIAS (sin, struct sockaddr_in, sa); 2504 DECLARE_POINTER_ALIAS (sin, struct sockaddr_in, sa);
2505 len = sizeof (sin->sin_addr) + 1; 2505 len = sizeof (sin->sin_addr) + 1;
2506 if (!include_port)
2507 len--;
2506 address = Fmake_vector (make_number (len), Qnil); 2508 address = Fmake_vector (make_number (len), Qnil);
2507 p = XVECTOR (address); 2509 p = XVECTOR (address);
2508 p->contents[--len] = make_number (ntohs (sin->sin_port)); 2510 if (include_port)
2511 p->contents[--len] = make_number (ntohs (sin->sin_port));
2509 cp = (unsigned char *) &sin->sin_addr; 2512 cp = (unsigned char *) &sin->sin_addr;
2510 break; 2513 break;
2511 } 2514 }
@@ -2515,9 +2518,12 @@ conv_sockaddr_to_lisp (struct sockaddr *sa, ptrdiff_t len)
2515 DECLARE_POINTER_ALIAS (sin6, struct sockaddr_in6, sa); 2518 DECLARE_POINTER_ALIAS (sin6, struct sockaddr_in6, sa);
2516 DECLARE_POINTER_ALIAS (ip6, uint16_t, &sin6->sin6_addr); 2519 DECLARE_POINTER_ALIAS (ip6, uint16_t, &sin6->sin6_addr);
2517 len = sizeof (sin6->sin6_addr) / 2 + 1; 2520 len = sizeof (sin6->sin6_addr) / 2 + 1;
2521 if (!include_port)
2522 len--;
2518 address = Fmake_vector (make_number (len), Qnil); 2523 address = Fmake_vector (make_number (len), Qnil);
2519 p = XVECTOR (address); 2524 p = XVECTOR (address);
2520 p->contents[--len] = make_number (ntohs (sin6->sin6_port)); 2525 if (include_port)
2526 p->contents[--len] = make_number (ntohs (sin6->sin6_port));
2521 for (i = 0; i < len; i++) 2527 for (i = 0; i < len; i++)
2522 p->contents[i] = make_number (ntohs (ip6[i])); 2528 p->contents[i] = make_number (ntohs (ip6[i]));
2523 return address; 2529 return address;
@@ -2568,7 +2574,7 @@ conv_addrinfo_to_lisp (struct addrinfo *res)
2568{ 2574{
2569 Lisp_Object protocol = make_number (res->ai_protocol); 2575 Lisp_Object protocol = make_number (res->ai_protocol);
2570 eassert (XINT (protocol) == res->ai_protocol); 2576 eassert (XINT (protocol) == res->ai_protocol);
2571 return Fcons (protocol, conv_sockaddr_to_lisp (res->ai_addr, res->ai_addrlen)); 2577 return Fcons (protocol, conv_sockaddr_to_lisp (res->ai_addr, res->ai_addrlen, true));
2572} 2578}
2573 2579
2574 2580
@@ -2710,7 +2716,8 @@ set up yet, this function will block until socket setup has completed. */)
2710 2716
2711 channel = XPROCESS (process)->infd; 2717 channel = XPROCESS (process)->infd;
2712 return conv_sockaddr_to_lisp (datagram_address[channel].sa, 2718 return conv_sockaddr_to_lisp (datagram_address[channel].sa,
2713 datagram_address[channel].len); 2719 datagram_address[channel].len,
2720 true);
2714} 2721}
2715 2722
2716DEFUN ("set-process-datagram-address", Fset_process_datagram_address, Sset_process_datagram_address, 2723DEFUN ("set-process-datagram-address", Fset_process_datagram_address, Sset_process_datagram_address,
@@ -3571,7 +3578,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3571#endif 3578#endif
3572 3579
3573 contact = Fplist_put (contact, p->is_server? QClocal: QCremote, 3580 contact = Fplist_put (contact, p->is_server? QClocal: QCremote,
3574 conv_sockaddr_to_lisp (sa, addrlen)); 3581 conv_sockaddr_to_lisp (sa, addrlen, true));
3575#ifdef HAVE_GETSOCKNAME 3582#ifdef HAVE_GETSOCKNAME
3576 if (!p->is_server) 3583 if (!p->is_server)
3577 { 3584 {
@@ -3580,7 +3587,7 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3580 DECLARE_POINTER_ALIAS (psa1, struct sockaddr, &sa1); 3587 DECLARE_POINTER_ALIAS (psa1, struct sockaddr, &sa1);
3581 if (getsockname (s, psa1, &len1) == 0) 3588 if (getsockname (s, psa1, &len1) == 0)
3582 contact = Fplist_put (contact, QClocal, 3589 contact = Fplist_put (contact, QClocal,
3583 conv_sockaddr_to_lisp (psa1, len1)); 3590 conv_sockaddr_to_lisp (psa1, len1, true));
3584 } 3591 }
3585#endif 3592#endif
3586 } 3593 }
@@ -4253,7 +4260,8 @@ network_interface_list (void)
4253 namebuf[sizeof (ifq->ifr_name)] = 0; 4260 namebuf[sizeof (ifq->ifr_name)] = 0;
4254 res = Fcons (Fcons (build_string (namebuf), 4261 res = Fcons (Fcons (build_string (namebuf),
4255 conv_sockaddr_to_lisp (&ifq->ifr_addr, 4262 conv_sockaddr_to_lisp (&ifq->ifr_addr,
4256 sizeof (struct sockaddr))), 4263 sizeof (struct sockaddr),
4264 true)),
4257 res); 4265 res);
4258 } 4266 }
4259 4267
@@ -4456,9 +4464,9 @@ network_interface_info (Lisp_Object ifname)
4456 { 4464 {
4457 any = 1; 4465 any = 1;
4458#ifdef HAVE_STRUCT_IFREQ_IFR_NETMASK 4466#ifdef HAVE_STRUCT_IFREQ_IFR_NETMASK
4459 elt = conv_sockaddr_to_lisp (&rq.ifr_netmask, sizeof (rq.ifr_netmask)); 4467 elt = conv_sockaddr_to_lisp (&rq.ifr_netmask, sizeof (rq.ifr_netmask), true);
4460#else 4468#else
4461 elt = conv_sockaddr_to_lisp (&rq.ifr_addr, sizeof (rq.ifr_addr)); 4469 elt = conv_sockaddr_to_lisp (&rq.ifr_addr, sizeof (rq.ifr_addr), true);
4462#endif 4470#endif
4463 } 4471 }
4464#endif 4472#endif
@@ -4469,7 +4477,7 @@ network_interface_info (Lisp_Object ifname)
4469 if (ioctl (s, SIOCGIFBRDADDR, &rq) == 0) 4477 if (ioctl (s, SIOCGIFBRDADDR, &rq) == 0)
4470 { 4478 {
4471 any = 1; 4479 any = 1;
4472 elt = conv_sockaddr_to_lisp (&rq.ifr_broadaddr, sizeof (rq.ifr_broadaddr)); 4480 elt = conv_sockaddr_to_lisp (&rq.ifr_broadaddr, sizeof (rq.ifr_broadaddr), true);
4473 } 4481 }
4474#endif 4482#endif
4475 res = Fcons (elt, res); 4483 res = Fcons (elt, res);
@@ -4479,7 +4487,7 @@ network_interface_info (Lisp_Object ifname)
4479 if (ioctl (s, SIOCGIFADDR, &rq) == 0) 4487 if (ioctl (s, SIOCGIFADDR, &rq) == 0)
4480 { 4488 {
4481 any = 1; 4489 any = 1;
4482 elt = conv_sockaddr_to_lisp (&rq.ifr_addr, sizeof (rq.ifr_addr)); 4490 elt = conv_sockaddr_to_lisp (&rq.ifr_addr, sizeof (rq.ifr_addr), true);
4483 } 4491 }
4484#endif 4492#endif
4485 res = Fcons (elt, res); 4493 res = Fcons (elt, res);
@@ -4527,6 +4535,67 @@ Data that is unavailable is returned as nil. */)
4527#endif 4535#endif
4528} 4536}
4529 4537
4538DEFUN ("network-lookup-address-info", Fnetwork_lookup_address_info,
4539 Snetwork_lookup_address_info, 1, 2, 0,
4540 doc: /* Look up ip address info of NAME.
4541Optional parameter FAMILY controls whether to look up IPv4 or IPv6
4542addresses. The default of nil means both, symbol `ipv4' means IPv4
4543only, symbol `ipv6' means IPv6 only. Returns a list of addresses, or
4544nil if none were found. Each address is a vector of integers. */)
4545 (Lisp_Object name, Lisp_Object family)
4546{
4547 Lisp_Object addresses = Qnil;
4548 struct addrinfo *res, *lres;
4549 int ret;
4550
4551 struct addrinfo hints;
4552
4553 if (STRING_MULTIBYTE (name))
4554 error ("Non-ASCII hostname \"%s\" detected, please use puny-encode-string",
4555 SSDATA (name));
4556 memset (&hints, 0, sizeof hints);
4557 if (EQ (family, Qnil))
4558 hints.ai_family = AF_UNSPEC;
4559 if (EQ (family, Qipv4))
4560 hints.ai_family = AF_INET;
4561 if (EQ (family, Qipv6))
4562#ifdef AF_INET6
4563 hints.ai_family = AF_INET6;
4564#else
4565 /* If we don't support IPv6, querying will never work anyway */
4566 return addresses;
4567#endif
4568 hints.ai_socktype = SOCK_DGRAM;
4569
4570 ret = getaddrinfo (SSDATA (name), NULL, &hints, &res);
4571 if (ret)
4572#ifdef HAVE_GAI_STRERROR
4573 {
4574 synchronize_system_messages_locale ();
4575 char const *str = gai_strerror (ret);
4576 if (! NILP (Vlocale_coding_system))
4577 str = SSDATA (code_convert_string_norecord
4578 (build_string (str), Vlocale_coding_system, 0));
4579 message ("\"%s\" \"%s\"", SSDATA (name), str);
4580 }
4581#else
4582 message ("%s network-lookup-address-info error %d", SSDATA (name), ret);
4583#endif
4584 else
4585 {
4586 for (lres = res; lres; lres = lres->ai_next)
4587 {
4588 addresses = Fcons (conv_sockaddr_to_lisp
4589 (lres->ai_addr, lres->ai_addrlen, false),
4590 addresses);
4591 }
4592 addresses = Fnreverse (addresses);
4593
4594 freeaddrinfo (res);
4595 }
4596 return addresses;
4597}
4598
4530/* Turn off input and output for process PROC. */ 4599/* Turn off input and output for process PROC. */
4531 4600
4532static void 4601static void
@@ -4794,12 +4863,12 @@ server_accept_connection (Lisp_Object server, int channel)
4794 if (!NILP (service)) 4863 if (!NILP (service))
4795 contact = Fplist_put (contact, QCservice, service); 4864 contact = Fplist_put (contact, QCservice, service);
4796 contact = Fplist_put (contact, QCremote, 4865 contact = Fplist_put (contact, QCremote,
4797 conv_sockaddr_to_lisp (&saddr.sa, len)); 4866 conv_sockaddr_to_lisp (&saddr.sa, len, true));
4798#ifdef HAVE_GETSOCKNAME 4867#ifdef HAVE_GETSOCKNAME
4799 len = sizeof saddr; 4868 len = sizeof saddr;
4800 if (getsockname (s, &saddr.sa, &len) == 0) 4869 if (getsockname (s, &saddr.sa, &len) == 0)
4801 contact = Fplist_put (contact, QClocal, 4870 contact = Fplist_put (contact, QClocal,
4802 conv_sockaddr_to_lisp (&saddr.sa, len)); 4871 conv_sockaddr_to_lisp (&saddr.sa, len, true));
4803#endif 4872#endif
4804 4873
4805 pset_childp (p, contact); 4874 pset_childp (p, contact);
@@ -8031,7 +8100,7 @@ init_process_emacs (int sockfd)
8031 union u_sockaddr sa; 8100 union u_sockaddr sa;
8032 socklen_t salen = sizeof sa; 8101 socklen_t salen = sizeof sa;
8033 if (getsockname (sockfd, &sa.sa, &salen) == 0) 8102 if (getsockname (sockfd, &sa.sa, &salen) == 0)
8034 sockname = conv_sockaddr_to_lisp (&sa.sa, salen); 8103 sockname = conv_sockaddr_to_lisp (&sa.sa, salen, true);
8035 } 8104 }
8036# endif 8105# endif
8037 Vinternal__daemon_sockname = sockname; 8106 Vinternal__daemon_sockname = sockname;
@@ -8269,6 +8338,7 @@ returns non-`nil'. */);
8269 defsubr (&Sset_network_process_option); 8338 defsubr (&Sset_network_process_option);
8270 defsubr (&Smake_network_process); 8339 defsubr (&Smake_network_process);
8271 defsubr (&Sformat_network_address); 8340 defsubr (&Sformat_network_address);
8341 defsubr (&Snetwork_lookup_address_info);
8272 defsubr (&Snetwork_interface_list); 8342 defsubr (&Snetwork_interface_list);
8273 defsubr (&Snetwork_interface_info); 8343 defsubr (&Snetwork_interface_info);
8274#ifdef DATAGRAM_SOCKETS 8344#ifdef DATAGRAM_SOCKETS
diff --git a/src/process.h b/src/process.h
index 6bc22146a72..504e5e6aaac 100644
--- a/src/process.h
+++ b/src/process.h
@@ -278,7 +278,7 @@ extern Lisp_Object system_process_attributes (Lisp_Object);
278 278
279extern void record_deleted_pid (pid_t, Lisp_Object); 279extern void record_deleted_pid (pid_t, Lisp_Object);
280struct sockaddr; 280struct sockaddr;
281extern Lisp_Object conv_sockaddr_to_lisp (struct sockaddr *, ptrdiff_t); 281extern Lisp_Object conv_sockaddr_to_lisp (struct sockaddr *, ptrdiff_t, bool);
282extern void hold_keyboard_input (void); 282extern void hold_keyboard_input (void);
283extern void unhold_keyboard_input (void); 283extern void unhold_keyboard_input (void);
284extern bool kbd_on_hold_p (void); 284extern bool kbd_on_hold_p (void);
diff --git a/src/w32.c b/src/w32.c
index c848b33b2af..4759b082eb5 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -9210,7 +9210,8 @@ network_interface_get_info (Lisp_Object ifname)
9210 if (NILP (ifname)) 9210 if (NILP (ifname))
9211 res = Fcons (Fcons (build_string (namebuf), 9211 res = Fcons (Fcons (build_string (namebuf),
9212 conv_sockaddr_to_lisp ((struct sockaddr*) &sa, 9212 conv_sockaddr_to_lisp ((struct sockaddr*) &sa,
9213 sizeof (struct sockaddr))), 9213 sizeof (struct sockaddr),
9214 false)),
9214 res); 9215 res);
9215 else if (strcmp (namebuf, SSDATA (ifname)) == 0) 9216 else if (strcmp (namebuf, SSDATA (ifname)) == 0)
9216 { 9217 {
@@ -9257,7 +9258,8 @@ network_interface_get_info (Lisp_Object ifname)
9257 sa.sin_addr.s_addr = net_mask; 9258 sa.sin_addr.s_addr = net_mask;
9258 sa.sin_port = 0; 9259 sa.sin_port = 0;
9259 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, 9260 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa,
9260 sizeof (struct sockaddr)), 9261 sizeof (struct sockaddr),
9262 false),
9261 res); 9263 res);
9262 } 9264 }
9263 else 9265 else
@@ -9274,14 +9276,16 @@ network_interface_get_info (Lisp_Object ifname)
9274 sa.sin_addr.s_addr = bcast_addr; 9276 sa.sin_addr.s_addr = bcast_addr;
9275 sa.sin_port = 0; 9277 sa.sin_port = 0;
9276 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, 9278 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa,
9277 sizeof (struct sockaddr)), 9279 sizeof (struct sockaddr),
9280 false),
9278 res); 9281 res);
9279 9282
9280 /* IP address. */ 9283 /* IP address. */
9281 sa.sin_addr.s_addr = ip_addr; 9284 sa.sin_addr.s_addr = ip_addr;
9282 sa.sin_port = 0; 9285 sa.sin_port = 0;
9283 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, 9286 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa,
9284 sizeof (struct sockaddr)), 9287 sizeof (struct sockaddr),
9288 false),
9285 res); 9289 res);
9286 } 9290 }
9287 else 9291 else
@@ -9299,7 +9303,8 @@ network_interface_get_info (Lisp_Object ifname)
9299 sa.sin_addr.s_addr = sys_inet_addr ("127.0.0.1"); 9303 sa.sin_addr.s_addr = sys_inet_addr ("127.0.0.1");
9300 res = Fcons (Fcons (build_string ("lo"), 9304 res = Fcons (Fcons (build_string ("lo"),
9301 conv_sockaddr_to_lisp ((struct sockaddr*) &sa, 9305 conv_sockaddr_to_lisp ((struct sockaddr*) &sa,
9302 sizeof (struct sockaddr))), 9306 sizeof (struct sockaddr),
9307 false)),
9303 res); 9308 res);
9304 } 9309 }
9305 else if (strcmp (SSDATA (ifname), "lo") == 0) 9310 else if (strcmp (SSDATA (ifname), "lo") == 0)
@@ -9315,15 +9320,18 @@ network_interface_get_info (Lisp_Object ifname)
9315 res); 9320 res);
9316 sa.sin_addr.s_addr = sys_inet_addr ("255.0.0.0"); 9321 sa.sin_addr.s_addr = sys_inet_addr ("255.0.0.0");
9317 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, 9322 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa,
9318 sizeof (struct sockaddr)), 9323 sizeof (struct sockaddr),
9324 false),
9319 res); 9325 res);
9320 sa.sin_addr.s_addr = sys_inet_addr ("0.0.0.0"); 9326 sa.sin_addr.s_addr = sys_inet_addr ("0.0.0.0");
9321 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, 9327 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa,
9322 sizeof (struct sockaddr)), 9328 sizeof (struct sockaddr),
9329 false),
9323 res); 9330 res);
9324 sa.sin_addr.s_addr = sys_inet_addr ("127.0.0.1"); 9331 sa.sin_addr.s_addr = sys_inet_addr ("127.0.0.1");
9325 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, 9332 res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa,
9326 sizeof (struct sockaddr)), 9333 sizeof (struct sockaddr),
9334 false),
9327 res); 9335 res);
9328 } 9336 }
9329 9337