2 * EMFL Command Line Utility Linux specific code
4 * Copyright (C) 2010, Broadcom Corporation
7 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
8 * the contents of this file may not be disclosed to third parties, copied
9 * or duplicated in any form, in whole or in part, without the prior
10 * written permission of Broadcom Corporation.
12 * $Id: emfu_linux.c 241182 2011-02-17 21:50:03Z gmo $
16 #include <sys/sysctl.h>
18 #include <netinet/in.h>
23 #include <sys/socket.h>
24 #include <linux/types.h>
25 #include <linux/netlink.h>
30 #include "emfu_linux.h"
33 #define MAX_DATA_SIZE sizeof(emf_cfg_request_t)
36 emf_cfg_request_send(emf_cfg_request_t
*buffer
, int length
)
38 struct sockaddr_nl src_addr
, dest_addr
;
39 struct nlmsghdr
*nlh
= NULL
;
44 if ((buffer
== NULL
) || (length
> MAX_DATA_SIZE
))
46 fprintf(stderr
, "Invalid parameters %p %d\n", buffer
, length
);
50 /* Create a netlink socket */
51 sock_fd
= socket(PF_NETLINK
, SOCK_RAW
, NETLINK_EMFC
);
55 fprintf(stderr
, "Netlink socket create failed\n");
59 /* Associate a local address with the opened socket */
60 memset(&src_addr
, 0, sizeof(struct sockaddr_nl
));
61 src_addr
.nl_family
= AF_NETLINK
;
62 src_addr
.nl_pid
= getpid();
63 src_addr
.nl_groups
= 0;
64 bind(sock_fd
, (struct sockaddr
*)&src_addr
, sizeof(src_addr
));
66 /* Fill the destination address, pid of 0 indicates kernel */
67 memset(&dest_addr
, 0, sizeof(struct sockaddr_nl
));
68 dest_addr
.nl_family
= AF_NETLINK
;
70 dest_addr
.nl_groups
= 0;
72 /* Allocate memory for sending configuration request */
73 nlh
= (struct nlmsghdr
*)malloc(NLMSG_SPACE(MAX_DATA_SIZE
));
77 fprintf(stderr
, "Out of memory allocating cfg buffer\n");
81 /* Fill the netlink message header. The configuration request
82 * contains netlink header followed by data.
84 nlh
->nlmsg_len
= NLMSG_SPACE(MAX_DATA_SIZE
);
85 nlh
->nlmsg_pid
= getpid();
88 /* Fill the data part */
89 memcpy(NLMSG_DATA(nlh
), buffer
, length
);
90 iov
.iov_base
= (void *)nlh
;
91 iov
.iov_len
= nlh
->nlmsg_len
;
92 memset(&msg
, 0, sizeof(struct msghdr
));
93 msg
.msg_name
= (void *)&dest_addr
;
94 msg
.msg_namelen
= sizeof(dest_addr
);
98 /* Send request to kernel module */
99 ret
= sendmsg(sock_fd
, &msg
, 0);
107 /* Wait for the response */
108 memset(nlh
, 0, NLMSG_SPACE(MAX_DATA_SIZE
));
109 ret
= recvmsg(sock_fd
, &msg
, 0);
117 /* Copy data to user buffer */
118 memcpy(buffer
, NLMSG_DATA(nlh
), length
);