2
|
1 /* udp.cpp
|
|
2 *
|
|
3 * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005).
|
|
4 * All Rights Reserved.
|
|
5 *
|
|
6 * UDP functions for IPv4
|
|
7 * Multicast Doc: /usr/share/doc/howto/en/html/Multicast-HOWTO.html
|
|
8 *
|
|
9 * Version 0.2
|
|
10 */
|
|
11
|
|
12 #include <stdio.h>
|
|
13 #include <stdlib.h>
|
|
14 #include <string.h>
|
|
15
|
|
16 /* Socket io */
|
|
17 #include <sys/types.h>
|
|
18 #include <sys/socket.h>
|
|
19 #include <netinet/in.h>
|
|
20 #include <netdb.h>
|
|
21 #include <sys/time.h>
|
|
22 #include <unistd.h>
|
|
23 #include <sys/errno.h>
|
|
24 #include <assert.h>
|
|
25
|
|
26 #include "udp.h"
|
|
27 #include "intercomd.h"
|
|
28
|
|
29 int UDP_recv_init(int port)
|
|
30 /* starte UDP LAN Empfang. Programm-Exit bei Fehler! */
|
|
31 /* return: Filedescriptor fuer Empfang */
|
|
32 /* in port: UDP Port Nummer */
|
|
33 {
|
|
34 int fd;
|
|
35 struct sockaddr_in sock;
|
|
36 int local_flag;
|
|
37 socklen_t local_flagsize;
|
|
38
|
|
39 /* init UDP local1 */
|
|
40 fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
41 if (fd < 0) {
|
|
42 fprintf(stderr, "if_recv_init(): socket() failed\n");
|
|
43 exit(1);
|
|
44 }
|
|
45
|
|
46 memset((char *) &sock, 0, sizeof(sock));
|
|
47 sock.sin_family = AF_INET;
|
|
48 sock.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
49 sock.sin_port = htons(port);
|
|
50 if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
|
|
51 fprintf(stderr, "if_recv_init(): bind() failed\n");
|
|
52 exit(2);
|
|
53 }
|
|
54 local_flagsize = sizeof(int);
|
|
55 if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &local_flag,
|
|
56 &local_flagsize) < 0) {
|
|
57 fprintf(stderr, "if_recv_init(): getsockopt() failed\n");
|
|
58 exit(3);
|
|
59 }
|
|
60 /* printf("SO_RCVBUF=%d\n", local_flag); */
|
|
61
|
|
62 /* printf("init socket\n"); */
|
|
63 return fd;
|
|
64 }
|
|
65
|
|
66 void UDP::send_init(char *foreign_name, int foreign_port, int local_fd_)
|
|
67 /* Starte Versand von UDP Meldungen auf LAN */
|
|
68 /* in foreign_name: IP-Adresse auf die gesendet wird */
|
|
69 /* in foreign_port: UDP-Port auf den gesendet wird */
|
|
70 {
|
|
71 struct hostent *foreign_host;
|
|
72 int local_flag;
|
|
73 socklen_t local_flagsize;
|
|
74
|
|
75 local_fd = local_fd_;
|
|
76
|
|
77 /* turn on broadcast */
|
|
78 local_flagsize = sizeof(int);
|
|
79 if (getsockopt(local_fd, SOL_SOCKET, SO_BROADCAST,
|
|
80 (char *) &local_flag, &local_flagsize) < 0) {
|
|
81 fprintf(stderr, "udp_send_init(): getsockopt() failed\n");
|
|
82 exit(3);
|
|
83 }
|
|
84 if (local_flag == 0) {
|
|
85 local_flag = 1;
|
|
86 setsockopt(local_fd, SOL_SOCKET, SO_BROADCAST, (char *) &local_flag,
|
|
87 sizeof(int));
|
|
88 local_flagsize = sizeof(int);
|
|
89 if (getsockopt(local_fd, SOL_SOCKET, SO_BROADCAST,
|
|
90 (char *) &local_flag, &local_flagsize) < 0) {
|
|
91 fprintf(stderr, "udp_send_init() SO_BROADCAST failed\n");
|
|
92 exit(3);
|
|
93 }
|
|
94 }
|
|
95
|
|
96 /* init foreign part */
|
|
97 memset((char *) &foreign_sock, 0, sizeof(foreign_sock));
|
|
98
|
|
99 foreign_host = gethostbyname(foreign_name);
|
|
100 if (foreign_host == NULL || foreign_host->h_length == 0) {
|
|
101 fprintf(stderr, "udp_send_init(): gethostbyname() failed");
|
|
102 exit(1);
|
|
103 }
|
|
104 memcpy(&foreign_sock.sin_addr.s_addr, foreign_host->h_addr_list[0],
|
|
105 foreign_host->h_length);
|
|
106 foreign_sock.sin_family = AF_INET;
|
|
107 foreign_sock.sin_port = htons(foreign_port);
|
|
108
|
|
109
|
|
110 in_addr_t to_ip = ntohl(foreign_sock.sin_addr.s_addr);
|
|
111 char s[20];
|
|
112 print_gui("c %s\n", iptoa(s, to_ip));
|
|
113 }
|
|
114
|
|
115 void UDP::send(char *buf, int bytes)
|
|
116 /* Sende UDP Meldung auf LAN */
|
|
117 /* in buf: Meldung */
|
|
118 /* in bytes: Laenge der Meldung */
|
|
119 {
|
|
120 int len;
|
|
121
|
|
122 len = sendto(local_fd,
|
|
123 buf, bytes,
|
|
124 0, (struct sockaddr *) &foreign_sock, sizeof(foreign_sock));
|
|
125 if (len != bytes) {
|
|
126 fprintf(stderr, "udp_send(): sendto() foreign failed ret=%d\n",
|
|
127 len);
|
|
128 }
|
|
129 }
|
|
130
|
|
131 void UDP::send_close()
|
|
132 {
|
|
133 memset((char *) &foreign_sock, 0, sizeof(foreign_sock));
|
|
134 }
|
|
135
|
|
136 // IP to ASCII
|
|
137 char *iptoa(char *buf, in_addr_t ip)
|
|
138 {
|
|
139 int i1 = ip >> 24;
|
|
140 int i2 = (ip >> 16) & 0xFF;
|
|
141 int i3 = (ip >> 8) & 0xFF;
|
|
142 int i4 = ip & 0xFF;
|
|
143
|
|
144 sprintf(buf, "%d.%d.%d.%d", i1, i2, i3, i4);
|
|
145
|
|
146 return buf;
|
|
147 }
|
|
148
|
|
149 // ASCII to IP
|
|
150 in_addr_t atoip(char *buf)
|
|
151 {
|
|
152 int i1, i2, i3, i4;
|
|
153
|
|
154 sscanf(buf, "%d.%d.%d.%d", &i1, &i2, &i3, &i4);
|
|
155
|
|
156 return i1 << 24 | i2 << 16 | i3 << 8 | i4;
|
|
157 }
|