-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLinkLayer.cpp
More file actions
169 lines (136 loc) · 4 KB
/
LinkLayer.cpp
File metadata and controls
169 lines (136 loc) · 4 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <iostream>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include "LinkLayer.h"
#include "constants.h"
using namespace std;
LinkLayer::LinkLayer(phy_info localPhy, vector<itf_info> itfs) {
this->localPhy = localPhy;
this->itfs = itfs;
localAI = new struct addrinfo;
rcvSocket = createSocket(localPhy, localAI, true);
cout << "In LinkLayer: "<< endl;
cout << "The localPhy info: localhost is " << localPhy.ipAddr << " port is " << localPhy.port << endl;
for(vector<itf_info>::size_type i = 0; i != itfs.size(); i++){
cout << "In the " << i << "th itf: " << " Remote phy: address is " << itfs[i].rmtPhy.ipAddr << " port is " << itfs[i].rmtPhy.port << endl;
cout << " locAddr is " << itfs[i].locAddr << ", rmtAddr is " << itfs[i].rmtAddr << endl;
}
}
/**
* Returns string representation of IP address associated with the specified interface
*/
char* LinkLayer::getInterfaceAddr(int itfNum) {
return itfs[itfNum].locAddr;
}
/**
* Sends dataLen bytes of data over the interface specified by itfNum
*/
int LinkLayer::send(char* data, int dataLen, int itfNum) {
int sendSocket, bytesSent;
struct addrinfo *aiDest = new struct addrinfo;
sendSocket = createSocket(itfs[itfNum].rmtPhy, aiDest, false);
if ((bytesSent = sendto(sendSocket, data, dataLen, 0, aiDest->ai_addr, aiDest->ai_addrlen)) == -1) {
perror("Send error:");
return -1;
}
freeaddrinfo(aiDest);
printf("Sent %d bytes over interface %d\n", bytesSent, itfNum);
close(sendSocket);
return bytesSent;
}
int LinkLayer::listen(char* buf, int bufLen) {
int bytesRcvd;
if ((bytesRcvd = recvfrom(rcvSocket, buf, bufLen-1 , 0, NULL, NULL)) == -1) {
perror("Receive error:");
return -1;
}
}
/**
* Creates UDP socket and populates &aiRet with socket address info
*/
int LinkLayer::createSocket(phy_info phyInfo, struct addrinfo* aiRet, bool bindSock) {
int sockfd, gai_ret;
struct addrinfo aiHints, *aiList, *ai;
// zero out address info hints structure
memset(&aiHints, 0, sizeof aiHints);
// populate address info hints
aiHints.ai_family = AF_INET; // IPv4
aiHints.ai_socktype = SOCK_DGRAM; // UDP
if ((gai_ret = getaddrinfo(phyInfo.ipAddr, phyInfo.port, &aiHints, &aiList)) != 0) {
perror("Get address info error:");
return -1;
}
// loop through getaddrinfo() results. connect (and bind if flagged) to first one possible
for(ai = aiList; ai != NULL; ai = ai->ai_next) {
if ((sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) == -1) {
perror("Socket creation error:");
continue;
}
if (bindSock) {
if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) == -1) {
close(sockfd);
perror("Socking binding error:");
continue;
}
}
break;
}
if (ai == NULL) {
printf("No valid address info structure found.\n");
return -1;
}
// copy address info data
*aiRet = *ai;
// free address info list
freeaddrinfo(aiList);
return sockfd;
}
/* This main just for testing */
int main(int argc, char ** argv) {
int recv_len;
char msg[512], reply[512];
phy_info locPhy, rmtPhy;
itf_info itf;
vector<itf_info> itfs;
locPhy.ipAddr = "127.0.0.1";
rmtPhy.ipAddr = "127.0.0.1";
locPhy.port = argv[2];
rmtPhy.port = argv[3];
itf.locAddr = "192.168.1.1";
itf.rmtAddr = "192.168.1.1";
itf.rmtPhy = rmtPhy;
itfs.push_back(itf);
LinkLayer* ll = new LinkLayer(locPhy, itfs);
if (argv[1][0] == 'l') { // node is listener
while (1) {
perror("Listening for packets:\n");
recv_len = ll->listen(reply, 512);
if (recv_len < 0) {
perror("Recv error:");
return 1;
}
reply[recv_len] = 0;
printf("Receive message:\n%s\n", reply);
memset(reply, 0, sizeof(reply));
}
} else if (argv[1][0] == 's') { // node is sender
while (1) {
fflush(stdin);
printf("Enter message: \n");
gets(msg);
if (ll->send(msg, 512, 0) < 0) {
perror("Send error:");
return 1;
}
}
} else { // invalid argument
printf("Invalid argument.");
}
}