1 /*
2  * Copyright (C) 2008 Sun Microsystems
3  *
4  * This file is part of uperf.
5  *
6  * uperf is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 3
8  * as published by the Free Software Foundation.
9  *
10  * uperf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with uperf.  If not, see http://www.gnu.org/licenses/.
17  */
18 
19 /*
20  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved. Use is
21  * subject to license terms.
22  */
23 #ifdef HAVE_CONFIG_H
24 #include "../config.h"
25 #endif /* HAVE_CONFIG_H */
26 
27 #include <netinet/in.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <assert.h>
32 
33 #include "uperf.h"
34 #include "protocol.h"
35 
36 #ifdef HAVE_SSL
37 #include "ssl.h"
38 #endif /* HAVE_SSL */
39 
40 #include "generic.h"
41 #include "logging.h"
42 
43 protocol_t *protocol_tcp_init(char *host, int port);
44 protocol_t *protocol_udp_init(char *rhost, int port);
45 void protocol_udp_fini(protocol_t *p);
46 void protocol_rds_fini(protocol_t *p);
47 
48 int tcp_init(void *);
49 int udp_init(void *);
50 int ssl_init(void *);
51 int sctp_init(void *);
52 protocol_t *protocol_tcp_create(char *, int);
53 protocol_t *protocol_udp_create(char *, int);
54 protocol_t *protocol_ssl_create(char *, int);
55 protocol_t *protocol_sctp_create(char *, int);
56 protocol_t *protocol_rds_create(char *, int);
57 
58 void generic_fini(protocol_t *);
59 void udp_fini(protocol_t *);
60 void rds_fini(protocol_t *);
61 void ssl_fini(protocol_t *);
62 
63 typedef int (*init_func)(void *);
64 typedef protocol_t * (*create_func)(char *, int);
65 typedef void (*destroy_func)(protocol_t *);
66 
67 typedef struct pdetails {
68 	char protocol[16];
69 	proto_type_t type;
70 	init_func init;
71 	create_func create;
72 	destroy_func destroy;
73 }proto_list_t;
74 
75 static proto_list_t plist[] = {
76 	{ "tcp", PROTOCOL_TCP, NULL, protocol_tcp_create, generic_fini},
77 	{ "udp", PROTOCOL_UDP, NULL, protocol_udp_create, udp_fini },
78 #ifdef HAVE_RDS
79 	{ "rds", PROTOCOL_RDS, NULL, protocol_rds_create, rds_fini },
80 #endif /* HAVE_RDS */
81 #ifdef HAVE_SCTP
82 	{ "sctp", PROTOCOL_SCTP, NULL, protocol_sctp_create, generic_fini},
83 #endif /* HAVE_SCTP */
84 #ifdef HAVE_SSL
85 	{ "ssl", PROTOCOL_SSL, ssl_init, protocol_ssl_create, ssl_fini},
86 #endif /* HAVE_SSL */
87 };
88 
89 static proto_list_t *
find_protocol_by_name(char * name)90 find_protocol_by_name(char *name)
91 {
92 	int i;
93 	for (i = 0; i < sizeof (plist)/ sizeof (proto_list_t); i++) {
94 		if (strcasecmp(name, plist[i].protocol) == 0)
95 			return (&plist[i]);
96 	}
97 
98 	return (0);
99 }
100 
101 static proto_list_t *
find_protocol_by_type(proto_type_t type)102 find_protocol_by_type(proto_type_t type)
103 {
104 	int i;
105 	for (i = 0; i < sizeof (plist)/ sizeof (proto_list_t); i++) {
106 		if (type == plist[i].type)
107 			return (&plist[i]);
108 	}
109 
110 	return (0);
111 }
112 
113 int
protocol_init(void * arg)114 protocol_init(void *arg)
115 {
116 	int i;
117 	for (i = 0; i < sizeof (plist)/ sizeof (proto_list_t); i++) {
118 		if (plist[i].init) {
119 			if (plist[i].init(arg) == UPERF_FAILURE)
120 				return (UPERF_FAILURE);
121 		}
122 	}
123 	return (UPERF_SUCCESS);
124 }
125 
126 protocol_t *
create_protocol(proto_type_t type,char * host,int port,int run_type)127 create_protocol(proto_type_t type, char *host, int port, int run_type)
128 {
129 	proto_list_t *pl = find_protocol_by_type(type);
130 
131 	ASSERT(pl);
132 	ASSERT(pl->create);
133 	return (pl->create(host, port));
134 }
135 
136 void
destroy_protocol(proto_type_t type,protocol_t * p)137 destroy_protocol(proto_type_t type, protocol_t *p)
138 {
139 	proto_list_t *pl = find_protocol_by_type(type);
140 	ASSERT(type > 0);
141 	ASSERT(pl);
142 	ASSERT(pl->destroy);
143 	pl->destroy(p);
144 }
145 
146 proto_type_t
protocol_type(char * protocol)147 protocol_type(char *protocol)
148 {
149 	proto_list_t *pl = find_protocol_by_name(protocol);
150 
151 	return (pl ? pl->type : PROTOCOL_UNSUPPORTED);
152 }
153 
154 int
valid_protocol(proto_type_t type)155 valid_protocol(proto_type_t type)
156 {
157 	proto_list_t *pl = find_protocol_by_type(type);
158 
159 	return (pl ? 1 : -1);
160 }
161 
162 const char *
protocol_to_str(proto_type_t t)163 protocol_to_str(proto_type_t t)
164 {
165 	switch (t) {
166 		case PROTOCOL_TCP: return "TCP";
167 		case PROTOCOL_UDAPL: return "uDAPL";
168 		case PROTOCOL_UDP: return "UDP";
169 		case PROTOCOL_SSL: return "SSL";
170 		case PROTOCOL_SCTP: return "SCTP";
171 		default: return "Unknown";
172 	}
173 }
174