+ /* try to switch the socket into CAN FD mode */
+ setsockopt(s[i], SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));
+
+ if (rcvbuf_size) {
+
+ int curr_rcvbuf_size;
+ socklen_t curr_rcvbuf_size_len = sizeof(curr_rcvbuf_size);
+
+ /* try SO_RCVBUFFORCE first, if we run with CAP_NET_ADMIN */
+ if (setsockopt(s[i], SOL_SOCKET, SO_RCVBUFFORCE,
+ &rcvbuf_size, sizeof(rcvbuf_size)) < 0) {
+#ifdef DEBUG
+ printf("SO_RCVBUFFORCE failed so try SO_RCVBUF ...\n");
+#endif
+ if (setsockopt(s[i], SOL_SOCKET, SO_RCVBUF,
+ &rcvbuf_size, sizeof(rcvbuf_size)) < 0) {
+ perror("setsockopt SO_RCVBUF");
+ return 1;
+ }
+
+ if (getsockopt(s[i], SOL_SOCKET, SO_RCVBUF,
+ &curr_rcvbuf_size, &curr_rcvbuf_size_len) < 0) {
+ perror("getsockopt SO_RCVBUF");
+ return 1;
+ }
+
+ /* Only print a warning the first time we detect the adjustment */
+ /* n.b.: The wanted size is doubled in Linux in net/sore/sock.c */
+ if (!i && curr_rcvbuf_size < rcvbuf_size*2)
+ fprintf(stderr, "The socket receive buffer size was "
+ "adjusted due to /proc/sys/net/core/rmem_max.\n");
+ }
+ }
+
+ if (timestamp || log || logfrmt) {
+
+ const int timestamp_on = 1;
+
+ if (setsockopt(s[i], SOL_SOCKET, SO_TIMESTAMP,
+ ×tamp_on, sizeof(timestamp_on)) < 0) {
+ perror("setsockopt SO_TIMESTAMP");
+ return 1;
+ }
+ }
+
+ if (dropmonitor) {
+
+ const int dropmonitor_on = 1;
+
+ if (setsockopt(s[i], SOL_SOCKET, SO_RXQ_OVFL,
+ &dropmonitor_on, sizeof(dropmonitor_on)) < 0) {
+ perror("setsockopt SO_RXQ_OVFL not supported by your Linux Kernel");
+ return 1;
+ }
+ }
+