1 /*
2 * Copyright (c) 2017 Linaro Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #if !defined(__ZEPHYR__)
11
12 #include <netinet/in.h>
13 #include <sys/socket.h>
14 #include <arpa/inet.h>
15 #include <unistd.h>
16 #include <netdb.h>
17
18 #else
19
20 #include <zephyr/net/socket.h>
21 #include <zephyr/kernel.h>
22
23 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
24 #include <zephyr/net/tls_credentials.h>
25 #include "ca_certificate.h"
26 #endif
27
28 #include "net_sample_common.h"
29
30 #endif
31
32 /* HTTP server to connect to */
33 #define HTTP_HOST "google.com"
34 /* Port to connect to, as string */
35 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
36 #define HTTP_PORT "443"
37 #else
38 #define HTTP_PORT "80"
39 #endif
40 /* HTTP path to request */
41 #define HTTP_PATH "/"
42
43 #define SSTRLEN(s) (sizeof(s) - 1)
44 #define CHECK(r) { if (r < 0) { printf("Error: %d\n", (int)r); exit(1); } }
45
46 #define REQUEST "GET " HTTP_PATH " HTTP/1.1\r\nHost: " HTTP_HOST "\r\n\r\n"
47
48 static char response[1024];
49
dump_addrinfo(const struct addrinfo * ai)50 void dump_addrinfo(const struct addrinfo *ai)
51 {
52 printf("addrinfo @%p: ai_family=%d, ai_socktype=%d, ai_protocol=%d, "
53 "sa_family=%d, sin_port=%x\n",
54 ai, ai->ai_family, ai->ai_socktype, ai->ai_protocol, ai->ai_addr->sa_family,
55 ntohs(((struct sockaddr_in *)ai->ai_addr)->sin_port));
56 }
57
main(void)58 int main(void)
59 {
60 static struct addrinfo hints;
61 struct addrinfo *res;
62 int st, sock;
63
64 wait_for_network();
65
66 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
67 tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
68 ca_certificate, sizeof(ca_certificate));
69 #endif
70
71 printf("Preparing HTTP GET request for http://" HTTP_HOST
72 ":" HTTP_PORT HTTP_PATH "\n");
73
74 memset(&hints, 0, sizeof(hints));
75 hints.ai_family = AF_INET;
76 hints.ai_socktype = SOCK_STREAM;
77 st = getaddrinfo(HTTP_HOST, HTTP_PORT, &hints, &res);
78 printf("getaddrinfo status: %d\n", st);
79
80 if (st != 0) {
81 printf("Unable to resolve address, quitting\n");
82 return 0;
83 }
84
85 #if 0
86 for (; res; res = res->ai_next) {
87 dump_addrinfo(res);
88 }
89 #endif
90
91 dump_addrinfo(res);
92
93 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
94 sock = socket(res->ai_family, res->ai_socktype, IPPROTO_TLS_1_2);
95 #else
96 sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
97 #endif
98 CHECK(sock);
99 printf("sock = %d\n", sock);
100
101 #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
102 sec_tag_t sec_tag_opt[] = {
103 CA_CERTIFICATE_TAG,
104 };
105 CHECK(setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST,
106 sec_tag_opt, sizeof(sec_tag_opt)));
107
108 CHECK(setsockopt(sock, SOL_TLS, TLS_HOSTNAME,
109 HTTP_HOST, sizeof(HTTP_HOST)))
110 #endif
111
112 printf("Connecting to server...\n");
113 CHECK(connect(sock, res->ai_addr, res->ai_addrlen));
114 printf("Connected!\r\nSending request...\n");
115 CHECK(send(sock, REQUEST, SSTRLEN(REQUEST), 0));
116
117 printf("Response:\n\n");
118
119 while (1) {
120 int len = recv(sock, response, sizeof(response) - 1, 0);
121
122 if (len < 0) {
123 printf("Error reading response\n");
124 return 0;
125 }
126
127 if (len == 0) {
128 break;
129 }
130
131 response[len] = 0;
132 printf("%s", response);
133 }
134
135 printf("\nClose socket\n");
136
137 (void)close(sock);
138 freeaddrinfo(res);
139
140 return 0;
141 }
142