Hey everyone,
I am trying to develop a linux kernel module. One of the task that it has is to send a UDP packet to the broadcast address of
a network interface. I have attached the dmesg logs below. For some reason it is able to bind to the address but it is not able
to send the packet. It shows EFAULT. Please advise.
Thank you in advance.
16 static struct socket *sd_listener_sock = NULL;
17 static struct sockaddr_in sd_listener_sin;
18 static struct socket *sd_brdcst_sock = NULL;
19 static struct sockaddr_in sd_brdcst_sin;
17 static struct sockaddr_in sd_listener_sin;
18 static struct socket *sd_brdcst_sock = NULL;
19 static struct sockaddr_in sd_brdcst_sin;
...
106 static int __init onekfs_sd_brdcst_init(void)
107 {
108 int sd_err = 0;
109 int enable_brodcast = 1;
110 sockptr_t enable_brdcst;
111
112 /* Get socket */
113
114 sd_err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, 0, &sd_brdcst_sock);
115 if (sd_err < 0) {
116 printk(KERN_ERR "onekfs: Failed to create broadcast socket: %d\n", sd_err);
117 goto errout;
118 }
119
120 /* Enable broadcast */
121 enable_brdcst.is_kernel = 1;
122 enable_brdcst.kernel = &enable_brodcast;
123 sd_err = sock_setsockopt(sd_brdcst_sock, SOL_SOCKET,
124 SO_BROADCAST, enable_brdcst,
125 sizeof(enable_brdcst));
126 if (sd_err < 0) {
127 printk(KERN_ERR "onekfs: Could not set up broadcast: %d\n", sd_err);
128 goto errout_with_socket;
129 }
130
131 /* Bind to port */
132 memset(&sd_brdcst_sin, 0, sizeof(struct sockaddr_in));
133
134 sd_brdcst_sin.sin_family = AF_INET;
135 sd_brdcst_sin.sin_port = htons(ONEKFS_PORT + 1);
136 sd_brdcst_sin.sin_addr.s_addr = htonl(onekfs_brdcst_addr);
137 // sd_brdcst_sin.sin_addr.s_addr = onekfs_brdcst_addr;
138
139 sd_err = sd_brdcst_sock->ops->bind(sd_brdcst_sock,
140 (struct sockaddr *)&sd_brdcst_sin,
141 sizeof(struct sockaddr_in));
142 if (sd_err < 0) {
143 printk(KERN_ERR "onekfs: Failed to bind broadcast socket: %d\n", sd_err);
144 goto errout_with_socket;
145 }
146
147 /* We're live */
148 printk(KERN_INFO "onekfs: Broadcast of UDP packets at port %d\n",
149 ONEKFS_PORT + 1);
150
151 return 0;
152
153
154 errout_with_socket:
155 sock_release(sd_listener_sock);
156
157 errout:
158 return sd_err;
159 }
107 {
108 int sd_err = 0;
109 int enable_brodcast = 1;
110 sockptr_t enable_brdcst;
111
112 /* Get socket */
113
114 sd_err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, 0, &sd_brdcst_sock);
115 if (sd_err < 0) {
116 printk(KERN_ERR "onekfs: Failed to create broadcast socket: %d\n", sd_err);
117 goto errout;
118 }
119
120 /* Enable broadcast */
121 enable_brdcst.is_kernel = 1;
122 enable_brdcst.kernel = &enable_brodcast;
123 sd_err = sock_setsockopt(sd_brdcst_sock, SOL_SOCKET,
124 SO_BROADCAST, enable_brdcst,
125 sizeof(enable_brdcst));
126 if (sd_err < 0) {
127 printk(KERN_ERR "onekfs: Could not set up broadcast: %d\n", sd_err);
128 goto errout_with_socket;
129 }
130
131 /* Bind to port */
132 memset(&sd_brdcst_sin, 0, sizeof(struct sockaddr_in));
133
134 sd_brdcst_sin.sin_family = AF_INET;
135 sd_brdcst_sin.sin_port = htons(ONEKFS_PORT + 1);
136 sd_brdcst_sin.sin_addr.s_addr = htonl(onekfs_brdcst_addr);
137 // sd_brdcst_sin.sin_addr.s_addr = onekfs_brdcst_addr;
138
139 sd_err = sd_brdcst_sock->ops->bind(sd_brdcst_sock,
140 (struct sockaddr *)&sd_brdcst_sin,
141 sizeof(struct sockaddr_in));
142 if (sd_err < 0) {
143 printk(KERN_ERR "onekfs: Failed to bind broadcast socket: %d\n", sd_err);
144 goto errout_with_socket;
145 }
146
147 /* We're live */
148 printk(KERN_INFO "onekfs: Broadcast of UDP packets at port %d\n",
149 ONEKFS_PORT + 1);
150
151 return 0;
152
153
154 errout_with_socket:
155 sock_release(sd_listener_sock);
156
157 errout:
158 return sd_err;
159 }
...
183 int broadcast_msg(char *data, ssize_t data_len)184 {
185 /* Generate Msg */
186 struct msghdr* msg = kzalloc(sizeof (struct msghdr), GFP_KERNEL);
187 struct iovec* iov = kzalloc(sizeof (struct iovec), GFP_KERNEL);
188 int ret;
189
190 // memset(&msg, 0, sizeof(struct msghdr));
191 // memset(&iov, 0, sizeof(struct kvec));
192
193 char *pk_data = kzalloc(PROJECT_NAME_LEN + data_len, GFP_KERNEL);
194 if (!pk_data) {
195 printk(KERN_WARNING "onekfs:"
196 " Could not get memory for payload\n");
197 return 1;
198 }
199
200 sprintf(pk_data, "onekfs%s", data);
201
202 iov->iov_base = pk_data;
203 iov->iov_len = PROJECT_NAME_LEN + data_len;
204 msg->msg_name = (void *)&sd_brdcst_sin;
205 msg->msg_namelen = sizeof(sd_brdcst_sin);
206 msg->msg_inq = PROJECT_NAME_LEN + data_len;
207 iov_iter_init(&msg->msg_iter, WRITE, iov, 1, iov->iov_len);
208 /* Broadcast */
209
210 printk(KERN_INFO "onekfs: Broadcast Socket type: %d\n", sd_brdcst_sock->type);
211 __be32 temp = (sd_brdcst_sin.sin_addr.s_addr);
185 /* Generate Msg */
186 struct msghdr* msg = kzalloc(sizeof (struct msghdr), GFP_KERNEL);
187 struct iovec* iov = kzalloc(sizeof (struct iovec), GFP_KERNEL);
188 int ret;
189
190 // memset(&msg, 0, sizeof(struct msghdr));
191 // memset(&iov, 0, sizeof(struct kvec));
192
193 char *pk_data = kzalloc(PROJECT_NAME_LEN + data_len, GFP_KERNEL);
194 if (!pk_data) {
195 printk(KERN_WARNING "onekfs:"
196 " Could not get memory for payload\n");
197 return 1;
198 }
199
200 sprintf(pk_data, "onekfs%s", data);
201
202 iov->iov_base = pk_data;
203 iov->iov_len = PROJECT_NAME_LEN + data_len;
204 msg->msg_name = (void *)&sd_brdcst_sin;
205 msg->msg_namelen = sizeof(sd_brdcst_sin);
206 msg->msg_inq = PROJECT_NAME_LEN + data_len;
207 iov_iter_init(&msg->msg_iter, WRITE, iov, 1, iov->iov_len);
208 /* Broadcast */
209
210 printk(KERN_INFO "onekfs: Broadcast Socket type: %d\n", sd_brdcst_sock->type);
211 __be32 temp = (sd_brdcst_sin.sin_addr.s_addr);
...
215 ret = sock_sendmsg(sd_brdcst_sock, msg);
217 /* TODO: -14 (Bad Address error) */
218 if (ret < 0){
219 printk(KERN_INFO "onekfs: UDP Packet Send failed: %d\n", ret);
220 sock_release(sd_brdcst_sock);
221 sock_release(sd_listener_sock);
222 kfree(msg);
223 kfree(iov);
224 }
225
226 kfree(pk_data);
227
228 return ret < 0;
229 }
215 ret = sock_sendmsg(sd_brdcst_sock, msg);
217 /* TODO: -14 (Bad Address error) */
218 if (ret < 0){
219 printk(KERN_INFO "onekfs: UDP Packet Send failed: %d\n", ret);
220 sock_release(sd_brdcst_sock);
221 sock_release(sd_listener_sock);
222 kfree(msg);
223 kfree(iov);
224 }
225
226 kfree(pk_data);
227
228 return ret < 0;
229 }
Logs:
[ 4952.707575] onekfs: Interface: enp0s3, Broadcast Address: x.x.x.x
[ 4952.707626] onekfs: Broadcast of UDP packets at port 39530
[ 4952.707639] onekfs: Broadcast Addr: x.x.x.x
[ 4952.707665] onekfs: UDP Packet Send failed: -14
[ 4952.707678] onekfs: Loaded
[ 4952.707626] onekfs: Broadcast of UDP packets at port 39530
[ 4952.707639] onekfs: Broadcast Addr: x.x.x.x
[ 4952.707665] onekfs: UDP Packet Send failed: -14
[ 4952.707678] onekfs: Loaded
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies