xref: /openbmc/ipmitool/src/plugins/ipmi_intf.c (revision dfdfd89ec9b36c115a98f589880fd757a162af19)
1c18ec02fSPetter Reinholdtsen /*
2c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
3c18ec02fSPetter Reinholdtsen  *
4c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
6c18ec02fSPetter Reinholdtsen  * are met:
7c18ec02fSPetter Reinholdtsen  *
8c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
9c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
10c18ec02fSPetter Reinholdtsen  *
11c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
12c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
13c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
14c18ec02fSPetter Reinholdtsen  *
15c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
16c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
17c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
18c18ec02fSPetter Reinholdtsen  *
19c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
20c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31c18ec02fSPetter Reinholdtsen  */
32ce02ffafSZdenek Styblik #define _XOPEN_SOURCE 700
33ce02ffafSZdenek Styblik #define _GNU_SOURCE 1
34c18ec02fSPetter Reinholdtsen 
35c18ec02fSPetter Reinholdtsen #include <stdio.h>
36c18ec02fSPetter Reinholdtsen #include <stdlib.h>
37c18ec02fSPetter Reinholdtsen #include <string.h>
38c18ec02fSPetter Reinholdtsen #if defined(HAVE_CONFIG_H)
39c18ec02fSPetter Reinholdtsen # include <config.h>
40c18ec02fSPetter Reinholdtsen #endif
41c18ec02fSPetter Reinholdtsen 
42c18ec02fSPetter Reinholdtsen #if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)
43c18ec02fSPetter Reinholdtsen #include <sys/types.h>
44c18ec02fSPetter Reinholdtsen #include <sys/socket.h>
45c18ec02fSPetter Reinholdtsen #include <netinet/in.h>
46c18ec02fSPetter Reinholdtsen #include <arpa/inet.h>
47c18ec02fSPetter Reinholdtsen #include <ifaddrs.h>
48c18ec02fSPetter Reinholdtsen #include <unistd.h>
49c18ec02fSPetter Reinholdtsen #include <netdb.h>
50c18ec02fSPetter Reinholdtsen #endif
51c18ec02fSPetter Reinholdtsen 
52c18ec02fSPetter Reinholdtsen 
53c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
54c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
55c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
56c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
57c18ec02fSPetter Reinholdtsen 
5823e9340bSZdenek Styblik #define IPMI_DEFAULT_PAYLOAD_SIZE   25
5923e9340bSZdenek Styblik 
60c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_OPEN
61c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_open_intf;
62c18ec02fSPetter Reinholdtsen #endif
63c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_IMB
64c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_imb_intf;
65c18ec02fSPetter Reinholdtsen #endif
66c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_LIPMI
67c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_lipmi_intf;
68c18ec02fSPetter Reinholdtsen #endif
69c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_BMC
70c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_bmc_intf;
71c18ec02fSPetter Reinholdtsen #endif
72c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_LAN
73c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_lan_intf;
74c18ec02fSPetter Reinholdtsen #endif
75c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_LANPLUS
76c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_lanplus_intf;
77c18ec02fSPetter Reinholdtsen #endif
78c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_FREE
79c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_free_intf;
80c18ec02fSPetter Reinholdtsen #endif
81c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_SERIAL
82c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_serial_term_intf;
83c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_serial_bm_intf;
84c18ec02fSPetter Reinholdtsen #endif
85c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_DUMMY
86c18ec02fSPetter Reinholdtsen extern struct ipmi_intf ipmi_dummy_intf;
87c18ec02fSPetter Reinholdtsen #endif
88e2c5b322SZdenek Styblik #ifdef IPMI_INTF_USB
89e2c5b322SZdenek Styblik extern struct ipmi_intf ipmi_usb_intf;
90e2c5b322SZdenek Styblik #endif
91069e132eSJeremy Kerr #ifdef IPMI_INTF_DBUS
92069e132eSJeremy Kerr extern struct ipmi_intf ipmi_dbus_intf;
93069e132eSJeremy Kerr #endif
94c18ec02fSPetter Reinholdtsen 
95c18ec02fSPetter Reinholdtsen struct ipmi_intf * ipmi_intf_table[] = {
96*dfdfd89eSVernon Mauery #ifdef IPMI_INTF_DBUS
97*dfdfd89eSVernon Mauery 	&ipmi_dbus_intf,
98*dfdfd89eSVernon Mauery #endif
99c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_OPEN
100c18ec02fSPetter Reinholdtsen 	&ipmi_open_intf,
101c18ec02fSPetter Reinholdtsen #endif
102c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_IMB
103c18ec02fSPetter Reinholdtsen 	&ipmi_imb_intf,
104c18ec02fSPetter Reinholdtsen #endif
105c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_LIPMI
106c18ec02fSPetter Reinholdtsen 	&ipmi_lipmi_intf,
107c18ec02fSPetter Reinholdtsen #endif
108c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_BMC
109c18ec02fSPetter Reinholdtsen 	&ipmi_bmc_intf,
110c18ec02fSPetter Reinholdtsen #endif
111c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_LAN
112c18ec02fSPetter Reinholdtsen 	&ipmi_lan_intf,
113c18ec02fSPetter Reinholdtsen #endif
114c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_LANPLUS
115c18ec02fSPetter Reinholdtsen 	&ipmi_lanplus_intf,
116c18ec02fSPetter Reinholdtsen #endif
117c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_FREE
118c18ec02fSPetter Reinholdtsen 	&ipmi_free_intf,
119c18ec02fSPetter Reinholdtsen #endif
120c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_SERIAL
121c18ec02fSPetter Reinholdtsen 	&ipmi_serial_term_intf,
122c18ec02fSPetter Reinholdtsen 	&ipmi_serial_bm_intf,
123c18ec02fSPetter Reinholdtsen #endif
124c18ec02fSPetter Reinholdtsen #ifdef IPMI_INTF_DUMMY
125c18ec02fSPetter Reinholdtsen 	&ipmi_dummy_intf,
126c18ec02fSPetter Reinholdtsen #endif
127e2c5b322SZdenek Styblik #ifdef IPMI_INTF_USB
128e2c5b322SZdenek Styblik 	&ipmi_usb_intf,
129e2c5b322SZdenek Styblik #endif
130c18ec02fSPetter Reinholdtsen 	NULL
131c18ec02fSPetter Reinholdtsen };
132c18ec02fSPetter Reinholdtsen 
133c18ec02fSPetter Reinholdtsen /* ipmi_intf_print  -  Print list of interfaces
134c18ec02fSPetter Reinholdtsen  *
135c18ec02fSPetter Reinholdtsen  * no meaningful return code
136c18ec02fSPetter Reinholdtsen  */
ipmi_intf_print(struct ipmi_intf_support * intflist)137c18ec02fSPetter Reinholdtsen void ipmi_intf_print(struct ipmi_intf_support * intflist)
138c18ec02fSPetter Reinholdtsen {
139c18ec02fSPetter Reinholdtsen 	struct ipmi_intf ** intf;
140c18ec02fSPetter Reinholdtsen 	struct ipmi_intf_support * sup;
141c18ec02fSPetter Reinholdtsen 	int def = 1;
142c18ec02fSPetter Reinholdtsen 	int found;
143c18ec02fSPetter Reinholdtsen 
144c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "Interfaces:");
145c18ec02fSPetter Reinholdtsen 
146c18ec02fSPetter Reinholdtsen 	for (intf = ipmi_intf_table; intf && *intf; intf++) {
147c18ec02fSPetter Reinholdtsen 
148c18ec02fSPetter Reinholdtsen 		if (intflist != NULL) {
149c18ec02fSPetter Reinholdtsen 			found = 0;
150c18ec02fSPetter Reinholdtsen 			for (sup=intflist; sup->name != NULL; sup++) {
151c18ec02fSPetter Reinholdtsen 				if (strncmp(sup->name, (*intf)->name, strlen(sup->name)) == 0 &&
152c18ec02fSPetter Reinholdtsen 				    strncmp(sup->name, (*intf)->name, strlen((*intf)->name)) == 0 &&
153c18ec02fSPetter Reinholdtsen 				    sup->supported == 1)
154c18ec02fSPetter Reinholdtsen 					found = 1;
155c18ec02fSPetter Reinholdtsen 			}
156c18ec02fSPetter Reinholdtsen 			if (found == 0)
157c18ec02fSPetter Reinholdtsen 				continue;
158c18ec02fSPetter Reinholdtsen 		}
159c18ec02fSPetter Reinholdtsen 
160c18ec02fSPetter Reinholdtsen 		lprintf(LOG_NOTICE, "\t%-12s  %s %s",
161c18ec02fSPetter Reinholdtsen 			(*intf)->name, (*intf)->desc,
162c18ec02fSPetter Reinholdtsen 			def ? "[default]" : "");
163c18ec02fSPetter Reinholdtsen 		def = 0;
164c18ec02fSPetter Reinholdtsen 	}
165c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "");
166c18ec02fSPetter Reinholdtsen }
167c18ec02fSPetter Reinholdtsen 
168c18ec02fSPetter Reinholdtsen /* ipmi_intf_load  -  Load an interface from the interface table above
169c18ec02fSPetter Reinholdtsen  *                    If no interface name is given return first entry
170c18ec02fSPetter Reinholdtsen  *
171c18ec02fSPetter Reinholdtsen  * @name:	interface name to try and load
172c18ec02fSPetter Reinholdtsen  *
173c18ec02fSPetter Reinholdtsen  * returns pointer to inteface structure if found
174c18ec02fSPetter Reinholdtsen  * returns NULL on error
175c18ec02fSPetter Reinholdtsen  */
ipmi_intf_load(char * name)176c18ec02fSPetter Reinholdtsen struct ipmi_intf * ipmi_intf_load(char * name)
177c18ec02fSPetter Reinholdtsen {
178c18ec02fSPetter Reinholdtsen 	struct ipmi_intf ** intf;
179c18ec02fSPetter Reinholdtsen 	struct ipmi_intf * i;
180c18ec02fSPetter Reinholdtsen 
181c18ec02fSPetter Reinholdtsen 	if (name == NULL) {
182c18ec02fSPetter Reinholdtsen 		i = ipmi_intf_table[0];
183c18ec02fSPetter Reinholdtsen 		if (i->setup != NULL && (i->setup(i) < 0)) {
184c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Unable to setup "
185c18ec02fSPetter Reinholdtsen 				"interface %s", name);
186c18ec02fSPetter Reinholdtsen 			return NULL;
187c18ec02fSPetter Reinholdtsen 		}
188c18ec02fSPetter Reinholdtsen 		return i;
189c18ec02fSPetter Reinholdtsen 	}
190c18ec02fSPetter Reinholdtsen 
191c18ec02fSPetter Reinholdtsen 	for (intf = ipmi_intf_table;
192c18ec02fSPetter Reinholdtsen 	     ((intf != NULL) && (*intf != NULL));
193c18ec02fSPetter Reinholdtsen 	     intf++) {
194c18ec02fSPetter Reinholdtsen 		i = *intf;
195c18ec02fSPetter Reinholdtsen 		if (strncmp(name, i->name, strlen(name)) == 0) {
196c18ec02fSPetter Reinholdtsen 			if (i->setup != NULL && (i->setup(i) < 0)) {
197c18ec02fSPetter Reinholdtsen 				lprintf(LOG_ERR, "Unable to setup "
198c18ec02fSPetter Reinholdtsen 					"interface %s", name);
199c18ec02fSPetter Reinholdtsen 				return NULL;
200c18ec02fSPetter Reinholdtsen 			}
201c18ec02fSPetter Reinholdtsen 			return i;
202c18ec02fSPetter Reinholdtsen 		}
203c18ec02fSPetter Reinholdtsen 	}
204c18ec02fSPetter Reinholdtsen 
205c18ec02fSPetter Reinholdtsen 	return NULL;
206c18ec02fSPetter Reinholdtsen }
207c18ec02fSPetter Reinholdtsen 
208c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_hostname(struct ipmi_intf * intf,char * hostname)209c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname)
210c18ec02fSPetter Reinholdtsen {
211eb541367SZdenek Styblik 	if (intf->ssn_params.hostname != NULL) {
212eb541367SZdenek Styblik 		free(intf->ssn_params.hostname);
213eb541367SZdenek Styblik 		intf->ssn_params.hostname = NULL;
214eb541367SZdenek Styblik 	}
215eb541367SZdenek Styblik 	if (hostname == NULL) {
216c18ec02fSPetter Reinholdtsen 		return;
217c18ec02fSPetter Reinholdtsen 	}
218eb541367SZdenek Styblik 	intf->ssn_params.hostname = strdup(hostname);
219c18ec02fSPetter Reinholdtsen }
220c18ec02fSPetter Reinholdtsen 
221c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_username(struct ipmi_intf * intf,char * username)222c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
223c18ec02fSPetter Reinholdtsen {
224eb541367SZdenek Styblik 	memset(intf->ssn_params.username, 0, 17);
225c18ec02fSPetter Reinholdtsen 
226c18ec02fSPetter Reinholdtsen 	if (username == NULL)
227c18ec02fSPetter Reinholdtsen 		return;
228c18ec02fSPetter Reinholdtsen 
229eb541367SZdenek Styblik 	memcpy(intf->ssn_params.username, username, __min(strlen(username), 16));
230c18ec02fSPetter Reinholdtsen }
231c18ec02fSPetter Reinholdtsen 
232c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_password(struct ipmi_intf * intf,char * password)233c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password)
234c18ec02fSPetter Reinholdtsen {
235eb541367SZdenek Styblik 	memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE);
236c18ec02fSPetter Reinholdtsen 
237c18ec02fSPetter Reinholdtsen 	if (password == NULL) {
238eb541367SZdenek Styblik 		intf->ssn_params.password = 0;
239c18ec02fSPetter Reinholdtsen 		return;
240c18ec02fSPetter Reinholdtsen 	}
241c18ec02fSPetter Reinholdtsen 
242eb541367SZdenek Styblik 	intf->ssn_params.password = 1;
243eb541367SZdenek Styblik 	memcpy(intf->ssn_params.authcode_set, password,
244c18ec02fSPetter Reinholdtsen 	       __min(strlen(password), IPMI_AUTHCODE_BUFFER_SIZE));
245c18ec02fSPetter Reinholdtsen }
246c18ec02fSPetter Reinholdtsen 
247c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_privlvl(struct ipmi_intf * intf,uint8_t level)248c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)
249c18ec02fSPetter Reinholdtsen {
250eb541367SZdenek Styblik 	intf->ssn_params.privlvl = level;
251c18ec02fSPetter Reinholdtsen }
252c18ec02fSPetter Reinholdtsen 
253c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf,uint8_t lookupbit)254c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit)
255c18ec02fSPetter Reinholdtsen {
256eb541367SZdenek Styblik 	intf->ssn_params.lookupbit = lookupbit;
257c18ec02fSPetter Reinholdtsen }
258c18ec02fSPetter Reinholdtsen 
259c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf,uint8_t cipher_suite_id)260c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)
261c18ec02fSPetter Reinholdtsen {
262eb541367SZdenek Styblik 	intf->ssn_params.cipher_suite_id = cipher_suite_id;
263c18ec02fSPetter Reinholdtsen }
264c18ec02fSPetter Reinholdtsen 
265c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf,char sol_escape_char)266c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char)
267c18ec02fSPetter Reinholdtsen {
268eb541367SZdenek Styblik 	intf->ssn_params.sol_escape_char = sol_escape_char;
269c18ec02fSPetter Reinholdtsen }
270c18ec02fSPetter Reinholdtsen 
271c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_kgkey(struct ipmi_intf * intf,char * kgkey)272c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey)
273c18ec02fSPetter Reinholdtsen {
274eb541367SZdenek Styblik 	memset(intf->ssn_params.kg, 0, IPMI_KG_BUFFER_SIZE);
275c18ec02fSPetter Reinholdtsen 
276c18ec02fSPetter Reinholdtsen 	if (kgkey == NULL)
277c18ec02fSPetter Reinholdtsen 		return;
278c18ec02fSPetter Reinholdtsen 
279eb541367SZdenek Styblik 	memcpy(intf->ssn_params.kg, kgkey,
280c18ec02fSPetter Reinholdtsen 	       __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));
281c18ec02fSPetter Reinholdtsen }
282c18ec02fSPetter Reinholdtsen 
283c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_port(struct ipmi_intf * intf,int port)284c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
285c18ec02fSPetter Reinholdtsen {
286eb541367SZdenek Styblik 	intf->ssn_params.port = port;
287c18ec02fSPetter Reinholdtsen }
288c18ec02fSPetter Reinholdtsen 
289c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_authtype(struct ipmi_intf * intf,uint8_t authtype)290c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype)
291c18ec02fSPetter Reinholdtsen {
292c18ec02fSPetter Reinholdtsen 	/* clear password field if authtype NONE specified */
293c18ec02fSPetter Reinholdtsen 	if (authtype == IPMI_SESSION_AUTHTYPE_NONE) {
294eb541367SZdenek Styblik 		memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE);
295eb541367SZdenek Styblik 		intf->ssn_params.password = 0;
296c18ec02fSPetter Reinholdtsen 	}
297c18ec02fSPetter Reinholdtsen 
298eb541367SZdenek Styblik 	intf->ssn_params.authtype_set = authtype;
299c18ec02fSPetter Reinholdtsen }
300c18ec02fSPetter Reinholdtsen 
301c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_timeout(struct ipmi_intf * intf,uint32_t timeout)302c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout)
303c18ec02fSPetter Reinholdtsen {
304eb541367SZdenek Styblik 	intf->ssn_params.timeout = timeout;
305c18ec02fSPetter Reinholdtsen }
306c18ec02fSPetter Reinholdtsen 
307c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_set_retry(struct ipmi_intf * intf,int retry)308c18ec02fSPetter Reinholdtsen ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry)
309c18ec02fSPetter Reinholdtsen {
310eb541367SZdenek Styblik 	intf->ssn_params.retry = retry;
311c18ec02fSPetter Reinholdtsen }
312c18ec02fSPetter Reinholdtsen 
313c18ec02fSPetter Reinholdtsen void
ipmi_intf_session_cleanup(struct ipmi_intf * intf)314deb9a4edSZdenek Styblik ipmi_intf_session_cleanup(struct ipmi_intf *intf)
315deb9a4edSZdenek Styblik {
316deb9a4edSZdenek Styblik 	if (intf->session == NULL) {
317deb9a4edSZdenek Styblik 		return;
318deb9a4edSZdenek Styblik 	}
319eb541367SZdenek Styblik 
320deb9a4edSZdenek Styblik 	free(intf->session);
321deb9a4edSZdenek Styblik 	intf->session = NULL;
322deb9a4edSZdenek Styblik }
323deb9a4edSZdenek Styblik 
324deb9a4edSZdenek Styblik void
ipmi_cleanup(struct ipmi_intf * intf)325c18ec02fSPetter Reinholdtsen ipmi_cleanup(struct ipmi_intf * intf)
326c18ec02fSPetter Reinholdtsen {
327c18ec02fSPetter Reinholdtsen 	ipmi_sdr_list_empty(intf);
328eb541367SZdenek Styblik 	ipmi_intf_session_set_hostname(intf, NULL);
329c18ec02fSPetter Reinholdtsen }
330c18ec02fSPetter Reinholdtsen 
331c18ec02fSPetter Reinholdtsen #if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)
332c18ec02fSPetter Reinholdtsen int
ipmi_intf_socket_connect(struct ipmi_intf * intf)333c18ec02fSPetter Reinholdtsen ipmi_intf_socket_connect(struct ipmi_intf * intf)
334c18ec02fSPetter Reinholdtsen {
335eb541367SZdenek Styblik 	struct ipmi_session_params *params;
336c18ec02fSPetter Reinholdtsen 
337c18ec02fSPetter Reinholdtsen 	struct sockaddr_storage addr;
338c18ec02fSPetter Reinholdtsen 	struct addrinfo hints;
339c18ec02fSPetter Reinholdtsen 	struct addrinfo *rp0 = NULL, *rp;
340c18ec02fSPetter Reinholdtsen 	char service[NI_MAXSERV];
341c18ec02fSPetter Reinholdtsen 
342eb541367SZdenek Styblik 	if (!intf) {
343c18ec02fSPetter Reinholdtsen 		return -1;
344c18ec02fSPetter Reinholdtsen 	}
345c18ec02fSPetter Reinholdtsen 
346eb541367SZdenek Styblik 	params = &intf->ssn_params;
347c18ec02fSPetter Reinholdtsen 
348eb541367SZdenek Styblik 	if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) {
349c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "No hostname specified!");
350c18ec02fSPetter Reinholdtsen 		return -1;
351c18ec02fSPetter Reinholdtsen 	}
352c18ec02fSPetter Reinholdtsen 
353c18ec02fSPetter Reinholdtsen 	/* open port to BMC */
354c18ec02fSPetter Reinholdtsen 	memset(&addr, 0, sizeof(addr));
355c18ec02fSPetter Reinholdtsen 
356eb541367SZdenek Styblik 	sprintf(service, "%d", params->port);
357c18ec02fSPetter Reinholdtsen 	/* Obtain address(es) matching host/port */
358c18ec02fSPetter Reinholdtsen 	memset(&hints, 0, sizeof(hints));
359c18ec02fSPetter Reinholdtsen 	hints.ai_family   = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
360c18ec02fSPetter Reinholdtsen 	hints.ai_socktype = SOCK_DGRAM;   /* Datagram socket */
361c18ec02fSPetter Reinholdtsen 	hints.ai_flags    = 0;            /* use AI_NUMERICSERV for no name resolution */
362c18ec02fSPetter Reinholdtsen 	hints.ai_protocol = IPPROTO_UDP; /*  */
363c18ec02fSPetter Reinholdtsen 
364eb541367SZdenek Styblik 	if (getaddrinfo(params->hostname, service, &hints, &rp0) != 0) {
365c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Address lookup for %s failed",
366eb541367SZdenek Styblik 				params->hostname);
367c18ec02fSPetter Reinholdtsen 		return -1;
368c18ec02fSPetter Reinholdtsen 	}
369c18ec02fSPetter Reinholdtsen 
370c18ec02fSPetter Reinholdtsen 	/* getaddrinfo() returns a list of address structures.
371c18ec02fSPetter Reinholdtsen 	 * Try each address until we successfully connect(2).
372c18ec02fSPetter Reinholdtsen 	 * If socket(2) (or connect(2)) fails, we (close the socket
373c18ec02fSPetter Reinholdtsen 	 * and) try the next address.
374c18ec02fSPetter Reinholdtsen 	 */
375c18ec02fSPetter Reinholdtsen 
376c18ec02fSPetter Reinholdtsen 	for (rp = rp0; rp != NULL; rp = rp->ai_next) {
377c18ec02fSPetter Reinholdtsen 		/* We are only interested in IPv4 and IPv6 */
378c18ec02fSPetter Reinholdtsen 		if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) {
379c18ec02fSPetter Reinholdtsen 			continue;
380c18ec02fSPetter Reinholdtsen 		}
381c18ec02fSPetter Reinholdtsen 
382c18ec02fSPetter Reinholdtsen 		intf->fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
383c18ec02fSPetter Reinholdtsen 		if (intf->fd == -1) {
384c18ec02fSPetter Reinholdtsen 			continue;
385c18ec02fSPetter Reinholdtsen 		}
386c18ec02fSPetter Reinholdtsen 
387c18ec02fSPetter Reinholdtsen 		if (rp->ai_family == AF_INET) {
388c18ec02fSPetter Reinholdtsen 			if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
389eb541367SZdenek Styblik 				hints.ai_family = rp->ai_family;
390c18ec02fSPetter Reinholdtsen 				break;  /* Success */
391c18ec02fSPetter Reinholdtsen 			}
392c18ec02fSPetter Reinholdtsen 		}  else if (rp->ai_family == AF_INET6) {
393c18ec02fSPetter Reinholdtsen 			struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)rp->ai_addr;
394c18ec02fSPetter Reinholdtsen 			char hbuf[NI_MAXHOST];
395c18ec02fSPetter Reinholdtsen 			socklen_t len;
396c18ec02fSPetter Reinholdtsen 
397c18ec02fSPetter Reinholdtsen 			/* The scope was specified on the command line e.g. with -H FE80::219:99FF:FEA0:BD95%eth0 */
398c18ec02fSPetter Reinholdtsen 			if (addr6->sin6_scope_id != 0) {
399c18ec02fSPetter Reinholdtsen 				len = sizeof(struct sockaddr_in6);
400c18ec02fSPetter Reinholdtsen 				if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
401c18ec02fSPetter Reinholdtsen 					lprintf(LOG_DEBUG, "Trying address: %s scope=%d",
402c18ec02fSPetter Reinholdtsen 						hbuf,
403c18ec02fSPetter Reinholdtsen 						addr6->sin6_scope_id);
404c18ec02fSPetter Reinholdtsen 				}
405c18ec02fSPetter Reinholdtsen 				if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
406eb541367SZdenek Styblik 					hints.ai_family = rp->ai_family;
407c18ec02fSPetter Reinholdtsen 					break;  /* Success */
408c18ec02fSPetter Reinholdtsen 				}
409c18ec02fSPetter Reinholdtsen 			} else {
410c18ec02fSPetter Reinholdtsen 				/* No scope specified, try to get this from the list of interfaces */
411c18ec02fSPetter Reinholdtsen 				struct ifaddrs *ifaddrs = NULL;
412c18ec02fSPetter Reinholdtsen 				struct ifaddrs *ifa = NULL;
413c18ec02fSPetter Reinholdtsen 
414c18ec02fSPetter Reinholdtsen 				if (getifaddrs(&ifaddrs) < 0) {
415c18ec02fSPetter Reinholdtsen 					lprintf(LOG_ERR, "Interface address lookup for %s failed",
416eb541367SZdenek Styblik 						params->hostname);
417c18ec02fSPetter Reinholdtsen 					break;
418c18ec02fSPetter Reinholdtsen 				}
419c18ec02fSPetter Reinholdtsen 
420c18ec02fSPetter Reinholdtsen 				for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
421c18ec02fSPetter Reinholdtsen 					if (ifa->ifa_addr == NULL) {
422c18ec02fSPetter Reinholdtsen 						continue;
423c18ec02fSPetter Reinholdtsen 					}
424c18ec02fSPetter Reinholdtsen 
425c18ec02fSPetter Reinholdtsen 					if (ifa->ifa_addr->sa_family == AF_INET6) {
426c18ec02fSPetter Reinholdtsen 						struct sockaddr_in6 *tmp6 = (struct sockaddr_in6 *)ifa->ifa_addr;
427c18ec02fSPetter Reinholdtsen 
428c18ec02fSPetter Reinholdtsen 						/* Skip unwanted addresses */
429c18ec02fSPetter Reinholdtsen 						if (IN6_IS_ADDR_MULTICAST(&tmp6->sin6_addr)) {
430c18ec02fSPetter Reinholdtsen 							continue;
431c18ec02fSPetter Reinholdtsen 						}
432c18ec02fSPetter Reinholdtsen 						if (IN6_IS_ADDR_LOOPBACK(&tmp6->sin6_addr)) {
433c18ec02fSPetter Reinholdtsen 							continue;
434c18ec02fSPetter Reinholdtsen 						}
435c18ec02fSPetter Reinholdtsen 						len = sizeof(struct sockaddr_in6);
436c18ec02fSPetter Reinholdtsen 						if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) {
437c18ec02fSPetter Reinholdtsen 							lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d",
438c18ec02fSPetter Reinholdtsen 								ifa->ifa_name != NULL ? ifa->ifa_name : "???",
439c18ec02fSPetter Reinholdtsen 								hbuf,
440c18ec02fSPetter Reinholdtsen 								tmp6->sin6_scope_id);
441c18ec02fSPetter Reinholdtsen 						}
442c18ec02fSPetter Reinholdtsen 
443c18ec02fSPetter Reinholdtsen 						if (tmp6->sin6_scope_id != 0) {
444c18ec02fSPetter Reinholdtsen 							addr6->sin6_scope_id = tmp6->sin6_scope_id;
445c18ec02fSPetter Reinholdtsen 						} else {
446c18ec02fSPetter Reinholdtsen 							/*
447c18ec02fSPetter Reinholdtsen 							 * No scope information in interface address information
448c18ec02fSPetter Reinholdtsen 							 * On some OS'es, getifaddrs() is returning out the 'kernel' representation
449c18ec02fSPetter Reinholdtsen 							 * of scoped addresses which stores the scope in the 3rd and 4th
450c18ec02fSPetter Reinholdtsen 							 * byte. See also this page:
451c18ec02fSPetter Reinholdtsen 							 * http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html
452c18ec02fSPetter Reinholdtsen 							 */
453c18ec02fSPetter Reinholdtsen 							if (IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr)
4544c5058cdSGaurav Jain 									&& (tmp6->sin6_addr.s6_addr[1] != 0)) {
4554c5058cdSGaurav Jain 								addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr[1]);
456c18ec02fSPetter Reinholdtsen 							}
457c18ec02fSPetter Reinholdtsen 						}
458c18ec02fSPetter Reinholdtsen 
459c18ec02fSPetter Reinholdtsen 						/* OK, now try to connect with the scope id from this interface address */
460c18ec02fSPetter Reinholdtsen 						if (addr6->sin6_scope_id != 0) {
461c18ec02fSPetter Reinholdtsen 							if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) {
462eb541367SZdenek Styblik 								hints.ai_family = rp->ai_family;
463c18ec02fSPetter Reinholdtsen 								lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id);
464c18ec02fSPetter Reinholdtsen 								break;  /* Success */
465c18ec02fSPetter Reinholdtsen 							}
466c18ec02fSPetter Reinholdtsen 						}
467c18ec02fSPetter Reinholdtsen 					}
468c18ec02fSPetter Reinholdtsen 				}
469c18ec02fSPetter Reinholdtsen 				freeifaddrs(ifaddrs);
470c18ec02fSPetter Reinholdtsen 			}
471c18ec02fSPetter Reinholdtsen 		}
472eb541367SZdenek Styblik 		if (hints.ai_family != AF_UNSPEC) {
473c18ec02fSPetter Reinholdtsen 			break;
474c18ec02fSPetter Reinholdtsen 		}
475c18ec02fSPetter Reinholdtsen 		close(intf->fd);
476c18ec02fSPetter Reinholdtsen 		intf->fd = -1;
477c18ec02fSPetter Reinholdtsen 	}
478c18ec02fSPetter Reinholdtsen 
479c18ec02fSPetter Reinholdtsen 	/* No longer needed */
480c18ec02fSPetter Reinholdtsen 	freeaddrinfo(rp0);
481c18ec02fSPetter Reinholdtsen 
482c18ec02fSPetter Reinholdtsen 	return ((intf->fd != -1) ? 0 : -1);
483c18ec02fSPetter Reinholdtsen }
484c18ec02fSPetter Reinholdtsen #endif
485c18ec02fSPetter Reinholdtsen 
48623e9340bSZdenek Styblik uint16_t
ipmi_intf_get_max_request_data_size(struct ipmi_intf * intf)48723e9340bSZdenek Styblik ipmi_intf_get_max_request_data_size(struct ipmi_intf * intf)
48823e9340bSZdenek Styblik {
48923e9340bSZdenek Styblik 	int16_t size;
49023e9340bSZdenek Styblik 
49123e9340bSZdenek Styblik 	size = intf->max_request_data_size;
49223e9340bSZdenek Styblik 
49323e9340bSZdenek Styblik 	/* check if request size is not specified */
49423e9340bSZdenek Styblik 	if (!size) {
49523e9340bSZdenek Styblik 		/*
49623e9340bSZdenek Styblik 		 * The IPMB standard overall message length for �non -bridging�
49723e9340bSZdenek Styblik 		 * messages is specified as 32 bytes, maximum, including slave
49823e9340bSZdenek Styblik 		 * address. This sets the upper limit for typical IPMI messages.
49923e9340bSZdenek Styblik 		 * With the exception of messages used for bridging messages to
50023e9340bSZdenek Styblik 		 * other busses or interfaces (e.g. Master Write-Read and Send Message)
50123e9340bSZdenek Styblik 		 * IPMI messages should be designed to fit within this 32-byte maximum.
50223e9340bSZdenek Styblik 		 * In order to support bridging, the Master Write -Read and Send Message
50323e9340bSZdenek Styblik 		 * commands are allowed to exceed the 32-byte maximum transaction on IPMB
50423e9340bSZdenek Styblik 		 */
50523e9340bSZdenek Styblik 
50623e9340bSZdenek Styblik 		size = IPMI_DEFAULT_PAYLOAD_SIZE;
50723e9340bSZdenek Styblik 
50823e9340bSZdenek Styblik 		/* check if message is forwarded */
50923e9340bSZdenek Styblik 		if (intf->target_addr && intf->target_addr != intf->my_addr) {
51023e9340bSZdenek Styblik 			/* add Send Message request size */
51123e9340bSZdenek Styblik 			size += 8;
51223e9340bSZdenek Styblik 		}
51323e9340bSZdenek Styblik 	}
51423e9340bSZdenek Styblik 
51523e9340bSZdenek Styblik 	/* check if message is forwarded */
51623e9340bSZdenek Styblik 	if (intf->target_addr && intf->target_addr != intf->my_addr) {
51723e9340bSZdenek Styblik 		/* subtract send message request size */
51823e9340bSZdenek Styblik 		size -= 8;
51923e9340bSZdenek Styblik 
52023e9340bSZdenek Styblik 		/*
52123e9340bSZdenek Styblik 		 * Check that forwarded request size is not greater
52223e9340bSZdenek Styblik 		 * than the default payload size.
52323e9340bSZdenek Styblik 		 */
52423e9340bSZdenek Styblik 		if (size > IPMI_DEFAULT_PAYLOAD_SIZE) {
52523e9340bSZdenek Styblik 			size = IPMI_DEFAULT_PAYLOAD_SIZE;
52623e9340bSZdenek Styblik 		}
52723e9340bSZdenek Styblik 
52823e9340bSZdenek Styblik 		/* check for double bridging */
52923e9340bSZdenek Styblik 		if (intf->transit_addr && intf->transit_addr != intf->target_addr) {
53023e9340bSZdenek Styblik 			/* subtract inner send message request size */
53123e9340bSZdenek Styblik 			size -= 8;
53223e9340bSZdenek Styblik 		}
53323e9340bSZdenek Styblik 	}
53423e9340bSZdenek Styblik 
53523e9340bSZdenek Styblik 	/* check for underflow */
53623e9340bSZdenek Styblik 	if (size < 0) {
53723e9340bSZdenek Styblik 		return 0;
53823e9340bSZdenek Styblik 	}
53923e9340bSZdenek Styblik 
54023e9340bSZdenek Styblik 	return size;
54123e9340bSZdenek Styblik }
54223e9340bSZdenek Styblik 
54323e9340bSZdenek Styblik uint16_t
ipmi_intf_get_max_response_data_size(struct ipmi_intf * intf)54423e9340bSZdenek Styblik ipmi_intf_get_max_response_data_size(struct ipmi_intf * intf)
54523e9340bSZdenek Styblik {
54623e9340bSZdenek Styblik 	int16_t size;
54723e9340bSZdenek Styblik 
54823e9340bSZdenek Styblik 	size = intf->max_response_data_size;
54923e9340bSZdenek Styblik 
55023e9340bSZdenek Styblik 	/* check if response size is not specified */
55123e9340bSZdenek Styblik 	if (!size) {
55223e9340bSZdenek Styblik 		/*
55323e9340bSZdenek Styblik 		 * The IPMB standard overall message length for �non -bridging�
55423e9340bSZdenek Styblik 		 * messages is specified as 32 bytes, maximum, including slave
55523e9340bSZdenek Styblik 		 * address. This sets the upper limit for typical IPMI messages.
55623e9340bSZdenek Styblik 		 * With the exception of messages used for bridging messages to
55723e9340bSZdenek Styblik 		 * other busses or interfaces (e.g. Master Write-Read and Send Message)
55823e9340bSZdenek Styblik 		 * IPMI messages should be designed to fit within this 32-byte maximum.
55923e9340bSZdenek Styblik 		 * In order to support bridging, the Master Write -Read and Send Message
56023e9340bSZdenek Styblik 		 * commands are allowed to exceed the 32-byte maximum transaction on IPMB
56123e9340bSZdenek Styblik 		 */
56223e9340bSZdenek Styblik 
56323e9340bSZdenek Styblik 		size = IPMI_DEFAULT_PAYLOAD_SIZE; /* response length with subtracted header and checksum byte */
56423e9340bSZdenek Styblik 
56523e9340bSZdenek Styblik 		/* check if message is forwarded */
56623e9340bSZdenek Styblik 		if (intf->target_addr && intf->target_addr != intf->my_addr) {
56723e9340bSZdenek Styblik 			/* add Send Message header size */
56823e9340bSZdenek Styblik 			size += 7;
56923e9340bSZdenek Styblik 		}
57023e9340bSZdenek Styblik 	}
57123e9340bSZdenek Styblik 
57223e9340bSZdenek Styblik 	/* check if message is forwarded */
57323e9340bSZdenek Styblik 	if (intf->target_addr && intf->target_addr != intf->my_addr) {
57423e9340bSZdenek Styblik 		/*
57523e9340bSZdenek Styblik 		 * Some IPMI controllers like PICMG AMC Carriers embed responses
57623e9340bSZdenek Styblik 		 * to the forwarded messages into the Send Message response.
57723e9340bSZdenek Styblik 		 * In order to be sure that the response is not truncated,
57823e9340bSZdenek Styblik 		 * subtract the internal message header size.
57923e9340bSZdenek Styblik 		 */
58023e9340bSZdenek Styblik 		size -= 8;
58123e9340bSZdenek Styblik 
58223e9340bSZdenek Styblik 		/*
58323e9340bSZdenek Styblik 		 * Check that forwarded response is not greater
58423e9340bSZdenek Styblik 		 * than the default payload size.
58523e9340bSZdenek Styblik 		 */
58623e9340bSZdenek Styblik 		if (size > IPMI_DEFAULT_PAYLOAD_SIZE) {
58723e9340bSZdenek Styblik 			size = IPMI_DEFAULT_PAYLOAD_SIZE;
58823e9340bSZdenek Styblik 		}
58923e9340bSZdenek Styblik 
59023e9340bSZdenek Styblik 		/* check for double bridging */
59123e9340bSZdenek Styblik 		if (intf->transit_addr && intf->transit_addr != intf->target_addr) {
59223e9340bSZdenek Styblik 			/* subtract inner send message header size */
59323e9340bSZdenek Styblik 			size -= 8;
59423e9340bSZdenek Styblik 		}
59523e9340bSZdenek Styblik 	}
59623e9340bSZdenek Styblik 
59723e9340bSZdenek Styblik 	/* check for underflow */
59823e9340bSZdenek Styblik 	if (size < 0) {
59923e9340bSZdenek Styblik 		return 0;
60023e9340bSZdenek Styblik 	}
60123e9340bSZdenek Styblik 
60223e9340bSZdenek Styblik 	return size;
60323e9340bSZdenek Styblik }
60423e9340bSZdenek Styblik 
60523e9340bSZdenek Styblik void
ipmi_intf_set_max_request_data_size(struct ipmi_intf * intf,uint16_t size)60623e9340bSZdenek Styblik ipmi_intf_set_max_request_data_size(struct ipmi_intf * intf, uint16_t size)
60723e9340bSZdenek Styblik {
60823e9340bSZdenek Styblik 	if (size < IPMI_DEFAULT_PAYLOAD_SIZE) {
60923e9340bSZdenek Styblik 		lprintf(LOG_ERR, "Request size is too small (%d), leave default size",
61023e9340bSZdenek Styblik 				size);
61123e9340bSZdenek Styblik 		return;
61223e9340bSZdenek Styblik 	}
61323e9340bSZdenek Styblik 
61423e9340bSZdenek Styblik 	if (intf->set_max_request_data_size) {
61523e9340bSZdenek Styblik 		intf->set_max_request_data_size(intf, size);
61623e9340bSZdenek Styblik 	} else {
61723e9340bSZdenek Styblik 		intf->max_request_data_size = size;
61823e9340bSZdenek Styblik 	}
61923e9340bSZdenek Styblik }
62023e9340bSZdenek Styblik 
62123e9340bSZdenek Styblik void
ipmi_intf_set_max_response_data_size(struct ipmi_intf * intf,uint16_t size)62223e9340bSZdenek Styblik ipmi_intf_set_max_response_data_size(struct ipmi_intf * intf, uint16_t size)
62323e9340bSZdenek Styblik {
62423e9340bSZdenek Styblik 	if (size < IPMI_DEFAULT_PAYLOAD_SIZE - 1) {
62523e9340bSZdenek Styblik 		lprintf(LOG_ERR, "Response size is too small (%d), leave default size",
62623e9340bSZdenek Styblik 				size);
62723e9340bSZdenek Styblik 		return;
62823e9340bSZdenek Styblik 	}
62923e9340bSZdenek Styblik 
63023e9340bSZdenek Styblik 	if (intf->set_max_response_data_size) {
63123e9340bSZdenek Styblik 		intf->set_max_response_data_size(intf, size);
63223e9340bSZdenek Styblik 	} else {
63323e9340bSZdenek Styblik 		intf->max_response_data_size = size;
63423e9340bSZdenek Styblik 	}
63523e9340bSZdenek Styblik }
636