#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function

__description__ = 'Test the SIPHoney honeypot'
__license__ = 'GPL'
__VERSION__ = '1.0.0'
__author__ = 'Vesselin Bontchev'
__email__ = 'vbontchev@yahoo.com'


from argparse import ArgumentParser
from contextlib import contextmanager
from socket import AF_INET, IPPROTO_UDP, SOCK_DGRAM, socket, timeout
from sys import version_info


if version_info[0] >= 3:
    def decode(x):
        return x.decode('utf-8', errors='ignore')
    def encode(x):
        return x.encode()
else:
    def decode(x):
        return x
    def encode(x):
        return x


@contextmanager
def connect_to(host, port):
    connection = None
    try:
        connection = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
        connection.connect((host, int(port)))
        yield connection
    finally:
        if connection:
            connection.close()


def get_options():
    parser = ArgumentParser(description=__description__)

    parser.add_argument('-v', '--version', action='version', version='%(prog)s version ' + __VERSION__)
    parser.add_argument('-P', '--port', type=int, default=5060,
                        help='Port to send data to (default: %(default)d)')
    parser.add_argument('-H', '--host', default='127.0.0.1',
                        help='Host to communicate with (default: %(default)s)')
    parser.add_argument('-s', '--sender', default='"sipvicious"<sip:100@1.1.1.1>',
                        help='From address (default: %(default)s)')
    parser.add_argument('-t', '--to', default='<sip:user_2@test.test>',
                        help='To address (default: %(default)s)')
    parser.add_argument('-c', '--callid', default='1@0.0.0.0',
                        help='Call ID (default: %(default)s)')
    parser.add_argument('-r', '--request', default='OPTIONS',
                        help='Request (default: %(default)s)')
    args = parser.parse_args()
    return args


def main():
    args = get_options()

    with connect_to(args.host, args.port) as connection:
        payload = (
            '{} sip:user_1@test.test SIP/2.0\r\n'
            'To: {}\r\n'
            'From: {};tag=none\r\n'
            'Call-ID: {}\r\n'
            'CSeq: 1 INVITE\r\n'
            'Contact: {}\r\n'
            'Via: SIP/2.0/TCP 0.0.0.0;branch=34uiddhjczqw3mq23\r\n'
            'Content-Length: 1\r\n'
            '\r\n'
            'T'
        ).format(args.request.upper(), args.to, args.sender, args.callid, args.sender)
        connection.send(encode(payload))
        connection.settimeout(1)
        print('Response:\n')
        while True:
            try:
                data = connection.recv(2048)
                if data:
                    print(decode(data.strip().replace(b'\r\n', b'\n')))
            except timeout:
                break
            except Exception as e:
                print(e)
                break
    print()


if __name__ == '__main__':
    main()
