2 * Connection oriented routing user space utils
3 * Copyright (C) 2009-2011
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 #define MAX_ADDRLEN 128
43 struct route_list localneighs
;
48 struct route_list routes
;
55 #define ROUTE_MAXHOPS 7
59 int routes
[ROUTE_MAXHOPS
+ 1];
63 #define SEARCHQUERY_NEIGHSNOTQUERIED 1
64 #define SEARCHQUERY_NODEBYADDRESS 2
75 static int node_matches_searchquery(struct node
*n
, struct search_query
*q
)
77 if (q
->type
== SEARCHQUERY_NEIGHSNOTQUERIED
) {
78 return n
->neighs_queried
== 0;
79 } else if (q
->type
== SEARCHQUERY_NODEBYADDRESS
) {
80 if (n
->addrlen
!= q
->query
.nodebyaddress
.addrlen
)
82 if (memcmp(n
->addr
, q
->query
.nodebyaddress
.addr
,
92 static int try_find_neigh(struct e2e_route
*route
, struct search_query
*q
,
93 struct route_list
*curr
)
95 int *pos
= &(route
->routes
[route
->pos
]);
97 for (*pos
=0;*pos
<curr
->numroutes
;(*pos
)++) {
98 struct node
*n
= curr
->routes
[*pos
].dst
;
99 if (node_matches_searchquery(n
, q
)) {
105 if (route
->pos
>= ROUTE_MAXHOPS
)
110 for (*pos
=0;*pos
<curr
->numroutes
;(*pos
)++) {
111 int rc
= try_find_neigh(route
, q
,
112 &(curr
->routes
[*pos
].dst
->routes
));
122 static int try_find_neigh_byaddr(struct e2e_route
*route
, __u16 addrlen
,
125 struct search_query q
;
126 bzero(&q
, sizeof(struct search_query
));
127 q
.type
= SEARCHQUERY_NODEBYADDRESS
;
128 q
.query
.nodebyaddress
.addrlen
= addrlen
;
129 q
.query
.nodebyaddress
.addr
= addr
;
131 return try_find_neigh(route
, &q
, &localneighs
);
134 static int connect_to_host_recv(int fd
, struct e2e_route
*route
)
137 for (u
=0;route
!= 0 && u
<=route
->pos
;u
++) {
138 int rc
= read_resp(fd
);
140 return RC_CONNBROKEN
;
145 static int connect_to_host_send(int fd
, struct e2e_route
*route
)
147 struct route_list
*routes
= &localneighs
;
149 for (u
=0;u
<=route
->pos
;u
++) {
150 struct node
*n
= routes
->routes
[route
->routes
[u
]].dst
;
151 int rc
= send_connect_neigh(fd
, n
->addrlen
, n
->addr
);
153 return RC_CONNBROKEN
;
154 routes
= &(n
->routes
);
160 static int connect_to_host(int fd
, __u16 addrlen
, char *addr
)
163 struct e2e_route route
;
164 bzero(&route
, sizeof(struct e2e_route
));
166 if (try_find_neigh_byaddr(&route
, addrlen
, addr
) == 0)
167 return RC_CONNBROKEN
;
169 rc
= connect_to_host_send(fd
, &route
);
173 rc
= connect_to_host_recv(fd
, &route
);
179 void add_neigh(void *ptr
, __u32 addrlen
, char *addr
)
181 struct route_list
*list
= (struct route_list
*) ptr
;
183 struct e2e_route route
;
185 if (addrlen
> MAX_ADDRLEN
)
188 if (list
->numroutes
>= list
->rows_alloc
)
191 assert(list
->routes
[list
->numroutes
].dst
== 0);
193 bzero(&route
, sizeof(struct e2e_route
));
194 if (try_find_neigh_byaddr(&route
, addrlen
, addr
) == 0) {
195 node
= calloc(1, sizeof(struct node
));
197 node
->addr
= malloc(((int) addrlen
));
198 node
->addrlen
= addrlen
;
199 memcpy(node
->addr
, addr
, addrlen
);
204 list
->routes
[list
->numroutes
].dst
= node
;
208 void init_neighlist(void *ptr
, __u32 numneighs
)
210 struct route_list
*list
= (struct route_list
*) ptr
;
214 list
->rows_alloc
= (__u16
) numneighs
;
215 list
->routes
= calloc(numneighs
, sizeof(struct route
));
218 static void print_hex(char *buf
, int len
)
222 printf("%hhx ", buf
[u
]);
226 void neigh_printaddr(__u16 addrlen
, char *addr
)
228 printf("addrlen = %d addr: ", (int) addrlen
);
229 print_hex(addr
, addrlen
);
233 void load_neigh_list(struct e2e_route
*route
)
235 struct route_list
*list
;
239 fd
= socket(PF_COR
, SOCK_RAW
, PROTO_COR_RAW
);
245 rc
= connect(fd
, 0, 0);
254 neigh_printaddr(route
->result
->addrlen
,
255 route
->result
->addr
);
256 list
= &(route
->result
->routes
);
257 rc
= connect_to_host_send(fd
, route
);
260 printf("connect_to_host_send error\n");
264 rc
= send_list_neigh(fd
);
266 printf("send_list_neigh error\n");
271 rc
= connect_to_host_recv(fd
, route
);
273 printf("connect_to_host_recv error\n");
279 printf("read_resp error\n");
281 rc
= read_neigh_list(fd
, list
, init_neighlist
, add_neigh
);
283 printf("read_neigh_list error\n");
285 printf("load_neigh_list rc %d\n", rc
);
294 struct search_query q
;
295 bzero(&q
, sizeof(struct search_query
));
296 q
.type
= SEARCHQUERY_NEIGHSNOTQUERIED
;
299 struct e2e_route nextroute
;
300 bzero(&nextroute
, sizeof(struct e2e_route
));
301 int rc
= try_find_neigh(&nextroute
, &q
, &localneighs
);
304 load_neigh_list(&nextroute
);
305 nextroute
.result
->neighs_queried
= 1;