-
Notifications
You must be signed in to change notification settings - Fork 198
/
osal_eth.c
137 lines (112 loc) · 3.03 KB
/
osal_eth.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*********************************************************************
* _ _ _
* _ __ | |_ _ | | __ _ | |__ ___
* | '__|| __|(_)| | / _` || '_ \ / __|
* | | | |_ _ | || (_| || |_) |\__ \
* |_| \__|(_)|_| \__,_||_.__/ |___/
*
* www.rt-labs.com
* Copyright 2018 rt-labs AB, Sweden.
*
* This software is dual-licensed under GPLv3 and a commercial
* license. See the file LICENSE.md distributed with this software for
* full license information.
********************************************************************/
#include "options.h"
#include "osal.h"
#include "osal_sys.h"
#include "pf_includes.h"
#include "log.h"
#include "cc.h"
#include <stdlib.h>
#include <errno.h>
#include <net/if.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/ioctl.h>
#include <netpacket/packet.h>
static int os_eth_recv(uint16_t type, os_buf_t * p)
{
int handled = 0;
switch (type)
{
case OS_ETHTYPE_PROFINET:
case OS_ETHTYPE_LLDP:
handled = pf_eth_recv(p, p->len);
break;
case OS_ETHTYPE_ETHERCAT:
handled = 0;
break;
default:
break;
}
return handled;
}
static void os_eth_task(void * arg)
{
int * sock = (int *) arg;
ssize_t readlen;
os_buf_t * p = os_buf_alloc (1522);
assert(p == NULL);
while (1)
{
readlen = recv (*sock, p->payload, p->len, 0);
if(readlen == -1)
continue;
p->len = readlen;
if (os_eth_recv (OS_ETHTYPE_PROFINET, p) == 1)
{
printf("r");
fflush(stdout);
p = os_buf_alloc (1522);
assert(p == NULL);
}
}
}
int os_eth_init(const char * if_name)
{
int * sock;
int i;
struct ifreq ifr;
struct sockaddr_ll sll;
int ifindex;
struct timeval timeout;
sock = calloc (1, sizeof(int));
*sock = -1;
*sock = socket(PF_PACKET, SOCK_RAW, htons(OS_ETHTYPE_PROFINET));
timeout.tv_sec = 0;
timeout.tv_usec = 1;
setsockopt(*sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
i = 1;
setsockopt(*sock, SOL_SOCKET, SO_DONTROUTE, &i, sizeof(i));
strcpy(ifr.ifr_name, if_name);
ioctl(*sock, SIOCGIFINDEX, &ifr);
ifindex = ifr.ifr_ifindex;
strcpy(ifr.ifr_name, if_name);
ifr.ifr_flags = 0;
/* reset flags of NIC interface */
ioctl(*sock, SIOCGIFFLAGS, &ifr);
/* set flags of NIC interface, here promiscuous and broadcast */
ifr.ifr_flags = ifr.ifr_flags | IFF_PROMISC | IFF_BROADCAST;
ioctl(*sock, SIOCSIFFLAGS, &ifr);
/* bind socket to protocol, in this case RAW EtherCAT */
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifindex;
sll.sll_protocol = htons(OS_ETHTYPE_PROFINET);
bind(*sock, (struct sockaddr *)&sll, sizeof(sll));
if (*sock > -1)
{
os_thread_create ("os_eth_task", 10,
4096, os_eth_task, sock);
}
return *sock;
}
int os_eth_send(uint32_t id, os_buf_t * buf)
{
int ret = send (id, buf->payload, buf->len, 0);
if (ret<0)
printf("os_eth_send sent length: %d errno %d\n", ret, errno);
printf("t");
fflush(stdout);
return ret;
}