]> git.ipfire.org Git - people/ms/rstp.git/blame - ctl_socket.c
Fix rstpctl usage
[people/ms/rstp.git] / ctl_socket.c
CommitLineData
ad02a0eb
SH
1/*****************************************************************************
2 Copyright (c) 2006 EMC Corporation.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2 of the License, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Authors: Srinivas Aji <Aji_Srinivas@emc.com>
22
23******************************************************************************/
24
25#include "ctl_socket.h"
26#include "ctl_socket_server.h"
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <sys/un.h>
31#include <unistd.h>
32#include <stdio.h>
33#include <fcntl.h>
34
35#include "epoll_loop.h"
36#include "log.h"
37
ad02a0eb
SH
38int server_socket(void)
39{
11904a35
SH
40 struct sockaddr_un sa;
41 int s;
ad02a0eb 42
11904a35 43 TST(strlen(RSTP_SERVER_SOCK_NAME) < sizeof(sa.sun_path), -1);
ad02a0eb 44
11904a35
SH
45 s = socket(PF_UNIX, SOCK_DGRAM, 0);
46 if (s < 0) {
47 ERROR("Couldn't open unix socket: %m");
48 return -1;
49 }
50
51 set_socket_address(&sa, RSTP_SERVER_SOCK_NAME);
ad02a0eb 52
11904a35
SH
53 if (bind(s, (struct sockaddr *)&sa, sizeof(sa)) != 0) {
54 ERROR("Couldn't bind socket: %m");
55 close(s);
56 return -1;
57 }
58
59 return s;
60}
ad02a0eb
SH
61
62int handle_message(int cmd, void *inbuf, int lin, void *outbuf, int *lout)
63{
11904a35
SH
64 switch (cmd) {
65 SERVER_MESSAGE_CASE(enable_bridge_rstp);
66 SERVER_MESSAGE_CASE(get_bridge_state);
67 SERVER_MESSAGE_CASE(set_bridge_config);
68 SERVER_MESSAGE_CASE(get_port_state);
69 SERVER_MESSAGE_CASE(set_port_config);
70 SERVER_MESSAGE_CASE(set_debug_level);
71
72 default:
73 ERROR("CTL: Unknown command %d", cmd);
74 return -1;
75 }
ad02a0eb
SH
76}
77
78#define msg_buf_len 1024
79unsigned char msg_inbuf[1024];
80unsigned char msg_outbuf[1024];
81
82void ctl_rcv_handler(uint32_t events, struct epoll_event_handler *p)
83{
11904a35
SH
84 struct ctl_msg_hdr mhdr;
85 struct msghdr msg;
86 struct sockaddr_un sa;
87 struct iovec iov[2];
88 int l;
89
90 msg.msg_name = &sa;
91 msg.msg_namelen = sizeof(sa);
92 msg.msg_iov = iov;
93 msg.msg_iovlen = 2;
94 msg.msg_control = NULL;
95 msg.msg_controllen = 0;
96 iov[0].iov_base = &mhdr;
97 iov[0].iov_len = sizeof(mhdr);
98 iov[1].iov_base = msg_inbuf;
99 iov[1].iov_len = msg_buf_len;
100 l = recvmsg(p->fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT);
101 TST(l > 0,);
102 if (msg.msg_flags != 0 || l < sizeof(mhdr) ||
103 l != sizeof(mhdr) + mhdr.lin ||
104 mhdr.lout > msg_buf_len || mhdr.cmd < 0) {
105 ERROR("CTL: Unexpected message. Ignoring");
106 return;
107 }
108
109 if (mhdr.lout)
110 mhdr.res = handle_message(mhdr.cmd, msg_inbuf, mhdr.lin,
111 msg_outbuf, &mhdr.lout);
112 else
113 mhdr.res = handle_message(mhdr.cmd, msg_inbuf, mhdr.lin,
114 NULL, NULL);
115
116 if (mhdr.res < 0)
117 mhdr.lout = 0;
118 iov[1].iov_base = msg_outbuf;
119 iov[1].iov_len = mhdr.lout;
120 l = sendmsg(p->fd, &msg, MSG_NOSIGNAL);
121 if (l < 0)
122 ERROR("CTL: Couldn't send response: %m");
123 else if (l != sizeof(mhdr) + mhdr.lout) {
124 ERROR
125 ("CTL: Couldn't send full response, sent %d bytes instead of %zd.",
126 l, sizeof(mhdr) + mhdr.lout);
127 }
ad02a0eb
SH
128}
129
130struct epoll_event_handler ctl_handler;
131
132int ctl_socket_init(void)
133{
11904a35
SH
134 int s = server_socket();
135 if (s < 0)
136 return -1;
ad02a0eb 137
11904a35
SH
138 ctl_handler.fd = s;
139 ctl_handler.handler = ctl_rcv_handler;
140
141 TST(add_epoll(&ctl_handler) == 0, -1);
142 return 0;
ad02a0eb
SH
143}
144
145void ctl_socket_cleanup(void)
146{
11904a35
SH
147 remove_epoll(&ctl_handler);
148 close(ctl_handler.fd);
ad02a0eb 149}