6060#include <sys/socket.h>
6161#include <sys/ioctl.h>
6262#include <sys/uio.h>
63+ #include <sys/un.h>
6364#include <net/if.h>
6465#include <netinet/in.h>
6566#include <netinet/tcp.h>
@@ -100,16 +101,20 @@ int main(int argc, char **argv)
100101{
101102 int i ;
102103 struct sockaddr_in serveraddr ;
104+ struct sockaddr_un serveraddr_un ;
105+ socklen_t serveraddr_un_len ;
103106 struct hostent * server_ent ;
104107 struct sigaction sigint_action ;
105108 char buf [MAXLEN ];
106109 char * server_string ;
110+ char * afuxname ;
107111
108112 /* set default config settings */
109113 port = PORT ;
110114 strcpy (ldev , "can0" );
111115 strcpy (rdev , "can0" );
112116 server_string = malloc (strlen ("localhost" ));
117+ afuxname = NULL ;
113118
114119
115120 /* Parse commandline arguments */
@@ -119,13 +124,14 @@ int main(int argc, char **argv)
119124 static struct option long_options [] = {
120125 {"verbose" , no_argument , 0 , 'v' },
121126 {"interfaces" , required_argument , 0 , 'i' },
127+ {"afuxname" , required_argument , 0 , 'u' },
122128 {"server" , required_argument , 0 , 's' },
123129 {"port" , required_argument , 0 , 'p' },
124130 {"version" , no_argument , 0 , 'z' },
125131 {0 , 0 , 0 , 0 }
126132 };
127133
128- c = getopt_long (argc , argv , "vhi:p:l:s:" , long_options , & option_index );
134+ c = getopt_long (argc , argv , "vhi:p:l:s:u: " , long_options , & option_index );
129135
130136 if (c == -1 )
131137 break ;
@@ -146,6 +152,11 @@ int main(int argc, char **argv)
146152 port = atoi (optarg );
147153 break ;
148154
155+ case 'u' :
156+ afuxname = realloc (afuxname , strlen (optarg )+ 1 );
157+ strcpy (afuxname , optarg );
158+ break ;
159+
149160 case 's' :
150161 server_string = realloc (server_string , strlen (optarg )+ 1 );
151162 strcpy (server_string , optarg );
@@ -180,30 +191,70 @@ int main(int argc, char **argv)
180191 sigint_action .sa_flags = 0 ;
181192 sigaction (SIGINT , & sigint_action , NULL );
182193
183- server_socket = socket (AF_INET , SOCK_STREAM , 0 );
184- if (server_socket < 0 ) {
185- perror ("socket" );
186- exit (1 );
187- }
188194
189- memset (& serveraddr , 0 , sizeof (serveraddr ));
190- serveraddr .sin_family = AF_INET ;
191- serveraddr .sin_port = htons (port );
195+ if (afuxname ) {
196+ /* create AF_UNIX socket */
197+ server_socket = socket (AF_UNIX , SOCK_STREAM , 0 );
198+ if (server_socket < 0 ) {
199+ perror ("unixsocket" );
200+ exit (1 );
201+ }
192202
193- server_ent = gethostbyname ( server_string ) ;
194- if ( server_ent == 0 ) {
195- perror ( server_string );
196- exit (1 );
197- }
203+ serveraddr_un . sun_family = AF_UNIX ;
204+ if ( strlen ( afuxname ) > sizeof ( serveraddr_un . sun_path ) - 3 ) {
205+ printf ( "afuxname is too long.\n" );
206+ exit (1 );
207+ }
198208
199- memcpy (& (serveraddr .sin_addr .s_addr ), server_ent -> h_addr ,
200- server_ent -> h_length );
209+ /* when the given afuxname starts with a '/' we assume the path name scheme, e.g.
210+ * /var/run/socketcand or /tmp/socketcand-afunix-socket
211+ * Without the leading '/' we use the string as abstract socket address.
212+ */
201213
214+ if (afuxname [0 ] == '/' ) {
215+ strcpy (& serveraddr_un .sun_path [0 ], afuxname );
216+ /* due to the trailing \0 in path name definition we can write the entire struct */
217+ serveraddr_un_len = sizeof (serveraddr_un );
218+ } else {
219+ strcpy (& serveraddr_un .sun_path [1 ], afuxname );
220+ serveraddr_un .sun_path [0 ] = 0 ;
221+ /* abtract name length definition without trailing \0 but with leading \0 */
222+ serveraddr_un_len = strlen (afuxname ) + sizeof (serveraddr_un .sun_family ) + 1 ;
223+ }
202224
203- if (connect (server_socket , (struct sockaddr * )& serveraddr ,
204- sizeof (serveraddr )) != 0 ) {
205- perror ("connect" );
206- exit (1 );
225+ if (connect (server_socket , (struct sockaddr * )& serveraddr_un , serveraddr_un_len ) != 0 ) {
226+ perror ("connect" );
227+ exit (1 );
228+ }
229+ }
230+ else {
231+ /* create AF_INET socket */
232+
233+ server_socket = socket (AF_INET , SOCK_STREAM , 0 );
234+ if (server_socket < 0 ) {
235+ perror ("socket" );
236+ exit (1 );
237+ }
238+
239+ memset (& serveraddr , 0 , sizeof (serveraddr ));
240+ serveraddr .sin_family = AF_INET ;
241+ serveraddr .sin_port = htons (port );
242+
243+ server_ent = gethostbyname (server_string );
244+ if (server_ent == 0 ) {
245+ perror (server_string );
246+ exit (1 );
247+ }
248+
249+ memcpy (& (serveraddr .sin_addr .s_addr ), server_ent -> h_addr ,
250+ server_ent -> h_length );
251+
252+
253+ if (connect (server_socket , (struct sockaddr * )& serveraddr ,
254+ sizeof (serveraddr )) != 0 ) {
255+ perror ("connect" );
256+ exit (1 );
257+ }
207258 }
208259
209260
@@ -500,12 +551,13 @@ int receive_command(int socket, char *buffer)
500551
501552void print_usage (void )
502553{
503- printf ("Usage: socketcandcl [-v | --verbose] [-i interfaces | --interfaces interfaces]\n\t\t[-s server | --server server ]\n\t\t[-p port | --port port]\n" );
554+ printf ("Usage: socketcandcl [-v | --verbose] [-i interfaces | --interfaces interfaces]\n\t\t[-s server | --server server ] [-u name | --afuxname name] \n\t\t[-p port | --port port]\n" );
504555 printf ("Options:\n" );
505556 printf ("\t-v activates verbose output to STDOUT\n" );
506557 printf ("\t-s server hostname\n" );
507558 printf ("\t-i SocketCAN interfaces to use: device_server,device_client \n" );
508559 printf ("\t-p port changes the default port (%d) the client connects to\n" , PORT );
560+ printf ("\t-u AF_UNIX socket path - abstract name when leading '/' is missing\n" );
509561 printf ("\t-h prints this message\n" );
510562}
511563
0 commit comments