[package] p910nd: add IPv6 support (#7646)
[openwrt/svn-archive/archive.git] / net / p910nd / patches / 001-ipv6_support.patch
1 diff --git a/p910nd.c b/p910nd.c
2 index e32cca5..4395128 100644
3 --- a/p910nd.c
4 +++ b/p910nd.c
5 @@ -16,6 +16,9 @@
6 * Port 9100+n will then be passively opened
7 * n defaults to 0
8 *
9 + * Version 0.94
10 + * Support IPv6
11 + *
12 * Version 0.93
13 * Fix open call to include mode, required for O_CREAT
14 *
15 @@ -141,6 +144,40 @@ static char *device = 0;
16 static int bidir = 0;
17 static char *bindaddr = 0;
18
19 +
20 +/* Helper function: convert a struct sockaddr address (IPv4 and IPv6) to a string */
21 +char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen)
22 +{
23 + switch(sa->sa_family) {
24 + case AF_INET:
25 + inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen);
26 + break;
27 + case AF_INET6:
28 + inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen);
29 + break;
30 + default:
31 + strncpy(s, "Unknown AF", maxlen);
32 + return NULL;
33 + }
34 + return s;
35 +}
36 +
37 +uint16_t get_port(const struct sockaddr *sa)
38 +{
39 + uint16_t port;
40 + switch(sa->sa_family) {
41 + case AF_INET:
42 + port = ntohs(((struct sockaddr_in *)sa)->sin_port);
43 + break;
44 + case AF_INET6:
45 + port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
46 + break;
47 + default:
48 + return 0;
49 + }
50 + return port;
51 +}
52 +
53 void usage(void)
54 {
55 fprintf(stderr, "%s %s %s\n", progname, version, copyright);
56 @@ -399,11 +436,13 @@ int copy_stream(int fd, int lp)
57 void one_job(int lpnumber)
58 {
59 int lp;
60 - struct sockaddr_in client;
61 + struct sockaddr_storage client;
62 socklen_t clientlen = sizeof(client);
63
64 - if (getpeername(0, (struct sockaddr *)&client, &clientlen) >= 0)
65 - syslog(LOG_NOTICE, "Connection from %s port %hu\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
66 + if (getpeername(0, (struct sockaddr *)&client, &clientlen) >= 0) {
67 + char host[INET6_ADDRSTRLEN];
68 + syslog(LOG_NOTICE, "Connection from %s port %hu\n", get_ip_str((struct sockaddr *)&client, host, sizeof(host)), get_port((struct sockaddr *)&client));
69 + }
70 if (get_lock(lpnumber) == 0)
71 return;
72 /* Make sure lp device is open... */
73 @@ -423,10 +462,11 @@ void server(int lpnumber)
74 #endif
75 int netfd, fd, lp, one = 1;
76 socklen_t clientlen;
77 - struct sockaddr_in netaddr, client;
78 + struct sockaddr_storage client;
79 + struct addrinfo hints, *res, *ressave;
80 char pidfilename[sizeof(PIDFILE)];
81 + char service[sizeof(BASEPORT+lpnumber-'0')+1];
82 FILE *f;
83 - int ipret;
84
85 #ifndef TESTING
86 switch (fork()) {
87 @@ -465,47 +505,55 @@ void server(int lpnumber)
88 if (get_lock(lpnumber) == 0)
89 exit(1);
90 #endif
91 -#ifdef USE_GETPROTOBYNAME
92 - if ((proto = getprotobyname("tcp")) == NULL) {
93 - syslog(LOGOPTS, "Cannot find protocol for TCP!\n");
94 + memset(&hints, 0, sizeof(hints));
95 + hints.ai_family = PF_UNSPEC;
96 + hints.ai_flags = AI_PASSIVE;
97 + hints.ai_socktype = SOCK_STREAM;
98 + (void)snprintf(service, sizeof(service), "%hu", (BASEPORT + lpnumber - '0'));
99 + if (getaddrinfo(bindaddr, service, &hints, &res) != 0) {
100 + syslog(LOGOPTS, "getaddr: %m\n");
101 exit(1);
102 }
103 - if ((netfd = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0)
104 + ressave = res;
105 + while (res) {
106 +#ifdef USE_GETPROTOBYNAME
107 + if ((proto = getprotobyname("tcp6")) == NULL) {
108 + if ((proto = getprotobyname("tcp")) == NULL) {
109 + syslog(LOGOPTS, "Cannot find protocol for TCP!\n");
110 + exit(1);
111 + }
112 + }
113 + if ((netfd = socket(res->ai_family, res->ai_socktype, proto->p_proto)) < 0)
114 #else
115 - if ((netfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
116 + if ((netfd = socket(res->ai_family, res->ai_socktype, IPPROTO_IP)) < 0)
117 #endif
118 - {
119 - syslog(LOGOPTS, "socket: %m\n");
120 - exit(1);
121 - }
122 - if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))
123 - < 0) {
124 - syslog(LOGOPTS, "setsocketopt: %m\n");
125 - exit(1);
126 - }
127 - netaddr.sin_family = AF_INET;
128 - netaddr.sin_port = htons(BASEPORT + lpnumber - '0');
129 - if (bindaddr == 0) {
130 - netaddr.sin_addr.s_addr = htonl(INADDR_ANY);
131 - } else {
132 - ipret = inet_pton(AF_INET, bindaddr, &netaddr.sin_addr.s_addr);
133 - if (ipret < 0) {
134 - syslog(LOGOPTS, "inet_pton: %m\n");
135 - exit(1);
136 - } else if (ipret == 0) {
137 - syslog(LOGOPTS, "inet_pton: invalid bind IP address\n");
138 - exit(1);
139 + {
140 + syslog(LOGOPTS, "socket: %m\n");
141 + close(netfd);
142 + res = res->ai_next;
143 + continue;
144 }
145 + if (setsockopt(netfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
146 + syslog(LOGOPTS, "setsocketopt: %m\n");
147 + close(netfd);
148 + res = res->ai_next;
149 + continue;
150 + }
151 + if (bind(netfd, res->ai_addr, res->ai_addrlen) < 0) {
152 + syslog(LOGOPTS, "bind: %m\n");
153 + close(netfd);
154 + res = res->ai_next;
155 + continue;
156 + }
157 + if (listen(netfd, 5) < 0) {
158 + syslog(LOGOPTS, "listen: %m\n");
159 + close(netfd);
160 + res = res->ai_next;
161 + continue;
162 + }
163 + break;
164 }
165 - memset(netaddr.sin_zero, 0, sizeof(netaddr.sin_zero));
166 - if (bind(netfd, (struct sockaddr *)&netaddr, sizeof(netaddr)) < 0) {
167 - syslog(LOGOPTS, "bind: %m\n");
168 - exit(1);
169 - }
170 - if (listen(netfd, 5) < 0) {
171 - syslog(LOGOPTS, "listen: %m\n");
172 - exit(1);
173 - }
174 + freeaddrinfo(ressave);
175 clientlen = sizeof(client);
176 memset(&client, 0, sizeof(client));
177 while ((fd = accept(netfd, (struct sockaddr *)&client, &clientlen)) >= 0) {
178 @@ -517,7 +565,8 @@ void server(int lpnumber)
179 continue;
180 }
181 #endif
182 - syslog(LOG_NOTICE, "Connection from %s port %hu accepted\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
183 + char host[INET6_ADDRSTRLEN];
184 + syslog(LOG_NOTICE, "Connection from %s port %hu accepted\n", get_ip_str((struct sockaddr *)&client, host, sizeof(host)), get_port((struct sockaddr *)&client));
185 /*write(fd, "Printing", 8); */
186
187 /* Make sure lp device is open... */
188 @@ -536,7 +585,7 @@ void server(int lpnumber)
189
190 int is_standalone(void)
191 {
192 - struct sockaddr_in bind_addr;
193 + struct sockaddr_storage bind_addr;
194 socklen_t ba_len;
195
196 /*