cregit-Linux how code gets into the kernel

Release 4.14 net/ax25/ax25_ip.c

Directory: net/ax25
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
 */
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/uaccess.h>
#include <linux/fcntl.h>
#include <linux/termios.h>	/* For TIOCINQ/OUTQ */
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/sysctl.h>
#include <net/ip.h>
#include <net/arp.h>

/*
 *      IP over AX.25 encapsulation.
 */

/*
 *      Shove an AX.25 UI header on an IP packet and handle ARP
 */

#ifdef CONFIG_INET


static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, unsigned int len) { unsigned char *buff; /* they sometimes come back to us... */ if (type == ETH_P_AX25) return 0; /* header is an AX.25 UI frame from us to them */ buff = skb_push(skb, AX25_HEADER_LEN); *buff++ = 0x00; /* KISS DATA */ if (daddr != NULL) memcpy(buff, daddr, dev->addr_len); /* Address specified */ buff[6] &= ~AX25_CBIT; buff[6] &= ~AX25_EBIT; buff[6] |= AX25_SSSID_SPARE; buff += AX25_ADDR_LEN; if (saddr != NULL) memcpy(buff, saddr, dev->addr_len); else memcpy(buff, dev->dev_addr, dev->addr_len); buff[6] &= ~AX25_CBIT; buff[6] |= AX25_EBIT; buff[6] |= AX25_SSSID_SPARE; buff += AX25_ADDR_LEN; *buff++ = AX25_UI; /* UI */ /* Append a suitable AX.25 PID */ switch (type) { case ETH_P_IP: *buff++ = AX25_P_IP; break; case ETH_P_ARP: *buff++ = AX25_P_ARP; break; default: printk(KERN_ERR "AX.25: ax25_hard_header - wrong protocol type 0x%2.2x\n", type); *buff++ = 0; break; } if (daddr != NULL) return AX25_HEADER_LEN; return -AX25_HEADER_LEN; /* Unfinished header */ }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)21190.95%228.57%
Linus Torvalds156.47%114.29%
Stephen Hemminger20.86%114.29%
Ralf Bächle20.86%114.29%
Eric W. Biedermann10.43%114.29%
Eric Dumazet10.43%114.29%
Total232100.00%7100.00%


netdev_tx_t ax25_ip_xmit(struct sk_buff *skb) { struct sk_buff *ourskb; unsigned char *bp = skb->data; ax25_route *route; struct net_device *dev = NULL; ax25_address *src, *dst; ax25_digi *digipeat = NULL; ax25_dev *ax25_dev; ax25_cb *ax25; char ip_mode = ' '; dst = (ax25_address *)(bp + 1); src = (ax25_address *)(bp + 8); route = ax25_get_route(dst, NULL); if (route) { digipeat = route->digipeat; dev = route->dev; ip_mode = route->ip_mode; } if (dev == NULL) dev = skb->dev; if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) { kfree_skb(skb); goto put; } if (bp[16] == AX25_P_IP) { if (ip_mode == 'V' || (ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) { /* * We copy the buffer and release the original thereby * keeping it straight * * Note: we report 1 back so the caller will * not feed the frame direct to the physical device * We don't want that to happen. (It won't be upset * as we have pulled the frame from the queue by * freeing it). * * NB: TCP modifies buffers that are still * on a device queue, thus we use skb_copy() * instead of using skb_clone() unless this * gets fixed. */ ax25_address src_c; ax25_address dst_c; if ((ourskb = skb_copy(skb, GFP_ATOMIC)) == NULL) { kfree_skb(skb); goto put; } if (skb->sk != NULL) skb_set_owner_w(ourskb, skb->sk); kfree_skb(skb); /* dl9sau: bugfix * after kfree_skb(), dst and src which were pointer * to bp which is part of skb->data would not be valid * anymore hope that after skb_pull(ourskb, ..) our * dsc_c and src_c will not become invalid */ bp = ourskb->data; dst_c = *(ax25_address *)(bp + 1); src_c = *(ax25_address *)(bp + 8); skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */ skb_reset_network_header(ourskb); ax25=ax25_send_frame( ourskb, ax25_dev->values[AX25_VALUES_PACLEN], &src_c, &dst_c, digipeat, dev); if (ax25) { ax25_cb_put(ax25); } goto put; } } bp[7] &= ~AX25_CBIT; bp[7] &= ~AX25_EBIT; bp[7] |= AX25_SSSID_SPARE; bp[14] &= ~AX25_CBIT; bp[14] |= AX25_EBIT; bp[14] |= AX25_SSSID_SPARE; skb_pull(skb, AX25_KISS_HEADER_LEN); if (digipeat != NULL) { if ((ourskb = ax25_rt_build_path(skb, src, dst, route->digipeat)) == NULL) { kfree_skb(skb); goto put; } skb = ourskb; } ax25_queue_xmit(skb, dev); put: if (route) ax25_put_route(route); return NETDEV_TX_OK; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)31872.11%842.11%
Ralf Bächle6314.29%315.79%
Thomas Osterried276.12%15.26%
Jeroen Vreeken173.85%15.26%
Eric W. Biedermann102.27%315.79%
Arnaldo Carvalho de Melo51.13%210.53%
Linus Torvalds10.23%15.26%
Total441100.00%19100.00%

#else /* INET */
static int ax25_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, unsigned int len) { return -AX25_HEADER_LEN; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3386.84%233.33%
Stephen Hemminger25.26%116.67%
Eric Dumazet12.63%116.67%
Ralf Bächle12.63%116.67%
Eric W. Biedermann12.63%116.67%
Total38100.00%6100.00%


netdev_tx_t ax25_ip_xmit(struct sk_buff *skb) { kfree_skb(skb); return NETDEV_TX_OK; }

Contributors

PersonTokensPropCommitsCommitProp
Eric W. Biedermann1794.44%266.67%
Fengguang Wu15.56%133.33%
Total18100.00%3100.00%

#endif
static bool ax25_validate_header(const char *header, unsigned int len) { ax25_digi digi; if (!len) return false; if (header[0]) return true; return ax25_addr_parse(header + 1, len - 1, NULL, NULL, &digi, NULL, NULL); }

Contributors

PersonTokensPropCommitsCommitProp
Willem de Bruijn59100.00%1100.00%
Total59100.00%1100.00%

const struct header_ops ax25_header_ops = { .create = ax25_hard_header, .validate = ax25_validate_header, }; EXPORT_SYMBOL(ax25_header_ops); EXPORT_SYMBOL(ax25_ip_xmit);

Overall Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)65071.35%929.03%
Ralf Bächle707.68%619.35%
Willem de Bruijn647.03%13.23%
Eric W. Biedermann343.73%412.90%
Thomas Osterried272.96%13.23%
Stephen Hemminger212.31%13.23%
Jeroen Vreeken171.87%13.23%
Linus Torvalds171.87%39.68%
Arnaldo Carvalho de Melo50.55%26.45%
Tejun Heo30.33%13.23%
Eric Dumazet20.22%13.23%
Fengguang Wu10.11%13.23%
Total911100.00%31100.00%
Directory: net/ax25
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.