1144564Simp/*- 21558Srgrimes * SPDX-License-Identifier: BSD-2-Clause 31558Srgrimes * 41558Srgrimes * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org> 51558Srgrimes * All rights reserved. 61558Srgrimes * 71558Srgrimes * Redistribution and use in source and binary forms, with or without 81558Srgrimes * modification, are permitted provided that the following conditions 91558Srgrimes * are met: 101558Srgrimes * 1. Redistributions of source code must retain the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer. 121558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131558Srgrimes * notice, this list of conditions and the following disclaimer in the 141558Srgrimes * documentation and/or other materials provided with the distribution. 151558Srgrimes * 161558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 171558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 181558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191558Srgrimes * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS 201558Srgrimes * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211558Srgrimes * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221558Srgrimes * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 231558Srgrimes * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 241558Srgrimes * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 251558Srgrimes * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 261558Srgrimes * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271558Srgrimes * 281558Srgrimes */ 291558Srgrimes 301558Srgrimes#include <sys/queue.h> 311558Srgrimes#include <sys/types.h> 321558Srgrimes#include <sys/socket.h> 331558Srgrimes#include <sys/stat.h> 3423669Speter#include <sys/un.h> 3596707Strhodes#include <sys/uio.h> 361558Srgrimes#include <net/if.h> 371558Srgrimes#include <net/if_dl.h> 381558Srgrimes#include <netinet/in.h> 391558Srgrimes#include <netinet/icmp6.h> 401558Srgrimes#include <fcntl.h> 411558Srgrimes#include <errno.h> 421558Srgrimes#include <netdb.h> 43164911Sdwmalone#include <unistd.h> 44204111Suqs#include <signal.h> 451558Srgrimes#include <string.h> 461558Srgrimes#include <stdarg.h> 4735852Sjkh#include <stdio.h> 481558Srgrimes#include <stdlib.h> 491558Srgrimes#include <syslog.h> 501558Srgrimes 511558Srgrimes#include "pathnames.h" 521558Srgrimes#include "rtadvd.h" 531558Srgrimes#include "if.h" 5423669Speter#include "control.h" 55102231Strhodes#include "control_client.h" 561558Srgrimes 571558Srgrimesint 581558Srgrimescm_handler_client(int fd, int state, char *buf_orig) 591558Srgrimes{ 601558Srgrimes char buf[CM_MSG_MAXLEN]; 611558Srgrimes struct ctrl_msg_hdr *cm; 621558Srgrimes struct ctrl_msg_hdr *cm_orig; 631558Srgrimes int error; 64144099Simp char *msg; 651558Srgrimes char *msg_orig; 661558Srgrimes 67102231Strhodes syslog(LOG_DEBUG, "<%s> enter", __func__); 681558Srgrimes 691558Srgrimes memset(buf, 0, sizeof(buf)); 701558Srgrimes cm = (struct ctrl_msg_hdr *)buf; 711558Srgrimes cm_orig = (struct ctrl_msg_hdr *)buf_orig; 721558Srgrimes msg = (char *)buf + sizeof(*cm); 731558Srgrimes msg_orig = (char *)buf_orig + sizeof(*cm_orig); 741558Srgrimes 751558Srgrimes if (cm_orig->cm_len > CM_MSG_MAXLEN) { 761558Srgrimes syslog(LOG_DEBUG, "<%s> msg too long", __func__); 771558Srgrimes close(fd); 781558Srgrimes return (-1); 791558Srgrimes } 801558Srgrimes cm->cm_type = cm_orig->cm_type; 811558Srgrimes if (cm_orig->cm_len > sizeof(*cm_orig)) { 821558Srgrimes memcpy(msg, msg_orig, cm_orig->cm_len - sizeof(*cm)); 831558Srgrimes cm->cm_len = cm_orig->cm_len; 841558Srgrimes } 851558Srgrimes while (state != CM_STATE_EOM) { 861558Srgrimes syslog(LOG_DEBUG, "<%s> state = %d", __func__, state); 871558Srgrimes 881558Srgrimes switch (state) { 891558Srgrimes case CM_STATE_INIT: 901558Srgrimes state = CM_STATE_EOM; 911558Srgrimes break; 921558Srgrimes case CM_STATE_MSG_DISPATCH: 931558Srgrimes cm->cm_version = CM_VERSION; 941558Srgrimes error = cm_send(fd, buf); 951558Srgrimes if (error) { 961558Srgrimes syslog(LOG_WARNING, 971558Srgrimes "<%s> cm_send()", __func__); 981558Srgrimes return (-1); 991558Srgrimes } 1001558Srgrimes state = CM_STATE_ACK_WAIT; 1011558Srgrimes break; 1021558Srgrimes case CM_STATE_ACK_WAIT: 1031558Srgrimes error = cm_recv(fd, buf); 1041558Srgrimes if (error) { 10598542Smckusick syslog(LOG_ERR, 10698542Smckusick "<%s> cm_recv()", __func__); 10798542Smckusick close(fd); 10898542Smckusick return (-1); 10998542Smckusick } 11098542Smckusick switch (cm->cm_type) { 11198542Smckusick case CM_TYPE_ACK: 11298542Smckusick syslog(LOG_DEBUG, 11398542Smckusick "<%s> CM_TYPE_ACK", __func__); 114100207Smckusick break; 11598542Smckusick case CM_TYPE_ERR: 11698542Smckusick syslog(LOG_DEBUG, 117100207Smckusick "<%s> CM_TYPE_ERR", __func__); 118167011Smckusick close(fd); 11998542Smckusick return (-1); 1201558Srgrimes default: 1211558Srgrimes syslog(LOG_DEBUG, 1221558Srgrimes "<%s> unknown status", __func__); 1231558Srgrimes close(fd); 1241558Srgrimes return (-1); 1251558Srgrimes } 1261558Srgrimes memcpy(buf_orig, buf, cm->cm_len); 1271558Srgrimes state = CM_STATE_EOM; 1281558Srgrimes break; 1291558Srgrimes } 1301558Srgrimes } 1311558Srgrimes close(fd); 1321558Srgrimes return (0); 1331558Srgrimes} 1341558Srgrimes