Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
47413c11
Commit
47413c11
authored
Oct 06, 2011
by
Charles-François Natali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #10141: socket: add SocketCAN (PF_CAN) support. Initial patch by Matthias
Fuchs, updated by Tiago Gonçalves.
parent
90c30e87
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
683 additions
and
321 deletions
+683
-321
Doc/library/socket.rst
Doc/library/socket.rst
+66
-5
Doc/whatsnew/3.3.rst
Doc/whatsnew/3.3.rst
+14
-7
Lib/test/test_socket.py
Lib/test/test_socket.py
+164
-0
Misc/ACKS
Misc/ACKS
+2
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/socketmodule.c
Modules/socketmodule.c
+105
-0
Modules/socketmodule.h
Modules/socketmodule.h
+11
-0
configure
configure
+305
-309
configure.in
configure.in
+7
-0
pyconfig.h.in
pyconfig.h.in
+6
-0
No files found.
Doc/library/socket.rst
View file @
47413c11
...
...
@@ -80,6 +80,11 @@ Socket addresses are represented as follows:
If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
reference, and *v3* should be set to 0.
- A tuple ``(interface, )`` is used for the :const:`AF_CAN` address family,
where *interface* is a string representing a network interface name like
``'can0'``. The network interface name ``''`` can be used to receive packets
from all network interfaces of this family.
- Certain other address families (:const:`AF_BLUETOOTH`, :const:`AF_PACKET`)
support specific representations.
...
...
@@ -216,6 +221,19 @@ The module :mod:`socket` exports the following constants and functions:
in the Unix header files are defined; for a few symbols, default values are
provided.
.. data:: AF_CAN
PF_CAN
SOL_CAN_*
CAN_*
Many constants of these forms, documented in the Linux documentation, are
also defined in the socket module.
Availability: Linux >= 2.6.25.
.. versionadded:: 3.3
.. data:: SIO_*
RCVALL_*
...
...
@@ -387,10 +405,14 @@ The module :mod:`socket` exports the following constants and functions:
Create a new socket using the given address family, socket type and protocol
number. The address family should be :const:`AF_INET` (the default),
:const:`AF_INET6` or :const:`AF_UNIX`. The socket type should be
:const:`SOCK_STREAM` (the default), :const:`SOCK_DGRAM` or perhaps one of the
other ``SOCK_`` constants. The protocol number is usually zero and may be
omitted in that case.
:const:`AF_INET6`, :const:`AF_UNIX` or :const:`AF_CAN`. The socket type
should be :const:`SOCK_STREAM` (the default), :const:`SOCK_DGRAM`,
:const:`SOCK_RAW` or perhaps one of the other ``SOCK_`` constants. The
protocol number is usually zero and may be omitted in that case or
:const:`CAN_RAW` in case the address family is :const:`AF_CAN`.
.. versionchanged:: 3.3
The AF_CAN family was added.
.. function:: socketpair([family[, type[, proto]]])
...
...
@@ -1213,7 +1235,7 @@ sends traffic to the first one connected successfully. ::
print('Received', repr(data))
The
las
t example shows how to write a very simple network sniffer with raw
The
nex
t example shows how to write a very simple network sniffer with raw
sockets on Windows. The example requires administrator privileges to modify
the interface::
...
...
@@ -1238,6 +1260,45 @@ the interface::
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
The last example shows how to use the socket interface to communicate to a CAN
network. This example might require special priviledge::
import socket
import struct
# CAN frame packing/unpacking (see `struct can_frame` in <linux/can.h>)
can_frame_fmt = "=IB3x8s"
def build_can_frame(can_id, data):
can_dlc = len(data)
data = data.ljust(8, b'\x00')
return struct.pack(can_frame_fmt, can_id, can_dlc, data)
def dissect_can_frame(frame):
can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
return (can_id, can_dlc, data[:can_dlc])
# create a raw socket and bind it to the `vcan0` interface
s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
s.bind(('vcan0',))
while True:
cf, addr = s.recvfrom(16)
print('Received: can_id=%x, can_dlc=%x, data=%s' % dissect_can_frame(cf))
try:
s.send(cf)
except socket.error:
print('Error sending CAN frame')
try:
s.send(build_can_frame(0x01, b'\x01\x02\x03'))
except socket.error:
print('Error sending CAN frame')
Running an example several times with too small delay between executions, could
lead to this error::
...
...
Doc/whatsnew/3.3.rst
View file @
47413c11
...
...
@@ -300,15 +300,22 @@ signal
socket
------
The :class:`~socket.socket` class now exposes addititonal methods to
process
ancillary data when supported by the underlying platform:
* The :class:`~socket.socket` class now exposes additional methods to process
ancillary data when supported by the underlying platform:
* :func:`~socket.socket.sendmsg`
* :func:`~socket.socket.recvmsg`
* :func:`~socket.socket.recvmsg_into`
* :func:`~socket.socket.sendmsg`
* :func:`~socket.socket.recvmsg`
* :func:`~socket.socket.recvmsg_into`
(Contributed by David Watson in :issue:`6560`, based on an earlier patch by
Heiko Wundram)
* The :class:`~socket.socket` class now supports the PF_CAN protocol family
(http://en.wikipedia.org/wiki/Socketcan), on Linux
(http://lwn.net/Articles/253425).
(Contributed by Matthias Fuchs, updated by Tiago Gonçalves in :issue:`10141`)
(Contributed by David Watson in :issue:`6560`, based on an earlier patch
by Heiko Wundram)
ssl
---
...
...
Lib/test/test_socket.py
View file @
47413c11
...
...
@@ -21,6 +21,7 @@ from weakref import proxy
import
signal
import
math
import
pickle
import
struct
try
:
import
fcntl
except
ImportError
:
...
...
@@ -36,6 +37,18 @@ except ImportError:
thread
=
None
threading
=
None
def
_have_socket_can
():
"""Check whether CAN sockets are supported on this host."""
try
:
s
=
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
except
(
AttributeError
,
socket
.
error
,
OSError
):
return
False
else
:
s
.
close
()
return
True
HAVE_SOCKET_CAN
=
_have_socket_can
()
# Size in bytes of the int type
SIZEOF_INT
=
array
.
array
(
"i"
).
itemsize
...
...
@@ -80,6 +93,30 @@ class ThreadSafeCleanupTestCase(unittest.TestCase):
with
self
.
_cleanup_lock
:
return
super
().
doCleanups
(
*
args
,
**
kwargs
)
class
SocketCANTest
(
unittest
.
TestCase
):
"""To be able to run this test, a `vcan0` CAN interface can be created with
the following commands:
# modprobe vcan
# ip link add dev vcan0 type vcan
# ifconfig vcan0 up
"""
interface
=
'vcan0'
bufsize
=
128
def
setUp
(
self
):
self
.
s
=
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
try
:
self
.
s
.
bind
((
self
.
interface
,))
except
socket
.
error
:
self
.
skipTest
(
'network interface `%s` does not exist'
%
self
.
interface
)
self
.
s
.
close
()
def
tearDown
(
self
):
self
.
s
.
close
()
self
.
s
=
None
class
ThreadableTest
:
"""Threadable Test class
...
...
@@ -210,6 +247,26 @@ class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest):
self
.
cli
=
None
ThreadableTest
.
clientTearDown
(
self
)
class
ThreadedCANSocketTest
(
SocketCANTest
,
ThreadableTest
):
def
__init__
(
self
,
methodName
=
'runTest'
):
SocketCANTest
.
__init__
(
self
,
methodName
=
methodName
)
ThreadableTest
.
__init__
(
self
)
def
clientSetUp
(
self
):
self
.
cli
=
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
try
:
self
.
cli
.
bind
((
self
.
interface
,))
except
socket
.
error
:
self
.
skipTest
(
'network interface `%s` does not exist'
%
self
.
interface
)
self
.
cli
.
close
()
def
clientTearDown
(
self
):
self
.
cli
.
close
()
self
.
cli
=
None
ThreadableTest
.
clientTearDown
(
self
)
class
SocketConnectedTest
(
ThreadedTCPSocketTest
):
"""Socket tests for client-server connection.
...
...
@@ -1072,6 +1129,112 @@ class GeneralModuleTests(unittest.TestCase):
srv
.
close
()
@
unittest
.
skipUnless
(
HAVE_SOCKET_CAN
,
'SocketCan required for this test.'
)
class
BasicCANTest
(
unittest
.
TestCase
):
def
testCrucialConstants
(
self
):
socket
.
AF_CAN
socket
.
PF_CAN
socket
.
CAN_RAW
def
testCreateSocket
(
self
):
with
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
as
s
:
pass
def
testBindAny
(
self
):
with
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
as
s
:
s
.
bind
((
''
,
))
def
testTooLongInterfaceName
(
self
):
# most systems limit IFNAMSIZ to 16, take 1024 to be sure
with
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
as
s
:
self
.
assertRaisesRegexp
(
socket
.
error
,
'interface name too long'
,
s
.
bind
,
(
'x'
*
1024
,))
@
unittest
.
skipUnless
(
hasattr
(
socket
,
"CAN_RAW_LOOPBACK"
),
'socket.CAN_RAW_LOOPBACK required for this test.'
)
def
testLoopback
(
self
):
with
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
as
s
:
for
loopback
in
(
0
,
1
):
s
.
setsockopt
(
socket
.
SOL_CAN_RAW
,
socket
.
CAN_RAW_LOOPBACK
,
loopback
)
self
.
assertEqual
(
loopback
,
s
.
getsockopt
(
socket
.
SOL_CAN_RAW
,
socket
.
CAN_RAW_LOOPBACK
))
@
unittest
.
skipUnless
(
hasattr
(
socket
,
"CAN_RAW_FILTER"
),
'socket.CAN_RAW_FILTER required for this test.'
)
def
testFilter
(
self
):
can_id
,
can_mask
=
0x200
,
0x700
can_filter
=
struct
.
pack
(
"=II"
,
can_id
,
can_mask
)
with
socket
.
socket
(
socket
.
PF_CAN
,
socket
.
SOCK_RAW
,
socket
.
CAN_RAW
)
as
s
:
s
.
setsockopt
(
socket
.
SOL_CAN_RAW
,
socket
.
CAN_RAW_FILTER
,
can_filter
)
self
.
assertEqual
(
can_filter
,
s
.
getsockopt
(
socket
.
SOL_CAN_RAW
,
socket
.
CAN_RAW_FILTER
,
8
))
@
unittest
.
skipUnless
(
HAVE_SOCKET_CAN
,
'SocketCan required for this test.'
)
@
unittest
.
skipUnless
(
thread
,
'Threading required for this test.'
)
class
CANTest
(
ThreadedCANSocketTest
):
"""The CAN frame structure is defined in <linux/can.h>:
struct can_frame {
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 can_dlc; /* data length code: 0 .. 8 */
__u8 data[8] __attribute__((aligned(8)));
};
"""
can_frame_fmt
=
"=IB3x8s"
def
__init__
(
self
,
methodName
=
'runTest'
):
ThreadedCANSocketTest
.
__init__
(
self
,
methodName
=
methodName
)
@
classmethod
def
build_can_frame
(
cls
,
can_id
,
data
):
"""Build a CAN frame."""
can_dlc
=
len
(
data
)
data
=
data
.
ljust
(
8
,
b'
\
x00
'
)
return
struct
.
pack
(
cls
.
can_frame_fmt
,
can_id
,
can_dlc
,
data
)
@
classmethod
def
dissect_can_frame
(
cls
,
frame
):
"""Dissect a CAN frame."""
can_id
,
can_dlc
,
data
=
struct
.
unpack
(
cls
.
can_frame_fmt
,
frame
)
return
(
can_id
,
can_dlc
,
data
[:
can_dlc
])
def
testSendFrame
(
self
):
cf
,
addr
=
self
.
s
.
recvfrom
(
self
.
bufsize
)
self
.
assertEqual
(
self
.
cf
,
cf
)
self
.
assertEqual
(
addr
[
0
],
self
.
interface
)
self
.
assertEqual
(
addr
[
1
],
socket
.
AF_CAN
)
def
_testSendFrame
(
self
):
self
.
cf
=
self
.
build_can_frame
(
0x00
,
b'
\
x01
\
x02
\
x03
\
x04
\
x05
'
)
self
.
cli
.
send
(
self
.
cf
)
def
testSendMaxFrame
(
self
):
cf
,
addr
=
self
.
s
.
recvfrom
(
self
.
bufsize
)
self
.
assertEqual
(
self
.
cf
,
cf
)
def
_testSendMaxFrame
(
self
):
self
.
cf
=
self
.
build_can_frame
(
0x00
,
b'
\
x07
'
*
8
)
self
.
cli
.
send
(
self
.
cf
)
def
testSendMultiFrames
(
self
):
cf
,
addr
=
self
.
s
.
recvfrom
(
self
.
bufsize
)
self
.
assertEqual
(
self
.
cf1
,
cf
)
cf
,
addr
=
self
.
s
.
recvfrom
(
self
.
bufsize
)
self
.
assertEqual
(
self
.
cf2
,
cf
)
def
_testSendMultiFrames
(
self
):
self
.
cf1
=
self
.
build_can_frame
(
0x07
,
b'
\
x44
\
x33
\
x22
\
x11
'
)
self
.
cli
.
send
(
self
.
cf1
)
self
.
cf2
=
self
.
build_can_frame
(
0x12
,
b'
\
x99
\
x22
\
x33
'
)
self
.
cli
.
send
(
self
.
cf2
)
@
unittest
.
skipUnless
(
thread
,
'Threading required for this test.'
)
class
BasicTCPTest
(
SocketConnectedTest
):
...
...
@@ -4194,6 +4357,7 @@ def test_main():
if
isTipcAvailable
():
tests
.
append
(
TIPCTest
)
tests
.
append
(
TIPCThreadableTest
)
tests
.
extend
([
BasicCANTest
,
CANTest
])
tests
.
extend
([
CmsgMacroTests
,
SendmsgUDPTest
,
...
...
Misc/ACKS
View file @
47413c11
...
...
@@ -319,6 +319,7 @@ John Fouhy
Martin Franklin
Robin Friedrich
Ivan Frohne
Matthias Fuchs
Jim Fulton
Tadayoshi Funaba
Gyro Funch
...
...
@@ -354,6 +355,7 @@ Michael Gilfix
Yannick Gingras
Christoph Gohlke
Tim Golden
Tiago Gonçalves
Chris Gonnerman
David Goodger
Hans de Graaff
...
...
Misc/NEWS
View file @
47413c11
...
...
@@ -1322,6 +1322,9 @@ Tools/Demos
Extension Modules
-----------------
- Issue #10141: socket: Add SocketCAN (PF_CAN) support. Initial patch by
Matthias Fuchs, updated by Tiago Gonçalves.
- Issue #13070: Fix a crash when a TextIOWrapper caught in a reference cycle
would be finalized after the reference to its underlying BufferedRWPair'
s
writer
got
cleared
by
the
GC
.
...
...
Modules/socketmodule.c
View file @
47413c11
...
...
@@ -1220,6 +1220,25 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
}
#endif
#ifdef HAVE_LINUX_CAN_H
case
AF_CAN
:
{
struct
sockaddr_can
*
a
=
(
struct
sockaddr_can
*
)
addr
;
char
*
ifname
=
""
;
struct
ifreq
ifr
;
/* need to look up interface name given index */
if
(
a
->
can_ifindex
)
{
ifr
.
ifr_ifindex
=
a
->
can_ifindex
;
if
(
ioctl
(
sockfd
,
SIOCGIFNAME
,
&
ifr
)
==
0
)
ifname
=
ifr
.
ifr_name
;
}
return
Py_BuildValue
(
"O&h"
,
PyUnicode_DecodeFSDefault
,
ifname
,
a
->
can_family
);
}
#endif
/* More cases here... */
default:
...
...
@@ -1587,6 +1606,53 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
}
#endif
#ifdef HAVE_LINUX_CAN_H
case
AF_CAN
:
switch
(
s
->
sock_proto
)
{
case
CAN_RAW
:
{
struct
sockaddr_can
*
addr
;
PyObject
*
interfaceName
;
struct
ifreq
ifr
;
addr
=
(
struct
sockaddr_can
*
)
addr_ret
;
Py_ssize_t
len
;
if
(
!
PyArg_ParseTuple
(
args
,
"O&"
,
PyUnicode_FSConverter
,
&
interfaceName
))
return
0
;
len
=
PyBytes_GET_SIZE
(
interfaceName
);
if
(
len
==
0
)
{
ifr
.
ifr_ifindex
=
0
;
}
else
if
(
len
<
sizeof
(
ifr
.
ifr_name
))
{
strcpy
(
ifr
.
ifr_name
,
PyBytes_AS_STRING
(
interfaceName
));
if
(
ioctl
(
s
->
sock_fd
,
SIOCGIFINDEX
,
&
ifr
)
<
0
)
{
s
->
errorhandler
();
Py_DECREF
(
interfaceName
);
return
0
;
}
}
else
{
PyErr_SetString
(
socket_error
,
"AF_CAN interface name too long"
);
Py_DECREF
(
interfaceName
);
return
0
;
}
addr
->
can_family
=
AF_CAN
;
addr
->
can_ifindex
=
ifr
.
ifr_ifindex
;
*
len_ret
=
sizeof
(
*
addr
);
Py_DECREF
(
interfaceName
);
return
1
;
}
default:
PyErr_SetString
(
socket_error
,
"getsockaddrarg: unsupported CAN protocol"
);
return
0
;
}
#endif
/* More cases here... */
default:
...
...
@@ -1680,6 +1746,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
}
#endif
#ifdef HAVE_LINUX_CAN_H
case
AF_CAN
:
{
*
len_ret
=
sizeof
(
struct
sockaddr_can
);
return
1
;
}
#endif
/* More cases here... */
default:
...
...
@@ -5533,6 +5607,15 @@ PyInit__socket(void)
PyModule_AddStringConstant
(
m
,
"BDADDR_LOCAL"
,
"00:00:00:FF:FF:FF"
);
#endif
#ifdef AF_CAN
/* Controller Area Network */
PyModule_AddIntConstant
(
m
,
"AF_CAN"
,
AF_CAN
);
#endif
#ifdef PF_CAN
/* Controller Area Network */
PyModule_AddIntConstant
(
m
,
"PF_CAN"
,
PF_CAN
);
#endif
#ifdef AF_PACKET
PyModule_AddIntMacro
(
m
,
AF_PACKET
);
#endif
...
...
@@ -5803,6 +5886,28 @@ PyInit__socket(void)
#else
PyModule_AddIntConstant
(
m
,
"SOL_UDP"
,
17
);
#endif
#ifdef SOL_CAN_BASE
PyModule_AddIntConstant
(
m
,
"SOL_CAN_BASE"
,
SOL_CAN_BASE
);
#endif
#ifdef SOL_CAN_RAW
PyModule_AddIntConstant
(
m
,
"SOL_CAN_RAW"
,
SOL_CAN_RAW
);
PyModule_AddIntConstant
(
m
,
"CAN_RAW"
,
CAN_RAW
);
#endif
#ifdef HAVE_LINUX_CAN_H
PyModule_AddIntConstant
(
m
,
"CAN_EFF_FLAG"
,
CAN_EFF_FLAG
);
PyModule_AddIntConstant
(
m
,
"CAN_RTR_FLAG"
,
CAN_RTR_FLAG
);
PyModule_AddIntConstant
(
m
,
"CAN_ERR_FLAG"
,
CAN_ERR_FLAG
);
PyModule_AddIntConstant
(
m
,
"CAN_SFF_MASK"
,
CAN_SFF_MASK
);
PyModule_AddIntConstant
(
m
,
"CAN_EFF_MASK"
,
CAN_EFF_MASK
);
PyModule_AddIntConstant
(
m
,
"CAN_ERR_MASK"
,
CAN_ERR_MASK
);
#endif
#ifdef HAVE_LINUX_CAN_RAW_H
PyModule_AddIntConstant
(
m
,
"CAN_RAW_FILTER"
,
CAN_RAW_FILTER
);
PyModule_AddIntConstant
(
m
,
"CAN_RAW_ERR_FILTER"
,
CAN_RAW_ERR_FILTER
);
PyModule_AddIntConstant
(
m
,
"CAN_RAW_LOOPBACK"
,
CAN_RAW_LOOPBACK
);
PyModule_AddIntConstant
(
m
,
"CAN_RAW_RECV_OWN_MSGS"
,
CAN_RAW_RECV_OWN_MSGS
);
#endif
#ifdef IPPROTO_IP
PyModule_AddIntConstant
(
m
,
"IPPROTO_IP"
,
IPPROTO_IP
);
#else
...
...
Modules/socketmodule.h
View file @
47413c11
...
...
@@ -72,6 +72,14 @@ typedef int socklen_t;
# include <linux/tipc.h>
#endif
#ifdef HAVE_LINUX_CAN_H
#include <linux/can.h>
#endif
#ifdef HAVE_LINUX_CAN_RAW_H
#include <linux/can/raw.h>
#endif
#ifndef Py__SOCKET_H
#define Py__SOCKET_H
#ifdef __cplusplus
...
...
@@ -126,6 +134,9 @@ typedef union sock_addr {
#ifdef HAVE_NETPACKET_PACKET_H
struct
sockaddr_ll
ll
;
#endif
#ifdef HAVE_LINUX_CAN_H
struct
sockaddr_can
can
;
#endif
}
sock_addr_t
;
/* The object holding a socket. It holds some extra information,
...
...
configure
View file @
47413c11
This diff is collapsed.
Click to expand it.
configure.in
View file @
47413c11
...
...
@@ -1376,6 +1376,13 @@ AC_CHECK_HEADERS(linux/netlink.h,,,[
#endif
])
# On Linux, can.h and can/raw.h require sys/socket.h
AC_CHECK_HEADERS(linux/can.h linux/can/raw.h,,,[
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
])
# checks for typedefs
was_it_defined=no
AC_MSG_CHECKING(for clock_t in time.h)
...
...
pyconfig.h.in
View file @
47413c11
...
...
@@ -467,6 +467,12 @@
/* Define to 1 if you have the `linkat' function. */
#undef HAVE_LINKAT
/* Define to 1 if you have the <linux/can.h> header file. */
#undef HAVE_LINUX_CAN_H
/* Define to 1 if you have the <linux/can/raw.h> header file. */
#undef HAVE_LINUX_CAN_RAW_H
/* Define to 1 if you have the <linux/netlink.h> header file. */
#undef HAVE_LINUX_NETLINK_H
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment