# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import os import logging import six from ryu.lib import hub, alert from ryu.base import app_manager from ryu.controller import event BUFSIZE = alert.AlertPkt._ALERTPKT_SIZE SOCKFILE = "/tmp/snort_alert" class EventAlert(event.EventBase): def __init__(self, msg): super(EventAlert, self).__init__() self.msg = msg class SnortLib(app_manager.RyuApp): def __init__(self): super(SnortLib, self).__init__() self.name = 'snortlib' self.config = {'unixsock': True} self._set_logger() self.sock = None self.nwsock = None def set_config(self, config): assert isinstance(config, dict) self.config = config def start_socket_server(self): if not self.config.get('unixsock'): if self.config.get('port') is None: self.config['port'] = 51234 self._start_recv_nw_sock(self.config.get('port')) else: self._start_recv() self.logger.info(self.config) def _recv_loop(self): self.logger.info("Unix socket start listening...") while True: data = self.sock.recv(BUFSIZE) msg = alert.AlertPkt.parser(data) if msg: self.send_event_to_observers(EventAlert(msg)) def _start_recv(self): if os.path.exists(SOCKFILE): os.unlink(SOCKFILE) self.sock = hub.socket.socket(hub.socket.AF_UNIX, hub.socket.SOCK_DGRAM) self.sock.bind(SOCKFILE) hub.spawn(self._recv_loop) def _start_recv_nw_sock(self, port): self.nwsock = hub.socket.socket(hub.socket.AF_INET, hub.socket.SOCK_STREAM) self.nwsock.setsockopt(hub.socket.SOL_SOCKET, hub.socket.SO_REUSEADDR, 1) self.nwsock.bind(('0.0.0.0', port)) self.nwsock.listen(5) hub.spawn(self._accept_loop_nw_sock) def _accept_loop_nw_sock(self): self.logger.info("Network socket server start listening...") while True: conn, addr = self.nwsock.accept() self.logger.info("Connected with %s", addr[0]) hub.spawn(self._recv_loop_nw_sock, conn, addr) def _recv_loop_nw_sock(self, conn, addr): buf = six.binary_type() while True: ret = conn.recv(BUFSIZE) if len(ret) == 0: self.logger.info("Disconnected from %s", addr[0]) break buf += ret while len(buf) >= BUFSIZE: # self.logger.debug("Received buffer size: %d", len(buf)) data = buf[:BUFSIZE] msg = alert.AlertPkt.parser(data) if msg: self.send_event_to_observers(EventAlert(msg)) buf = buf[BUFSIZE:] def _set_logger(self): """change log format.""" self.logger.propagate = False hdl = logging.StreamHandler() fmt_str = '[snort][%(levelname)s] %(message)s' hdl.setFormatter(logging.Formatter(fmt_str)) self.logger.addHandler(hdl)