1 /*
2 * Copyright (c) 2014 Brian Swetland
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include "network.h"
15
lookup_hostname(const char * hostname)16 in_addr_t lookup_hostname(const char *hostname) {
17 int err;
18 struct addrinfo *info, *temp;
19 in_addr_t addr = 0;
20
21 struct addrinfo hints;
22 memset(&hints, 0, sizeof(hints));
23 hints.ai_family = AF_INET;
24 hints.ai_socktype = SOCK_STREAM;
25
26 err = getaddrinfo(hostname, NULL, &hints, &info);
27 if (err < 0) {
28 printf("getaddrinfo() returns %d, error '%s'\n", err, gai_strerror(err));
29 return 0;
30 }
31
32 for (temp = info; temp; temp = temp->ai_next) {
33 // printf("flags 0x%x, family %d, socktype %d, protocol %d, addrlen %d\n",
34 // temp->ai_flags, temp->ai_family, temp->ai_socktype, temp->ai_protocol, temp->ai_addrlen);
35
36 if (temp->ai_family == AF_INET && temp->ai_protocol == IPPROTO_TCP) {
37 struct sockaddr_in *sa = (struct sockaddr_in *)temp->ai_addr;
38 // printf("port %d, addr 0x%x\n", sa->sin_port, sa->sin_addr.s_addr);
39 addr = sa->sin_addr.s_addr;
40 }
41 }
42
43 freeaddrinfo(info);
44
45 return addr;
46 }
47
inet_listen(in_addr_t addr,int type,unsigned port,int shared)48 static int inet_listen(in_addr_t addr, int type, unsigned port, int shared) {
49 struct sockaddr_in sa;
50 int s;
51 if ((s = socket(AF_INET, type, 0)) < 0) {
52 return -1;
53 }
54 if (shared) {
55 int opt = 1;
56 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
57 //setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
58 }
59 memset(&sa, 0, sizeof(sa));
60 sa.sin_family = AF_INET;
61 sa.sin_port = htons(port);
62 sa.sin_addr.s_addr = addr;
63 if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
64 close(s);
65 return -1;
66 }
67 return s;
68 }
69
inet_connect(in_addr_t addr,int type,unsigned port)70 static int inet_connect(in_addr_t addr, int type, unsigned port) {
71 struct sockaddr_in sa;
72 int s;
73 if ((s = socket(AF_INET, type, 0)) < 0) {
74 return -1;
75 }
76 if (addr == 0xFFFFFFFF) {
77 int opt = 1;
78 setsockopt(s, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt));
79 }
80 memset(&sa, 0, sizeof(sa));
81 sa.sin_family = AF_INET;
82 sa.sin_port = htons(port);
83 sa.sin_addr.s_addr = addr;
84 if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
85 close(s);
86 return -1;
87 }
88 return s;
89 }
90
udp_listen(in_addr_t addr,unsigned port,int shared)91 int udp_listen(in_addr_t addr, unsigned port, int shared) {
92 return inet_listen(addr, SOCK_DGRAM, port, shared);
93 }
94
udp_connect(in_addr_t addr,unsigned port)95 int udp_connect(in_addr_t addr, unsigned port) {
96 return inet_connect(addr, SOCK_DGRAM, port);
97 }
98
tcp_listen(in_addr_t addr,unsigned port)99 int tcp_listen(in_addr_t addr, unsigned port) {
100 return inet_listen(addr, SOCK_STREAM, port, 0);
101 }
102
tcp_connect(in_addr_t addr,unsigned port)103 int tcp_connect(in_addr_t addr, unsigned port) {
104 return inet_connect(addr, SOCK_STREAM, port);
105 }
106