1 /*
2  * fiked - a fake IKE PSK+XAUTH daemon based on vpnc
3  * Copyright (C) 2005, Daniel Roethlisberger <daniel@roe.ch>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, see http://www.gnu.org/copyleft/
17  *
18  * $Id: datagram.c 103 2005-12-18 16:28:08Z roe $
19  */
20 
21 #include "datagram.h"
22 #include "log.h"
23 #include "mem.h"
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 /*
35  * Create a new datagram instance of given size.
36  * If size is 0, make it as large as supported by UDP.
37  */
datagram_new(size_t size)38 datagram * datagram_new(size_t size)
39 {
40 	if(size == 0)
41 		size = UDP_DGM_MAXSIZE;
42 	datagram *dgm = NULL;
43 	mem_allocate(&dgm, sizeof(datagram));
44 	memset(dgm, 0, sizeof(datagram));
45 	dgm->len = size;
46 	mem_allocate(&dgm->data, dgm->len);
47 	memset(dgm->data, 0, sizeof(dgm->len));
48 	return dgm;
49 }
50 
51 /*
52  * Free a datagram instance.
53  */
datagram_free(datagram * dgm)54 void datagram_free(datagram *dgm)
55 {
56 	if(dgm) {
57 		mem_free(&dgm->data);
58 		free(dgm);
59 	}
60 }
61 
62 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
63 
64 /*
65  * Open a UDP socket on the given port.
66  * Will quit on errors.
67  */
udp_socket_new(uint16_t port)68 udp_socket * udp_socket_new(uint16_t port)
69 {
70 	udp_socket *s = NULL;
71 	mem_allocate(&s, sizeof(udp_socket));
72 	s->port = port;
73 	s->fd = socket(PF_INET, SOCK_DGRAM, 0);
74 	if(s->fd < 0) {
75 		fprintf(stderr, "FATAL: socket(udp) returned %d: %s (%d)\n",
76 			s->fd, strerror(errno), errno);
77 		exit(-1);
78 	}
79 
80 	struct sockaddr_in sa;
81 	sa.sin_family = AF_INET;
82 	sa.sin_port = htons(s->port);
83 	sa.sin_addr.s_addr = htonl(INADDR_ANY);
84 	int ret = bind(s->fd, (struct sockaddr *)&sa, sizeof(sa));
85 	if(ret < 0) {
86 		fprintf(stderr, "FATAL: bind(%d/udp) returned %d: %s (%d)\n",
87 			s->port, ret, strerror(errno), errno);
88 		exit(-1);
89 	}
90 
91 	return s;
92 }
93 
94 /*
95  * Close UDP socket.
96  */
udp_socket_free(udp_socket * s)97 void udp_socket_free(udp_socket *s)
98 {
99 	if(s) {
100 		close(s->fd);
101 		free(s);
102 	}
103 }
104 
105 /*
106  * Receive next incoming UDP datagram on socket s.
107  * Blocks until a datagram is received.
108  */
udp_socket_recv(udp_socket * s)109 datagram * udp_socket_recv(udp_socket *s)
110 {
111 	char buf[UDP_DGM_MAXSIZE];
112 	struct sockaddr_in sa;
113 	socklen_t sa_len = sizeof(sa);
114 	int ret = recvfrom(s->fd, buf, sizeof(buf), 0,
115 		(struct sockaddr *)&sa, &sa_len);
116 	if(ret < 0) {
117 		log_printf(NULL, "ERROR: recvfrom(%d) returned %d: %s (%d)\n",
118 			s->fd, ret, strerror(errno), errno);
119 	}
120 
121 	datagram *dgm = datagram_new(ret);
122 	memcpy(dgm->data, buf, dgm->len);
123 	dgm->peer_addr = sa;
124 
125 	return dgm;
126 }
127 
128 /*
129  * Send a UDP datagram onto socket s.
130  */
udp_socket_send(udp_socket * s,datagram * dgm)131 void udp_socket_send(udp_socket *s, datagram *dgm)
132 {
133 	int ret = sendto(s->fd, dgm->data, dgm->len, 0,
134 		(struct sockaddr*)&dgm->peer_addr, sizeof(dgm->peer_addr));
135 	if(ret < 0) {
136 		log_printf(NULL, "ERROR: sendto(%d to %s:%d) returned %d: %s (%d)\n",
137 			s->fd, inet_ntoa(dgm->peer_addr.sin_addr),
138 			ntohs(dgm->peer_addr.sin_port),
139 			ret, strerror(errno), errno);
140 	}
141 }
142 
143