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