Lines Matching +full:route +full:- +full:ptp

1 // SPDX-License-Identifier: GPL-2.0-or-later
29 * Bradford Johnson : IP-over-DDP (experimental)
30 * Jay Schulist : Moved IP-over-DDP to its own
59 #include <net/route.h>
97 if (to->sat_port != at->src_port) in atalk_search_socket()
100 if (to->sat_addr.s_net == ATADDR_ANYNET && in atalk_search_socket()
101 to->sat_addr.s_node == ATADDR_BCAST) in atalk_search_socket()
104 if (to->sat_addr.s_net == at->src_net && in atalk_search_socket()
105 (to->sat_addr.s_node == at->src_node || in atalk_search_socket()
106 to->sat_addr.s_node == ATADDR_BCAST || in atalk_search_socket()
107 to->sat_addr.s_node == ATADDR_ANYNODE)) in atalk_search_socket()
110 /* XXXX.0 -- we got a request for this router. make sure in atalk_search_socket()
112 if (to->sat_addr.s_node == ATADDR_ANYNODE && in atalk_search_socket()
113 to->sat_addr.s_net != ATADDR_ANYNET && in atalk_search_socket()
114 atif->address.s_node == at->src_node) { in atalk_search_socket()
115 to->sat_addr.s_node = atif->address.s_node; in atalk_search_socket()
126 * atalk_find_or_insert_socket - Try to find a socket matching ADDR
145 if (at->src_net == sat->sat_addr.s_net && in atalk_find_or_insert_socket()
146 at->src_node == sat->sat_addr.s_node && in atalk_find_or_insert_socket()
147 at->src_port == sat->sat_port) in atalk_find_or_insert_socket()
162 sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; in atalk_destroy_timer()
163 add_timer(&sk->sk_timer); in atalk_destroy_timer()
171 skb_queue_purge(&sk->sk_receive_queue); in atalk_destroy_socket()
174 timer_setup(&sk->sk_timer, atalk_destroy_timer, 0); in atalk_destroy_socket()
175 sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; in atalk_destroy_socket()
176 add_timer(&sk->sk_timer); in atalk_destroy_socket()
187 /* Anti-deadlock ordering is atalk_routes_lock --> iface_lock -DaveM */
199 * Drop a device. Doesn't drop any of its routes - that is the caller's
209 if (tmp->dev == dev) { in atif_drop_device()
210 *iface = tmp->next; in atif_drop_device()
213 dev->atalk_ptr = NULL; in atif_drop_device()
215 iface = &tmp->next; in atif_drop_device()
229 iface->dev = dev; in atif_add_device()
230 dev->atalk_ptr = iface; in atif_add_device()
231 iface->address = *sa; in atif_add_device()
232 iface->status = 0; in atif_add_device()
235 iface->next = atalk_interfaces; in atif_add_device()
245 int netrange = ntohs(atif->nets.nr_lastnet) - in atif_probe_device()
246 ntohs(atif->nets.nr_firstnet) + 1; in atif_probe_device()
247 int probe_net = ntohs(atif->address.s_net); in atif_probe_device()
248 int probe_node = atif->address.s_node; in atif_probe_device()
253 probe_net = ntohs(atif->nets.nr_firstnet); in atif_probe_device()
261 atif->status |= ATIF_PROBE; in atif_probe_device()
264 atif->address.s_net = htons(probe_net); in atif_probe_device()
266 atif->address.s_node = (nodect + probe_node) & 0xFF; in atif_probe_device()
267 if (atif->address.s_node > 0 && in atif_probe_device()
268 atif->address.s_node < 254) { in atif_probe_device()
272 if (!(atif->status & ATIF_PROBE_FAIL)) { in atif_probe_device()
273 atif->status &= ~ATIF_PROBE; in atif_probe_device()
277 atif->status &= ~ATIF_PROBE_FAIL; in atif_probe_device()
280 if (probe_net > ntohs(atif->nets.nr_lastnet)) in atif_probe_device()
281 probe_net = ntohs(atif->nets.nr_firstnet); in atif_probe_device()
283 atif->status &= ~ATIF_PROBE; in atif_probe_device()
285 return -EADDRINUSE; /* Network is full... */ in atif_probe_device()
293 int netrange = ntohs(atif->nets.nr_lastnet) - in atif_proxy_probe_device()
294 ntohs(atif->nets.nr_firstnet) + 1; in atif_proxy_probe_device()
296 int probe_net = ntohs(atif->address.s_net); in atif_proxy_probe_device()
302 probe_net = ntohs(atif->nets.nr_firstnet); in atif_proxy_probe_device()
313 proxy_addr->s_net = htons(probe_net); in atif_proxy_probe_device()
315 proxy_addr->s_node = (nodect + probe_node) & 0xFF; in atif_proxy_probe_device()
316 if (proxy_addr->s_node > 0 && in atif_proxy_probe_device()
317 proxy_addr->s_node < 254) { in atif_proxy_probe_device()
322 if (ret != -EADDRINUSE) in atif_proxy_probe_device()
327 if (probe_net > ntohs(atif->nets.nr_lastnet)) in atif_proxy_probe_device()
328 probe_net = ntohs(atif->nets.nr_firstnet); in atif_proxy_probe_device()
331 return -EADDRINUSE; /* Network is full... */ in atif_proxy_probe_device()
337 struct atalk_iface *iface = dev->atalk_ptr; in atalk_find_dev_addr()
338 return iface ? &iface->address : NULL; in atalk_find_dev_addr()
348 * Return a point-to-point interface only if in atalk_find_primary()
349 * there is no non-ptp interface available. in atalk_find_primary()
352 for (iface = atalk_interfaces; iface; iface = iface->next) { in atalk_find_primary()
353 if (!fiface && !(iface->dev->flags & IFF_LOOPBACK)) in atalk_find_primary()
355 if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { in atalk_find_primary()
356 retval = &iface->address; in atalk_find_primary()
362 retval = &fiface->address; in atalk_find_primary()
364 retval = &atalk_interfaces->address; in atalk_find_primary()
373 * Find a match for 'any network' - ie any of our interfaces with that
378 struct atalk_iface *iface = dev->atalk_ptr; in atalk_find_anynet()
380 if (!iface || iface->status & ATIF_PROBE) in atalk_find_anynet()
384 iface->address.s_node != node && in atalk_find_anynet()
400 for (iface = atalk_interfaces; iface; iface = iface->next) { in atalk_find_interface()
403 iface->address.s_node == node) && in atalk_find_interface()
404 iface->address.s_net == net && in atalk_find_interface()
405 !(iface->status & ATIF_PROBE)) in atalk_find_interface()
408 /* XXXX.0 -- net.0 returns the iface associated with net */ in atalk_find_interface()
410 ntohs(iface->nets.nr_firstnet) <= ntohs(net) && in atalk_find_interface()
411 ntohs(net) <= ntohs(iface->nets.nr_lastnet)) in atalk_find_interface()
420 * Find a route for an AppleTalk packet. This ought to get cached in
422 * that a route must be direct to broadcast.
428 * host route, because some host routes might overlap in atrtr_find()
435 for (r = atalk_routes; r; r = r->next) { in atrtr_find()
436 if (!(r->flags & RTF_UP)) in atrtr_find()
439 if (r->target.s_net == target->s_net) { in atrtr_find()
440 if (r->flags & RTF_HOST) { in atrtr_find()
442 * if this host route is for the target, in atrtr_find()
445 if (r->target.s_node == target->s_node) in atrtr_find()
449 * this route will work if there isn't a in atrtr_find()
450 * direct host route, so cache it in atrtr_find()
457 * if we found a network route but not a direct host in atrtr_find()
458 * route, then return it in atrtr_find()
464 else /* No route can be found */ in atrtr_find()
479 return atr ? atr->dev : NULL; in atrtr_get_dev()
498 struct sockaddr_at *ta = (struct sockaddr_at *)&r->rt_dst; in atrtr_create()
499 struct sockaddr_at *ga = (struct sockaddr_at *)&r->rt_gateway; in atrtr_create()
502 int retval = -EINVAL; in atrtr_create()
510 if (ta->sat_family != AF_APPLETALK || in atrtr_create()
511 (!devhint && ga->sat_family != AF_APPLETALK)) in atrtr_create()
516 for (rt = atalk_routes; rt; rt = rt->next) { in atrtr_create()
517 if (r->rt_flags != rt->flags) in atrtr_create()
520 if (ta->sat_addr.s_net == rt->target.s_net) { in atrtr_create()
521 if (!(rt->flags & RTF_HOST)) in atrtr_create()
523 if (ta->sat_addr.s_node == rt->target.s_node) in atrtr_create()
532 for (iface = atalk_interfaces; iface; iface = iface->next) { in atrtr_create()
534 ntohs(ga->sat_addr.s_net) >= in atrtr_create()
535 ntohs(iface->nets.nr_firstnet) && in atrtr_create()
536 ntohs(ga->sat_addr.s_net) <= in atrtr_create()
537 ntohs(iface->nets.nr_lastnet)) in atrtr_create()
540 if (ga->sat_addr.s_net == iface->address.s_net && in atrtr_create()
541 ga->sat_addr.s_node == iface->address.s_node) in atrtr_create()
546 retval = -ENETUNREACH; in atrtr_create()
550 devhint = riface->dev; in atrtr_create()
556 retval = -ENOBUFS; in atrtr_create()
560 rt->next = atalk_routes; in atrtr_create()
565 rt->target = ta->sat_addr; in atrtr_create()
567 rt->dev = devhint; in atrtr_create()
568 rt->flags = r->rt_flags; in atrtr_create()
569 rt->gateway = ga->sat_addr; in atrtr_create()
578 /* Delete a route. Find it and discard it */
587 if (tmp->target.s_net == addr->s_net && in atrtr_delete()
588 (!(tmp->flags&RTF_GATEWAY) || in atrtr_delete()
589 tmp->target.s_node == addr->s_node)) { in atrtr_delete()
590 *r = tmp->next; in atrtr_delete()
591 dev_put(tmp->dev); in atrtr_delete()
595 r = &tmp->next; in atrtr_delete()
597 retval = -ENOENT; in atrtr_delete()
614 if (tmp->dev == dev) { in atrtr_device_down()
615 *r = tmp->next; in atrtr_device_down()
619 r = &tmp->next; in atrtr_device_down()
637 * delete our use of them (iface and route).
670 return -EFAULT; in atif_ioctl()
674 return -ENODEV; in atif_ioctl()
682 return -EPERM; in atif_ioctl()
683 if (sa->sat_family != AF_APPLETALK) in atif_ioctl()
684 return -EINVAL; in atif_ioctl()
685 if (dev->type != ARPHRD_ETHER && in atif_ioctl()
686 dev->type != ARPHRD_LOOPBACK && in atif_ioctl()
687 dev->type != ARPHRD_LOCALTLK && in atif_ioctl()
688 dev->type != ARPHRD_PPP) in atif_ioctl()
689 return -EPROTONOSUPPORT; in atif_ioctl()
691 nr = (struct atalk_netrange *)&sa->sat_zero[0]; in atif_ioctl()
695 * if this is a point-to-point iface, and we already in atif_ioctl()
697 * should not add a route in atif_ioctl()
699 if ((dev->flags & IFF_POINTOPOINT) && in atif_ioctl()
700 atalk_find_interface(sa->sat_addr.s_net, in atif_ioctl()
701 sa->sat_addr.s_node)) { in atif_ioctl()
702 printk(KERN_DEBUG "AppleTalk: point-to-point " in atif_ioctl()
712 if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) in atif_ioctl()
713 return -EPROTONOSUPPORT; in atif_ioctl()
714 if (sa->sat_addr.s_node == ATADDR_BCAST || in atif_ioctl()
715 sa->sat_addr.s_node == 254) in atif_ioctl()
716 return -EINVAL; in atif_ioctl()
719 if (atif->status & ATIF_PROBE) in atif_ioctl()
720 return -EBUSY; in atif_ioctl()
722 atif->address.s_net = sa->sat_addr.s_net; in atif_ioctl()
723 atif->address.s_node = sa->sat_addr.s_node; in atif_ioctl()
726 atif = atif_add_device(dev, &sa->sat_addr); in atif_ioctl()
728 return -ENOMEM; in atif_ioctl()
730 atif->nets = *nr; in atif_ioctl()
737 if (!(dev->flags & IFF_LOOPBACK) && in atif_ioctl()
738 !(dev->flags & IFF_POINTOPOINT) && in atif_ioctl()
741 return -EADDRINUSE; in atif_ioctl()
744 /* Hey it worked - add the direct routes */ in atif_ioctl()
746 sa->sat_family = AF_APPLETALK; in atif_ioctl()
747 sa->sat_addr.s_net = atif->address.s_net; in atif_ioctl()
748 sa->sat_addr.s_node = atif->address.s_node; in atif_ioctl()
751 sa->sat_family = AF_APPLETALK; in atif_ioctl()
752 sa->sat_addr.s_node = ATADDR_ANYNODE; in atif_ioctl()
753 if (dev->flags & IFF_LOOPBACK || in atif_ioctl()
754 dev->flags & IFF_POINTOPOINT) in atif_ioctl()
758 if (nr->nr_firstnet == htons(0) && in atif_ioctl()
759 nr->nr_lastnet == htons(0xFFFE)) { in atif_ioctl()
760 sa->sat_addr.s_net = atif->address.s_net; in atif_ioctl()
764 limit = ntohs(nr->nr_lastnet); in atif_ioctl()
765 if (limit - ntohs(nr->nr_firstnet) > 4096) { in atif_ioctl()
768 return -EINVAL; in atif_ioctl()
771 for (ct = ntohs(nr->nr_firstnet); in atif_ioctl()
773 sa->sat_addr.s_net = htons(ct); in atif_ioctl()
782 return -EADDRNOTAVAIL; in atif_ioctl()
784 sa->sat_family = AF_APPLETALK; in atif_ioctl()
785 sa->sat_addr = atif->address; in atif_ioctl()
790 return -EADDRNOTAVAIL; in atif_ioctl()
792 sa->sat_family = AF_APPLETALK; in atif_ioctl()
793 sa->sat_addr.s_net = atif->address.s_net; in atif_ioctl()
794 sa->sat_addr.s_node = ATADDR_BCAST; in atif_ioctl()
800 return -EPERM; in atif_ioctl()
801 if (sa->sat_family != AF_APPLETALK) in atif_ioctl()
802 return -EINVAL; in atif_ioctl()
808 return -EPERM; in atif_ioctl()
809 if (sa->sat_family != AF_APPLETALK) in atif_ioctl()
810 return -EINVAL; in atif_ioctl()
815 if (dev->type != ARPHRD_ETHER) in atif_ioctl()
816 return -EPROTONOSUPPORT; in atif_ioctl()
826 return -EADDRNOTAVAIL; in atif_ioctl()
828 nr = (struct atalk_netrange *)&(atif->nets); in atif_ioctl()
833 if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) in atif_ioctl()
834 return -EPROTONOSUPPORT; in atif_ioctl()
836 if (sa->sat_addr.s_node == ATADDR_BCAST || in atif_ioctl()
837 sa->sat_addr.s_node == 254) in atif_ioctl()
838 return -EINVAL; in atif_ioctl()
844 if (atif_proxy_probe_device(atif, &(sa->sat_addr)) < 0) in atif_ioctl()
845 return -EADDRINUSE; in atif_ioctl()
857 return -EPERM; in atif_ioctl()
858 if (sa->sat_family != AF_APPLETALK) in atif_ioctl()
859 return -EINVAL; in atif_ioctl()
861 return -EADDRNOTAVAIL; in atif_ioctl()
864 aarp_proxy_remove(atif->dev, &(sa->sat_addr)); in atif_ioctl()
868 return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0; in atif_ioctl()
875 if (rt->rt_dev) { in atrtr_ioctl_addrt()
878 if (copy_from_user(name, rt->rt_dev, IFNAMSIZ-1)) in atrtr_ioctl_addrt()
879 return -EFAULT; in atrtr_ioctl_addrt()
880 name[IFNAMSIZ-1] = '\0'; in atrtr_ioctl_addrt()
884 return -ENODEV; in atrtr_ioctl_addrt()
895 return -EFAULT; in atrtr_ioctl()
900 return -EINVAL; in atrtr_ioctl()
902 &rt.rt_dst)->sat_addr); in atrtr_ioctl()
907 return -EINVAL; in atrtr_ioctl()
925 while (len--) { in atalk_sum_partial()
932 /* Checksum skb data -- similar to skb_checksum */
941 if ((copy = start - offset) > 0) { in atalk_sum_skb()
944 sum = atalk_sum_partial(skb->data + offset, copy, sum); in atalk_sum_skb()
945 if ((len -= copy) == 0) in atalk_sum_skb()
952 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { in atalk_sum_skb()
954 const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; in atalk_sum_skb()
958 if ((copy = end - offset) > 0) { in atalk_sum_skb()
965 offset - start, copy, sum); in atalk_sum_skb()
968 if (!(len -= copy)) in atalk_sum_skb()
980 end = start + frag_iter->len; in atalk_sum_skb()
981 if ((copy = end - offset) > 0) { in atalk_sum_skb()
984 sum = atalk_sum_skb(frag_iter, offset - start, in atalk_sum_skb()
986 if ((len -= copy) == 0) in atalk_sum_skb()
1003 sum = atalk_sum_skb(skb, 4, len-4, 0); in atalk_checksum()
1023 int rc = -ESOCKTNOSUPPORT; in atalk_create()
1026 return -EAFNOSUPPORT; in atalk_create()
1032 if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) in atalk_create()
1035 rc = -EPERM; in atalk_create()
1036 if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) in atalk_create()
1039 rc = -ENOMEM; in atalk_create()
1044 sock->ops = &atalk_dgram_ops; in atalk_create()
1056 struct sock *sk = sock->sk; in atalk_release()
1063 sock->sk = NULL; in atalk_release()
1073 * atalk_pick_and_bind_port - Pick a source port when one is not given
1088 for (sat->sat_port = ATPORT_RESERVED; in atalk_pick_and_bind_port()
1089 sat->sat_port < ATPORT_LAST; in atalk_pick_and_bind_port()
1090 sat->sat_port++) { in atalk_pick_and_bind_port()
1096 if (at->src_net == sat->sat_addr.s_net && in atalk_pick_and_bind_port()
1097 at->src_node == sat->sat_addr.s_node && in atalk_pick_and_bind_port()
1098 at->src_port == sat->sat_port) in atalk_pick_and_bind_port()
1104 at_sk(sk)->src_port = sat->sat_port; in atalk_pick_and_bind_port()
1111 retval = -EBUSY; in atalk_pick_and_bind_port()
1122 int n = -EADDRNOTAVAIL; in atalk_autobind()
1124 if (!ap || ap->s_net == htons(ATADDR_ANYNET)) in atalk_autobind()
1127 at->src_net = sat.sat_addr.s_net = ap->s_net; in atalk_autobind()
1128 at->src_node = sat.sat_addr.s_node = ap->s_node; in atalk_autobind()
1141 struct sock *sk = sock->sk; in atalk_bind()
1147 return -EINVAL; in atalk_bind()
1149 if (addr->sat_family != AF_APPLETALK) in atalk_bind()
1150 return -EAFNOSUPPORT; in atalk_bind()
1153 if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { in atalk_bind()
1156 err = -EADDRNOTAVAIL; in atalk_bind()
1160 at->src_net = addr->sat_addr.s_net = ap->s_net; in atalk_bind()
1161 at->src_node = addr->sat_addr.s_node = ap->s_node; in atalk_bind()
1163 err = -EADDRNOTAVAIL; in atalk_bind()
1164 if (!atalk_find_interface(addr->sat_addr.s_net, in atalk_bind()
1165 addr->sat_addr.s_node)) in atalk_bind()
1168 at->src_net = addr->sat_addr.s_net; in atalk_bind()
1169 at->src_node = addr->sat_addr.s_node; in atalk_bind()
1172 if (addr->sat_port == ATADDR_ANYPORT) { in atalk_bind()
1178 at->src_port = addr->sat_port; in atalk_bind()
1180 err = -EADDRINUSE; in atalk_bind()
1196 struct sock *sk = sock->sk; in atalk_connect()
1201 sk->sk_state = TCP_CLOSE; in atalk_connect()
1202 sock->state = SS_UNCONNECTED; in atalk_connect()
1205 return -EINVAL; in atalk_connect()
1209 if (addr->sat_family != AF_APPLETALK) in atalk_connect()
1210 return -EAFNOSUPPORT; in atalk_connect()
1212 if (addr->sat_addr.s_node == ATADDR_BCAST && in atalk_connect()
1216 current->comm); in atalk_connect()
1218 return -EACCES; in atalk_connect()
1223 err = -EBUSY; in atalk_connect()
1228 err = -ENETUNREACH; in atalk_connect()
1229 if (!atrtr_get_dev(&addr->sat_addr)) in atalk_connect()
1232 at->dest_port = addr->sat_port; in atalk_connect()
1233 at->dest_net = addr->sat_addr.s_net; in atalk_connect()
1234 at->dest_node = addr->sat_addr.s_node; in atalk_connect()
1236 sock->state = SS_CONNECTED; in atalk_connect()
1237 sk->sk_state = TCP_ESTABLISHED; in atalk_connect()
1252 struct sock *sk = sock->sk; in atalk_getname()
1257 err = -ENOBUFS; in atalk_getname()
1265 err = -ENOTCONN; in atalk_getname()
1266 if (sk->sk_state != TCP_ESTABLISHED) in atalk_getname()
1269 sat.sat_addr.s_net = at->dest_net; in atalk_getname()
1270 sat.sat_addr.s_node = at->dest_node; in atalk_getname()
1271 sat.sat_port = at->dest_port; in atalk_getname()
1273 sat.sat_addr.s_net = at->src_net; in atalk_getname()
1274 sat.sat_addr.s_node = at->src_node; in atalk_getname()
1275 sat.sat_port = at->src_port; in atalk_getname()
1290 return skb->data[12] == 22; in is_ip_over_ddp()
1304 skb->protocol = htons(ETH_P_IP); in handle_ip_over_ddp()
1306 skb->dev = dev; in handle_ip_over_ddp()
1310 stats->rx_packets++; in handle_ip_over_ddp()
1311 stats->rx_bytes += skb->len + 13; in handle_ip_over_ddp()
1327 * Don't route multicast, etc., packets, or packets sent to "this in atalk_route_packet()
1330 if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) { in atalk_route_packet()
1337 if (dev->type == ARPHRD_PPP) in atalk_route_packet()
1343 ta.s_net = ddp->deh_dnet; in atalk_route_packet()
1344 ta.s_node = ddp->deh_dnode; in atalk_route_packet()
1346 /* Route the packet */ in atalk_route_packet()
1353 /* FIXME: use skb->cb to be able to use shared skbs */ in atalk_route_packet()
1356 * Route goes through another gateway, so set the target to the in atalk_route_packet()
1360 if (rt->flags & RTF_GATEWAY) { in atalk_route_packet()
1361 ta.s_net = rt->gateway.s_net; in atalk_route_packet()
1362 ta.s_node = rt->gateway.s_node; in atalk_route_packet()
1365 /* Fix up skb->len field */ in atalk_route_packet()
1367 (rt->dev->hard_header_len + in atalk_route_packet()
1368 ddp_dl->header_length + (len_hops & 1023)))); in atalk_route_packet()
1370 /* FIXME: use skb->cb to be able to use shared skbs */ in atalk_route_packet()
1371 ddp->deh_len_hops = htons(len_hops); in atalk_route_packet()
1382 * Note. ddp-> becomes invalid at the realloc. in atalk_route_packet()
1385 /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ in atalk_route_packet()
1399 if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP) in atalk_route_packet()
1409 * atalk_rcv - Receive a packet (in skb) from device dev
1410 * @skb - packet received
1411 * @dev - network device where the packet comes from
1412 * @pt - packet type
1415 * decoder, and on entry skb->transport_header is the DDP header, skb->len
1416 * is the DDP header, skb->len is the DDP length. The physical headers
1443 len_hops = ntohs(ddp->deh_len_hops); in atalk_rcv()
1446 origlen = skb->len; in atalk_rcv()
1447 skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023)); in atalk_rcv()
1450 * Size check to see if ddp->deh_len was crap in atalk_rcv()
1454 if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) { in atalk_rcv()
1456 "skb->len=%u)\n", len_hops & 1023, skb->len); in atalk_rcv()
1464 if (ddp->deh_sum && in atalk_rcv()
1465 atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum) in atalk_rcv()
1466 /* Not a valid AppleTalk frame - dustbin time */ in atalk_rcv()
1470 if (!ddp->deh_dnet) /* Net 0 is 'this network' */ in atalk_rcv()
1471 atif = atalk_find_anynet(ddp->deh_dnode, dev); in atalk_rcv()
1473 atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); in atalk_rcv()
1476 /* Not ours, so we route the packet via the correct in atalk_rcv()
1486 * Which socket - atalk_search_socket() looks for a *full match* in atalk_rcv()
1489 tosat.sat_addr.s_net = ddp->deh_dnet; in atalk_rcv()
1490 tosat.sat_addr.s_node = ddp->deh_dnode; in atalk_rcv()
1491 tosat.sat_port = ddp->deh_dport; in atalk_rcv()
1527 if (!ap || skb->len < sizeof(__be16) || skb->len > 1023) in ltalk_rcv()
1538 ddp = skb_push(skb, sizeof(*ddp) - 4); in ltalk_rcv()
1548 ddp->deh_dnode = skb_mac_header(skb)[0]; /* From physical header */ in ltalk_rcv()
1549 ddp->deh_snode = skb_mac_header(skb)[1]; /* From physical header */ in ltalk_rcv()
1551 ddp->deh_dnet = ap->s_net; /* Network number */ in ltalk_rcv()
1552 ddp->deh_snet = ap->s_net; in ltalk_rcv()
1553 ddp->deh_sum = 0; /* No checksum */ in ltalk_rcv()
1558 ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10)); in ltalk_rcv()
1570 struct sock *sk = sock->sk; in atalk_sendmsg()
1572 DECLARE_SOCKADDR(struct sockaddr_at *, usat, msg->msg_name); in atalk_sendmsg()
1573 int flags = msg->msg_flags; in atalk_sendmsg()
1584 return -EINVAL; in atalk_sendmsg()
1587 return -EMSGSIZE; in atalk_sendmsg()
1591 err = -EBUSY; in atalk_sendmsg()
1596 err = -EINVAL; in atalk_sendmsg()
1597 if (msg->msg_namelen < sizeof(*usat) || in atalk_sendmsg()
1598 usat->sat_family != AF_APPLETALK) in atalk_sendmsg()
1601 err = -EPERM; in atalk_sendmsg()
1603 if (usat->sat_addr.s_node == ATADDR_BCAST && in atalk_sendmsg()
1608 err = -ENOTCONN; in atalk_sendmsg()
1609 if (sk->sk_state != TCP_ESTABLISHED) in atalk_sendmsg()
1612 usat->sat_family = AF_APPLETALK; in atalk_sendmsg()
1613 usat->sat_port = at->dest_port; in atalk_sendmsg()
1614 usat->sat_addr.s_node = at->dest_node; in atalk_sendmsg()
1615 usat->sat_addr.s_net = at->dest_net; in atalk_sendmsg()
1622 size = sizeof(struct ddpehdr) + len + ddp_dl->header_length; in atalk_sendmsg()
1624 if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { in atalk_sendmsg()
1625 rt = atrtr_find(&usat->sat_addr); in atalk_sendmsg()
1630 at_hint.s_net = at->src_net; in atalk_sendmsg()
1634 err = -ENETUNREACH; in atalk_sendmsg()
1638 dev = rt->dev; in atalk_sendmsg()
1641 sk, size, dev->name); in atalk_sendmsg()
1643 size += dev->hard_header_len; in atalk_sendmsg()
1650 skb_reserve(skb, ddp_dl->header_length); in atalk_sendmsg()
1651 skb_reserve(skb, dev->hard_header_len); in atalk_sendmsg()
1652 skb->dev = dev; in atalk_sendmsg()
1657 ddp->deh_len_hops = htons(len + sizeof(*ddp)); in atalk_sendmsg()
1658 ddp->deh_dnet = usat->sat_addr.s_net; in atalk_sendmsg()
1659 ddp->deh_snet = at->src_net; in atalk_sendmsg()
1660 ddp->deh_dnode = usat->sat_addr.s_node; in atalk_sendmsg()
1661 ddp->deh_snode = at->src_node; in atalk_sendmsg()
1662 ddp->deh_dport = usat->sat_port; in atalk_sendmsg()
1663 ddp->deh_sport = at->src_port; in atalk_sendmsg()
1670 err = -EFAULT; in atalk_sendmsg()
1674 if (sk->sk_no_check_tx) in atalk_sendmsg()
1675 ddp->deh_sum = 0; in atalk_sendmsg()
1677 ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); in atalk_sendmsg()
1683 if (ddp->deh_dnode == ATADDR_BCAST && in atalk_sendmsg()
1684 !(rt->flags & RTF_GATEWAY) && !(dev->flags & IFF_LOOPBACK)) { in atalk_sendmsg()
1693 aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL); in atalk_sendmsg()
1697 if (dev->flags & IFF_LOOPBACK || loopback) { in atalk_sendmsg()
1701 if (ddp->deh_dnode == ATADDR_BCAST) { in atalk_sendmsg()
1710 err = -ENETUNREACH; in atalk_sendmsg()
1713 dev = rt->dev; in atalk_sendmsg()
1714 skb->dev = dev; in atalk_sendmsg()
1716 ddp_dl->request(ddp_dl, skb, dev->dev_addr); in atalk_sendmsg()
1719 if (rt->flags & RTF_GATEWAY) { in atalk_sendmsg()
1720 gsat.sat_addr = rt->gateway; in atalk_sendmsg()
1727 aarp_send_ddp(dev, skb, &usat->sat_addr, NULL); in atalk_sendmsg()
1739 struct sock *sk = sock->sk; in atalk_recvmsg()
1753 /* FIXME: use skb->cb to be able to use shared skbs */ in atalk_recvmsg()
1755 copied = ntohs(ddp->deh_len_hops) & 1023; in atalk_recvmsg()
1757 if (sk->sk_type != SOCK_RAW) { in atalk_recvmsg()
1759 copied -= offset; in atalk_recvmsg()
1764 msg->msg_flags |= MSG_TRUNC; in atalk_recvmsg()
1768 if (!err && msg->msg_name) { in atalk_recvmsg()
1769 DECLARE_SOCKADDR(struct sockaddr_at *, sat, msg->msg_name); in atalk_recvmsg()
1770 sat->sat_family = AF_APPLETALK; in atalk_recvmsg()
1771 sat->sat_port = ddp->deh_sport; in atalk_recvmsg()
1772 sat->sat_addr.s_node = ddp->deh_snode; in atalk_recvmsg()
1773 sat->sat_addr.s_net = ddp->deh_snet; in atalk_recvmsg()
1774 msg->msg_namelen = sizeof(*sat); in atalk_recvmsg()
1790 int rc = -ENOIOCTLCMD; in atalk_ioctl()
1791 struct sock *sk = sock->sk; in atalk_ioctl()
1797 long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); in atalk_ioctl()
1809 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); in atalk_ioctl()
1813 amount = skb->len - sizeof(struct ddpehdr); in atalk_ioctl()
1820 rc = -EPERM; in atalk_ioctl()
1849 if (copy_from_user(&rt.rt_dst, &ur->rt_dst, in atalk_compat_routing_ioctl()
1851 get_user(rt.rt_flags, &ur->rt_flags) || in atalk_compat_routing_ioctl()
1852 get_user(rt.rt_metric, &ur->rt_metric) || in atalk_compat_routing_ioctl()
1853 get_user(rt.rt_mtu, &ur->rt_mtu) || in atalk_compat_routing_ioctl()
1854 get_user(rt.rt_window, &ur->rt_window) || in atalk_compat_routing_ioctl()
1855 get_user(rt.rt_irtt, &ur->rt_irtt) || in atalk_compat_routing_ioctl()
1856 get_user(rtdev, &ur->rt_dev)) in atalk_compat_routing_ioctl()
1857 return -EFAULT; in atalk_compat_routing_ioctl()
1862 return -EINVAL; in atalk_compat_routing_ioctl()
1864 &rt.rt_dst)->sat_addr); in atalk_compat_routing_ioctl()
1870 return -EINVAL; in atalk_compat_routing_ioctl()
1876 struct sock *sk = sock->sk; in atalk_compat_ioctl()
1891 return -ENOIOCTLCMD; in atalk_compat_ioctl()
1962 rc = -ENOMEM; in atalk_init()
2019 aarp_cleanup_module(); /* General aarp clean-up. */ in atalk_exit()