/[dynamips]/trunk/linux_eth.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/linux_eth.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations)
Sat Oct 6 16:29:14 2007 UTC (11 years, 8 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7/linux_eth.c
File MIME type: text/plain
File size: 2857 byte(s)
dynamips-0.2.7

1 dpavlin 1 /*
2     * Copyright (c) 2006 Christophe Fillot.
3     * E-mail: cf@utc.fr
4     *
5     * linux_eth.c: module used to send/receive Ethernet packets.
6     *
7     * Specific to the Linux operating system.
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <string.h>
13     #include <stdarg.h>
14     #include <unistd.h>
15     #include <errno.h>
16     #include <signal.h>
17     #include <fcntl.h>
18     #include <ctype.h>
19     #include <netdb.h>
20     #include <sys/time.h>
21     #include <sys/stat.h>
22     #include <sys/types.h>
23     #include <sys/socket.h>
24     #include <sys/wait.h>
25     #include <netinet/in.h>
26     #include <arpa/inet.h>
27     #include <pthread.h>
28    
29     #include <sys/ioctl.h>
30     #include <netinet/if_ether.h>
31     #include <linux/if.h>
32     #include <linux/if_packet.h>
33    
34     #include "linux_eth.h"
35    
36     /* Get interface index of specified device */
37     int lnx_eth_get_dev_index(char *name)
38     {
39     struct ifreq if_req;
40     int fd;
41    
42     /* Create dummy file descriptor */
43     if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
44     fprintf(stderr,"eth_get_dev_index: socket: %s\n",strerror(errno));
45     return(-1);
46     }
47    
48     memset((void *)&if_req,0,sizeof(if_req));
49     strcpy(if_req.ifr_name,name);
50    
51     if (ioctl(fd,SIOCGIFINDEX,&if_req) < 0) {
52     fprintf(stderr,"eth_get_dev_index: SIOCGIFINDEX: %s\n",strerror(errno));
53     close(fd);
54     return(-1);
55     }
56    
57     close(fd);
58     return(if_req.ifr_ifindex);
59     }
60    
61     /* Initialize a new ethernet raw socket */
62     int lnx_eth_init_socket(char *device)
63     {
64     struct sockaddr_ll sa;
65     struct packet_mreq mreq;
66     int sck;
67    
68     if ((sck = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))) == -1) {
69     fprintf(stderr,"eth_init_socket: socket: %s\n",strerror(errno));
70     return(-1);
71     }
72    
73     memset(&sa,0,sizeof(struct sockaddr_ll));
74     sa.sll_family = AF_PACKET;
75     sa.sll_protocol = htons(ETH_P_ALL);
76     sa.sll_hatype = ARPHRD_ETHER;
77     sa.sll_halen = ETH_ALEN;
78     sa.sll_ifindex = lnx_eth_get_dev_index(device);
79    
80     memset(&mreq,0,sizeof(mreq));
81     mreq.mr_ifindex = sa.sll_ifindex;
82     mreq.mr_type = PACKET_MR_PROMISC;
83    
84     if (bind(sck,(struct sockaddr *)&sa,sizeof(struct sockaddr_ll)) == -1) {
85     fprintf(stderr,"eth_init_socket: bind: %s\n",strerror(errno));
86     return(-1);
87     }
88    
89     if (setsockopt(sck,SOL_PACKET,PACKET_ADD_MEMBERSHIP,
90     &mreq,sizeof(mreq)) == -1)
91     {
92     fprintf(stderr,"eth_init_socket: setsockopt: %s\n",strerror(errno));
93     return(-1);
94     }
95    
96     return(sck);
97     }
98    
99     /* Send an ethernet frame */
100     ssize_t lnx_eth_send(int sck,int dev_id,char *buffer,size_t len)
101     {
102     struct sockaddr_ll sa;
103    
104     memset(&sa,0,sizeof(struct sockaddr_ll));
105     sa.sll_family = AF_PACKET;
106     sa.sll_protocol = htons(ETH_P_ALL);
107     sa.sll_hatype = ARPHRD_ETHER;
108     sa.sll_halen = ETH_ALEN;
109     sa.sll_ifindex = dev_id;
110    
111     return(sendto(sck,buffer,len,0,(struct sockaddr *)&sa,sizeof(sa)));
112     }
113    
114     /* Receive an ethernet frame */
115     ssize_t lnx_eth_recv(int sck,char *buffer,size_t len)
116     {
117     return(recv(sck,buffer,len,0));
118     }

  ViewVC Help
Powered by ViewVC 1.1.26