]> git.sesse.net Git - vlc/blob - src/input/input_vlan.c
Bon. On ne rit pas, je m'�tais juste plant� dans l'en-t�te des
[vlc] / src / input / input_vlan.c
1 /*****************************************************************************
2  * input_vlan.c: vlan management library
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  *
6  * Authors:
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include "defs.h"
27
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <stdio.h>                                              /* sprintf() */
30 #include <unistd.h>                                               /* close() */
31 #include <string.h>                                   /* strerror(), bzero() */
32 #include <stdlib.h>                                                /* free() */
33
34 #if defined(SYS_BSD) || defined(SYS_BEOS)
35 #include <netinet/in.h>                                    /* struct in_addr */
36 #include <sys/socket.h>                                   /* struct sockaddr */
37 #endif
38
39 #if defined(SYS_LINUX) || defined(SYS_BSD) || defined(SYS_GNU)
40 #include <arpa/inet.h>                           /* inet_ntoa(), inet_aton() */
41 #endif
42
43 #ifdef SYS_LINUX
44 #include <sys/ioctl.h>                                            /* ioctl() */
45 #include <net/if.h>                            /* interface (arch-dependent) */
46 #endif
47
48 #include "config.h"
49 #include "common.h"
50 #include "threads.h"
51 #include "mtime.h"
52 #include "netutils.h"
53 #include "input_vlan.h"
54 #include "intf_msg.h"
55 #include "main.h"
56
57 /*****************************************************************************
58  * input_vlan_t: vlan library data
59  *****************************************************************************
60  * Store global vlan library data.
61  *****************************************************************************/
62 typedef struct input_vlan_s
63 {
64     int         i_vlan_id;                            /* current vlan number */
65     mtime_t     last_change;                             /* last change date */
66 } input_vlan_t;
67
68 /*****************************************************************************
69  * Local prototypes
70  *****************************************************************************/
71 static int ZeTrucMucheFunction( int Channel );
72
73 /*****************************************************************************
74  * input_VlanCreate: initialize global vlan method data
75  *****************************************************************************
76  * Initialize vlan input method global data. This function should be called
77  * once before any input thread is created or any call to other input_Vlan*()
78  * function is attempted.
79  *****************************************************************************/
80 int input_VlanCreate( void )
81 {
82 #ifdef SYS_BEOS
83     intf_ErrMsg( "error: vlans are not supported under beos\n" );
84     return( 1 );
85 #else
86     /* Allocate structure */
87     p_main->p_vlan = malloc( sizeof( input_vlan_t ) );
88     if( p_main->p_vlan == NULL )
89     {
90         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
91         return( 1 );
92     }
93
94     /* Initialize structure */
95     p_main->p_vlan->i_vlan_id   = 0;
96     p_main->p_vlan->last_change = 0;
97
98     intf_Msg("VLANs initialized\n");
99     return( 0 );
100 #endif /* SYS_BEOS */
101 }
102
103 /*****************************************************************************
104  * input_VlanDestroy: free global vlan method data
105  *****************************************************************************
106  * Free resources allocated by input_VlanMethodInit. This function should be
107  * called at the end of the program.
108  *****************************************************************************/
109 void input_VlanDestroy( void )
110 {
111     /* Return to default vlan */
112     if( p_main->p_vlan->i_vlan_id != 0 )
113     {
114         input_VlanJoin( 0 );
115     }
116
117     /* Free structure */
118     free( p_main->p_vlan );
119 }
120
121 /*****************************************************************************
122  * input_VlanJoin: join a vlan
123  *****************************************************************************
124  * This function will try to join a vlan. If the relevant interface is already
125  * on the good vlan, nothing will be done. Else, and if possible (if the
126  * interface is not locked), the vlan server will be contacted and a change will
127  * be requested. The function will block until the change is effective. Note
128  * that once a vlan is no more used, it's interface should be unlocked using
129  * input_VlanLeave().
130  * Non 0 will be returned in case of error.
131  *****************************************************************************/
132 int input_VlanJoin( int i_vlan_id )
133 {
134 #ifdef SYS_BEOS
135     return( -1 );
136 #else
137     /* If last change is too recent, wait a while */
138     if( mdate() - p_main->p_vlan->last_change < INPUT_VLAN_CHANGE_DELAY )
139     {
140         intf_Msg("Waiting before changing VLAN...\n");
141         mwait( p_main->p_vlan->last_change + INPUT_VLAN_CHANGE_DELAY );
142     }
143     p_main->p_vlan->last_change = mdate();
144     p_main->p_vlan->i_vlan_id = i_vlan_id;
145
146     intf_Msg("Joining VLAN %d (channel %d)\n", i_vlan_id + 2, i_vlan_id );
147     return( ZeTrucMucheFunction( i_vlan_id ) ); /* FIXME: join vlan ?? */
148 #endif /* SYS_BEOS */
149 }
150
151 /*****************************************************************************
152  * input_VlanLeave: leave a vlan
153  *****************************************************************************
154  * This function tells the vlan library that the designed interface is no more
155  * locked and than vlan changes can occur.
156  *****************************************************************************/
157 void input_VlanLeave( int i_vlan_id )
158 {
159     /* XXX?? */
160 }
161
162 /* following functions are local */
163
164 static int ZeTrucMucheFunction( int Channel)
165 {
166 #ifdef SYS_LINUX
167     int                         i_socket;
168     char   *                    ipaddr;
169     struct ifreq                interface;
170     struct sockaddr_in          sa_server;
171     struct sockaddr_in          sa_client;
172     char                        mess[80];
173
174     /*
175      *Looking for informations about the eth0 interface
176      */
177
178     interface.ifr_addr.sa_family = AF_INET;
179     strcpy( interface.ifr_name, main_GetPszVariable( INPUT_IFACE_VAR, INPUT_IFACE_DEFAULT ) );
180
181     i_socket = socket( AF_INET, SOCK_DGRAM, 0 );
182
183     /* Looking for the interface IP address */
184     ioctl( i_socket, SIOCGIFDSTADDR, &interface );
185     ipaddr = inet_ntoa((*(struct sockaddr_in *)(&(interface.ifr_addr))).sin_addr );
186
187     /* Looking for the interface MAC address */
188     ioctl( i_socket, SIOCGIFHWADDR, &interface );
189     close( i_socket );
190
191     /*
192      * Getting address, port, ... of the server
193      */
194
195     /* Initialize */
196     bzero( &sa_server, sizeof(struct sockaddr_in) );
197     /* sin_family is ALWAYS set to AF_INET (see in man 7 ip)*/
198     sa_server.sin_family = AF_INET;
199     /* Giving port on to connect after having convert it*/
200     sa_server.sin_port = htons ( main_GetIntVariable( INPUT_VLAN_PORT_VAR, INPUT_VLAN_PORT_DEFAULT ));
201     /* Giving address after having convert it into binary data*/
202     inet_aton( main_GetPszVariable( INPUT_VLAN_SERVER_VAR, INPUT_VLAN_SERVER_DEFAULT ), &(sa_server.sin_addr) );
203
204     /*
205      * Getting address, port, ... of the client
206      */
207
208     /* Initialize */
209     bzero( &sa_client, sizeof(struct sockaddr_in) );
210     /* sin_family is ALWAYS set to AF_INET (see in man 7 ip)*/
211     sa_client.sin_family = AF_INET;
212     /* Giving port on to connect after having convert it*/
213     sa_client.sin_port = htons( 0 );
214     /* Giving address after having convert it into binary data*/
215     inet_aton( ipaddr, &(sa_client.sin_addr) );
216
217     /* Initialization of the socket */
218     i_socket = socket(AF_INET, SOCK_DGRAM, 17 ); /* XXX?? UDP */
219      /*  SOCK_DGRAM because here we use DATAGRAM
220       * Sachant qu'il y a un #define AF_INET = PF_INET dans sys/socket.h et que PF_INET est le IP protocol family ...
221       * Protocol is in #define, should be 17 for udp */
222
223     /* Elaborate the message to send */
224         sprintf( mess , "%d %s %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n",
225             Channel, ipaddr,
226             interface.ifr_hwaddr.sa_data[0] & 0xff,
227             interface.ifr_hwaddr.sa_data[1] & 0xff,
228             interface.ifr_hwaddr.sa_data[2] & 0xff,
229             interface.ifr_hwaddr.sa_data[3] & 0xff,
230             interface.ifr_hwaddr.sa_data[4] & 0xff,
231             interface.ifr_hwaddr.sa_data[5] & 0xff,
232                     interface.ifr_hwaddr.sa_data[0] & 0xff,
233             interface.ifr_hwaddr.sa_data[1] & 0xff,
234             interface.ifr_hwaddr.sa_data[2] & 0xff,
235             interface.ifr_hwaddr.sa_data[3] & 0xff,
236             interface.ifr_hwaddr.sa_data[4] & 0xff,
237             interface.ifr_hwaddr.sa_data[5] & 0xff
238         );
239
240     /* Send the message */
241     intf_DbgMsg("%s\n", mess);
242         sendto(i_socket,mess,80,0,(struct sockaddr *)&sa_server,sizeof(struct sockaddr));
243
244     /*Close the socket */
245     close( i_socket );
246 #endif
247
248     return 0;
249 }